about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-08-29 21:01:47 +0000
committerUlrich Drepper <drepper@redhat.com>1997-08-29 21:01:47 +0000
commit800d775e426b9c0af63f711b79b09bf540c97456 (patch)
treeff7858571c81f2e6077c5e35b465494052984876
parent39e16978c3b4ac8eaf2201fac56316623910d9da (diff)
downloadglibc-cvs/libc-ud-970829.tar.gz
glibc-cvs/libc-ud-970829.tar.xz
glibc-cvs/libc-ud-970829.zip
1997-08-29 21:45  Ulrich Drepper  <drepper@cygnus.com>

	* sunrpc/auth_des.c: New file.  Copied from former secure_rpc add-on.
	* sunrpc/authdes_prot.c: New file.  Likewise.
	* sunrpc/des.h: New file.  Likewise.
	* sunrpc/des_crypt.c: New file.  Likewise.
	* sunrpc/des_soft.c: New file.  Likewise.
	* sunrpc/key_call.c: New file.  Likewise.
	* sunrpc/key_prot.c: New file.  Likewise.
	* sunrpc/netname.c: New file.  Likewise.
	* sunrpc/openchild.c: New file.  Likewise.
	* sunrpc/rtime.c: New file.  Likewise.
	* sunrpc/svc_auth.c: New file.  Likewise.
	* sunrpc/svcauth_des.c: New file.  Likewise.
	* sunrpc/xcrypt.c: New file.  Likewise.
	* sunrpc/rpc/auth.h: New file.  Likewise.
	* sunrpc/rpc/auth_des.h: New file.  Likewise.
	* sunrpc/rpc/des_crypt.h: New file.  Likewise.
	* sunrpc/rpc/key_prot.h: New file.  Likewise.
	* sunrpc/rpcsvc/key_prot.x: New file.  Likewise.
	* sysdeps/generic/svc_auth.h: Removed.
	* sysdeps/generic/rpc/auth.h: Removed.
	* sysdeps/generic/rpc/auth_des.h: Removed.
	* sysdeps/stub/des_impl.c: New file.  Stub version for DES.
	* sunrpc/Makefile (rpcsvc): Add keyprot.x.
	(headers): Add des_crypt.h and key_prot.h.
	(routines): Add auth_des, authdes_prot, des_crypt, des_impl, des_soft,
	key_call, key_prot, netname, openchild, rtime, svcauth_des, xcrypt.
	(distribute): Add des.h.

	* db2/Makefile: Add all headers and other files to distribute.
	(others): Add db_printlog.

	* sysdeps/mach/hurd/Dist: Add net/* headers.
	* sysdeps/mach/hurd/mips/Dist: New file.
	* sysdeps/powerpc/Dist: Add fe_nomask.c and t_sqrt.c.
	* sysdeps/sparc/Dist: Add sys/trap.h.
	* sysdeps/sparc/sparc32/Dist: Remove sys/trap.h.
	* sysdeps/sparc/sparc32/sparcv8/Dist: New file.
	* sysdeps/unix/sysv/linux/mips/Dist: Add sgidefs.h.
	* sysdeps/unix/sysv/linux/sparc/Dist: Add sys/trap.h.
	* sysdeps/unix/sysv/linux/sparc/sparc32/Dist: Remove sys/trap.h.

	Add previously missing assembler files for PPC.
	* sysdeps/powerpc/add_n.s: New file.
	* sysdeps/powerpc/addmul_1.s: New file.
	* sysdeps/powerpc/lshift.s: New file.
	* sysdeps/powerpc/memset.s: New file.
	* sysdeps/powerpc/mul_1.s: New file.
	* sysdeps/powerpc/rshift.s: New file.
	* sysdeps/powerpc/strchr.s: New file.
	* sysdeps/powerpc/strcmp.s: New file.
	* sysdeps/powerpc/sub_n.s: New file.
	* sysdeps/powerpc/submul_1.s: New file.

1997-08-28 18:42  Thorsten Kukuk  <kukuk@uni-paderborn.de>

	* nis/nis_server.c: Rewritten to fix a lot of bugs.

1997-08-28  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* md5-crypt/Makefile (LDFLAGS-md5crypt.so, libmd5crypt-map): New
	variables.

	in NLSPATH environment variable.  Patch by HJ Lu <hjl@gnu.ai.mit.edu>.
-rw-r--r--ChangeLog66
-rw-r--r--db2/Makefile22
-rw-r--r--md5-crypt/Makefile5
-rw-r--r--nis/nis_server.c81
-rw-r--r--sunrpc/Makefile11
-rw-r--r--sunrpc/auth_des.c459
-rw-r--r--sunrpc/authdes_prot.c81
-rw-r--r--sunrpc/des.h83
-rw-r--r--sunrpc/des_crypt.c120
-rw-r--r--sunrpc/des_soft.c68
-rw-r--r--sunrpc/key_call.c363
-rw-r--r--sunrpc/key_prot.c161
-rw-r--r--sunrpc/netname.c201
-rw-r--r--sunrpc/openchild.c112
-rw-r--r--sunrpc/rpc/auth.h (renamed from sysdeps/generic/rpc/auth.h)35
-rw-r--r--sunrpc/rpc/auth_des.h104
-rw-r--r--sunrpc/rpc/des_crypt.h97
-rw-r--r--sunrpc/rpc/key_prot.h345
-rw-r--r--sunrpc/rpcsvc/key_prot.x284
-rw-r--r--sunrpc/rtime.c146
-rw-r--r--sunrpc/svc_auth.c (renamed from sysdeps/generic/svc_auth.c)8
-rw-r--r--sunrpc/svcauth_des.c548
-rw-r--r--sunrpc/xcrypt.c180
-rw-r--r--sysdeps/generic/rpc/auth_des.h46
-rw-r--r--sysdeps/mach/hurd/Dist9
-rw-r--r--sysdeps/mach/hurd/mips/Dist3
-rw-r--r--sysdeps/powerpc/Dist2
-rw-r--r--sysdeps/powerpc/add_n.s68
-rw-r--r--sysdeps/powerpc/addmul_1.s50
-rw-r--r--sysdeps/powerpc/lshift.s479
-rw-r--r--sysdeps/powerpc/memset.s202
-rw-r--r--sysdeps/powerpc/mul_1.s47
-rw-r--r--sysdeps/powerpc/rshift.s59
-rw-r--r--sysdeps/powerpc/strchr.s118
-rw-r--r--sysdeps/powerpc/strcmp.s273
-rw-r--r--sysdeps/powerpc/sub_n.s69
-rw-r--r--sysdeps/powerpc/submul_1.s52
-rw-r--r--sysdeps/sparc/Dist1
-rw-r--r--sysdeps/sparc/sparc32/Dist1
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/Dist6
-rw-r--r--sysdeps/stub/des_impl.c27
-rw-r--r--sysdeps/unix/sysv/linux/mips/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Dist1
44 files changed, 4968 insertions, 127 deletions
diff --git a/ChangeLog b/ChangeLog
index 86a662f7ff..b7d78e243e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,67 @@
+1997-08-29 21:45  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sunrpc/auth_des.c: New file.  Copied from former secure_rpc add-on.
+	* sunrpc/authdes_prot.c: New file.  Likewise.
+	* sunrpc/des.h: New file.  Likewise.
+	* sunrpc/des_crypt.c: New file.  Likewise.
+	* sunrpc/des_soft.c: New file.  Likewise.
+	* sunrpc/key_call.c: New file.  Likewise.
+	* sunrpc/key_prot.c: New file.  Likewise.
+	* sunrpc/netname.c: New file.  Likewise.
+	* sunrpc/openchild.c: New file.  Likewise.
+	* sunrpc/rtime.c: New file.  Likewise.
+	* sunrpc/svc_auth.c: New file.  Likewise.
+	* sunrpc/svcauth_des.c: New file.  Likewise.
+	* sunrpc/xcrypt.c: New file.  Likewise.
+	* sunrpc/rpc/auth.h: New file.  Likewise.
+	* sunrpc/rpc/auth_des.h: New file.  Likewise.
+	* sunrpc/rpc/des_crypt.h: New file.  Likewise.
+	* sunrpc/rpc/key_prot.h: New file.  Likewise.
+	* sunrpc/rpcsvc/key_prot.x: New file.  Likewise.
+	* sysdeps/generic/svc_auth.h: Removed.
+	* sysdeps/generic/rpc/auth.h: Removed.
+	* sysdeps/generic/rpc/auth_des.h: Removed.
+	* sysdeps/stub/des_impl.c: New file.  Stub version for DES.
+	* sunrpc/Makefile (rpcsvc): Add keyprot.x.
+	(headers): Add des_crypt.h and key_prot.h.
+	(routines): Add auth_des, authdes_prot, des_crypt, des_impl, des_soft,
+	key_call, key_prot, netname, openchild, rtime, svcauth_des, xcrypt.
+	(distribute): Add des.h.
+
+	* db2/Makefile: Add all headers and other files to distribute.
+	(others): Add db_printlog.
+
+	* sysdeps/mach/hurd/Dist: Add net/* headers.
+	* sysdeps/mach/hurd/mips/Dist: New file.
+	* sysdeps/powerpc/Dist: Add fe_nomask.c and t_sqrt.c.
+	* sysdeps/sparc/Dist: Add sys/trap.h.
+	* sysdeps/sparc/sparc32/Dist: Remove sys/trap.h.
+	* sysdeps/sparc/sparc32/sparcv8/Dist: New file.
+	* sysdeps/unix/sysv/linux/mips/Dist: Add sgidefs.h.
+	* sysdeps/unix/sysv/linux/sparc/Dist: Add sys/trap.h.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/Dist: Remove sys/trap.h.
+
+	Add previously missing assembler files for PPC.
+	* sysdeps/powerpc/add_n.s: New file.
+	* sysdeps/powerpc/addmul_1.s: New file.
+	* sysdeps/powerpc/lshift.s: New file.
+	* sysdeps/powerpc/memset.s: New file.
+	* sysdeps/powerpc/mul_1.s: New file.
+	* sysdeps/powerpc/rshift.s: New file.
+	* sysdeps/powerpc/strchr.s: New file.
+	* sysdeps/powerpc/strcmp.s: New file.
+	* sysdeps/powerpc/sub_n.s: New file.
+	* sysdeps/powerpc/submul_1.s: New file.
+
+1997-08-28 18:42  Thorsten Kukuk  <kukuk@uni-paderborn.de>
+
+	* nis/nis_server.c: Rewritten to fix a lot of bugs.
+
+1997-08-28  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* md5-crypt/Makefile (LDFLAGS-md5crypt.so, libmd5crypt-map): New
+	variables.
+
 1997-08-29 02:36  Ulrich Drepper  <drepper@cygnus.com>
 
 	* Makefile (version-info.h): Use ISO form for the date.
@@ -35,7 +99,7 @@
 1997-08-28 17:30  Ulrich Drepper  <drepper@cygnus.com>
 
 	* catgets/catgets.c (catopen): Correctly determine length of string
-	in NLSPATH evironment variable.  Patch by HJ Lu <hjl@gnu.ai.mit.edu>.
+	in NLSPATH environment variable.  Patch by HJ Lu <hjl@gnu.ai.mit.edu>.
 
 1997-08-27 23:19  Richard Henderson  <rth@cygnus.com>
 
diff --git a/db2/Makefile b/db2/Makefile
index 24d74cc3d8..a7521b6580 100644
--- a/db2/Makefile
+++ b/db2/Makefile
@@ -30,6 +30,24 @@ subdir-dirs = btree common db db185 dbm hash lock log mp mutex os txn \
 	progs/db_dump progs/db_dump185 progs/db_load progs/db_printlog \
 	progs/db_recover progs/db_stat clib
 
+headers = db.h db_185.h
+
+distribute = db_int.h config.h compat.h clib/getlong.c btree/btree.src \
+	     db/db.src db185/db185_int.src hash/hash.src log/log.src \
+	     txn/txn.src \
+	     $(addprefix include/,btree.h btree_auto.h btree_ext.h \
+				  clib_ext.h common_ext.h cxx_int.h \
+				  db.h.src db_185.h.src db_am.h db_auto.h \
+				  db_cxx.h db_dispatch.h db_ext.h \
+				  db_int.h.src db_page.h db_shash.h db_swap.h \
+				  hash.h hash_auto.h hash_ext.h lock.h \
+				  lock_ext.h log.h log_auto.h log_ext.h \
+				  mp.h mp_ext.h mutex_ext.h os_ext.h queue.h \
+				  shqueue.h txn.h txn_auto.h txn_ext.h) \
+	     $(addprefix mutex/,x86.gcc uts4.cc.s sparc.gcc parisc.hp \
+				parisc.gcc alpha.gcc alpha.dec README \
+				68020.gcc)
+
 vpath %.c $(subdir-dirs)
 
 extra-libs := libdb
@@ -52,9 +70,9 @@ libdb-routines := bt_close bt_compare bt_conv bt_cursor bt_delete \
 	txn_rec dbm db185
 
 others		:= makedb db_dump185 db_archive db_checkpoint db_deadlock \
-		db_dump db_load db_recover db_stat
+		db_dump db_load db_recover db_stat db_printlog
 install-bin	:= makedb db_dump185 db_archive db_checkpoint db_deadlock \
-		db_dump db_load db_recover db_stat
+		db_dump db_load db_recover db_stat db_printlog
 
 include ../Rules
 
diff --git a/md5-crypt/Makefile b/md5-crypt/Makefile
index b52e1ef012..ab054ce8a6 100644
--- a/md5-crypt/Makefile
+++ b/md5-crypt/Makefile
@@ -63,6 +63,11 @@ libmd5crypt: $(foreach o,$(object-suffixes), \
 		    $(addprefix $(objpfx),$(patsubst %,$(libtype$o),md5crypt)))
 ifeq ($(build-shared),yes)
 libmd5crypt: $(objpfx)libmd5crypt.so
+# Use the same soname as the real libcrypt, so that it can be used as a
+# drop in replacement.
+LDFLAGS-md5crypt.so = -Wl,-soname=lib$(libprefix)crypt.so$(libcrypt.so-version)
+# We also use the same version script.
+libmd5crypt-map := libcrypt.map
 endif
 
 define o-iterator-doit
diff --git a/nis/nis_server.c b/nis/nis_server.c
index 5274a3bfc4..0df608a153 100644
--- a/nis/nis_server.c
+++ b/nis/nis_server.c
@@ -19,7 +19,6 @@
 
 #include <string.h>
 #include <rpcsvc/nis.h>
-#include <rpcsvc/nislib.h>
 #include "nis_intern.h"
 
 nis_error
@@ -29,42 +28,21 @@ nis_servstate (const nis_server *serv, const nis_tag *tags,
   nis_taglist taglist;
   nis_taglist tagres;
 
+  *result = 0;
   tagres.tags.tags_len = 0;
   tagres.tags.tags_val = NULL;
-  *result = NULL;
   taglist.tags.tags_len = numtags;
   taglist.tags.tags_val = (nis_tag *) tags;
 
   if (serv == NULL)
-    {
-      if (__do_niscall (NULL, NIS_SERVSTATE, (xdrproc_t) xdr_nis_taglist,
-			(caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
-			(caddr_t) &tagres, 0) != RPC_SUCCESS)
-	return NIS_RPCERROR;
-    }
-  else
-    {
-      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)
-	return NIS_RPCERROR;
-    }
-  if (tagres.tags.tags_len > 0)
-    {
-      u_long i;
-
-      result = malloc (sizeof (nis_tag *) * tagres.tags.tags_len);
-      if (result == NULL)
-	return NIS_NOMEMORY;
-      for (i = 0; i < tagres.tags.tags_len; ++i)
-	{
-	  result[i] = malloc (sizeof (nis_tag));
-	  if (result[i] == NULL)
-	    return NIS_NOMEMORY;
-	  result[i]->tag_val = strdup (tagres.tags.tags_val[i].tag_val);
-	  result[i]->tag_type = tagres.tags.tags_val[i].tag_type;
-	}
-    }
+    return NIS_BADOBJECT;
+
+  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)
+    return NIS_RPCERROR;
+
+  *result = tagres.tags.tags_val;
 
   return NIS_SUCCESS;
 }
@@ -76,42 +54,21 @@ nis_stats (const nis_server *serv, const nis_tag *tags,
   nis_taglist taglist;
   nis_taglist tagres;
 
+  *result = NULL;
   tagres.tags.tags_len = 0;
   tagres.tags.tags_val = NULL;
-  *result = NULL;
   taglist.tags.tags_len = numtags;
   taglist.tags.tags_val = (nis_tag *) tags;
 
   if (serv == NULL)
-    {
-      if (__do_niscall (NULL, NIS_STATUS, (xdrproc_t) xdr_nis_taglist,
-			(caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
-			(caddr_t) &tagres, 0) != RPC_SUCCESS)
-	return NIS_RPCERROR;
-    }
-  else
-    {
-      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)
-	return NIS_RPCERROR;
-    }
-  if (tagres.tags.tags_len > 0)
-    {
-      u_long i;
-
-      result = malloc (sizeof (nis_tag *) * tagres.tags.tags_len);
-      if (result == NULL)
-	return NIS_NOMEMORY;
-      for (i = 0; i < tagres.tags.tags_len; ++i)
-	{
-	  result[i] = malloc (sizeof (nis_tag));
-	  if (result[i] == NULL)
-	    return NIS_NOMEMORY;
-	  result[i]->tag_val = strdup (tagres.tags.tags_val[i].tag_val);
-	  result[i]->tag_type = tagres.tags.tags_val[i].tag_type;
-	}
-    }
+    return NIS_BADOBJECT;
+
+  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)
+    return NIS_RPCERROR;
+
+  *result = tagres.tags.tags_val;
 
   return NIS_SUCCESS;
 }
@@ -122,6 +79,6 @@ nis_freetags (nis_tag *tags, const int numtags)
   int i;
 
   for (i = 0; i < numtags; ++i)
-    free (tags->tag_val);
+    free (tags[i].tag_val);
   free (tags);
 }
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
index b7c86d4f84..baee72e85b 100644
--- a/sunrpc/Makefile
+++ b/sunrpc/Makefile
@@ -47,10 +47,11 @@ subdir	:= sunrpc
 
 rpcsvc = bootparam.x nlm_prot.x rstat.x \
 	 yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \
-	 rusers.x spray.x nfs_prot.x rquota.x
+	 rusers.x spray.x nfs_prot.x rquota.x key_prot.x
 headers = $(addprefix rpc/,auth.h auth_unix.h clnt.h netdb.h pmap_clnt.h \
 			   pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h svc.h \
-			   svc_auth.h types.h xdr.h auth_des.h) \
+			   svc_auth.h types.h xdr.h auth_des.h \
+			   des_crypt.h key_prot.h) \
 	  $(rpcsvc:%=rpcsvc/%)
 install-others = $(inst_sysconfdir)/rpc
 generated = $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) \
@@ -64,7 +65,9 @@ routines := auth_none auth_unix authuxprot bindrsvprt \
 	    pmap_prot2 pmap_rmt rpc_prot rpc_common rpc_cmsg \
 	    svc svc_auth svc_authux svc_raw svc_run svc_simple \
 	    svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \
-	    xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof
+	    xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \
+	    auth_des authdes_prot des_crypt des_impl des_soft \
+	    key_call key_prot netname openchild rtime svcauth_des xcrypt
 
 others := rpcinfo
 install-bin := rpcgen
@@ -73,7 +76,7 @@ rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
 	      rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
 	      rpc_tblout.o rpc_sample.o
 # These headers are part of rpcgen.
-distribute := proto.h rpc_util.h rpc_parse.h rpc_scan.h \
+distribute := proto.h rpc_util.h rpc_parse.h rpc_scan.h des.h \
 	      $(rpcgen-objs:.o=.c) etc.rpc
 extra-objs = $(rpcgen-objs)
 
diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c
new file mode 100644
index 0000000000..4ea6391c6e
--- /dev/null
+++ b/sunrpc/auth_des.c
@@ -0,0 +1,459 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)auth_des.c	2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+/*
+ * auth_des.c, client-side implementation of DES authentication
+ */
+
+#include <string.h>
+#include <rpc/des_crypt.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>		/* XXX: just to get htonl() and ntohl() */
+#include <sys/socket.h>
+
+#define MILLION		1000000L
+#define RTIME_TIMEOUT 5		/* seconds to wait for sync */
+
+#define AUTH_PRIVATE(auth)	(struct ad_private *) auth->ah_private
+#define ALLOC(object_type)	(object_type *) mem_alloc(sizeof(object_type))
+#define FREE(ptr, size)		mem_free((char *)(ptr), (int) size)
+#define ATTEMPT(xdr_op)		if (!(xdr_op)) return (FALSE)
+
+#define debug(msg)		/* printf("%s\n", msg) */
+
+extern int rtime (struct sockaddr_in *, struct timeval *, struct timeval *);
+extern bool_t xdr_authdes_cred (XDR *, struct authdes_cred *);
+extern bool_t xdr_authdes_verf (XDR *, struct authdes_verf *);
+
+/*
+ * DES authenticator operations vector
+ */
+AUTH *authdes_create (const char *, u_int, struct sockaddr *,
+		      des_block *);
+AUTH *authdes_pk_create (const char *, netobj *, u_int,
+			 struct sockaddr *, des_block *);
+static void authdes_nextverf (AUTH *);
+static bool_t authdes_marshal (AUTH *, XDR *);
+static bool_t authdes_validate (AUTH *, struct opaque_auth *);
+static bool_t authdes_refresh (AUTH *);
+static void authdes_destroy (AUTH *);
+static bool_t synchronize (struct sockaddr *, struct timeval *);
+
+static struct auth_ops authdes_ops =
+{
+  authdes_nextverf,
+  authdes_marshal,
+  authdes_validate,
+  authdes_refresh,
+  authdes_destroy
+};
+
+
+/*
+ * This struct is pointed to by the ah_private field of an "AUTH *"
+ */
+struct ad_private
+  {
+    char *ad_fullname;		/* client's full name */
+    u_int ad_fullnamelen;	/* length of name, rounded up */
+    char *ad_servername;	/* server's full name */
+    u_int ad_servernamelen;	/* length of name, rounded up */
+    u_int ad_window;		/* client specified window */
+    bool_t ad_dosync;		/* synchronize? */
+    struct sockaddr ad_syncaddr;	/* remote host to synch with */
+    struct timeval ad_timediff;	/* server's time - client's time */
+    u_long ad_nickname;		/* server's nickname for client */
+    struct authdes_cred ad_cred;	/* storage for credential */
+    struct authdes_verf ad_verf;	/* storage for verifier */
+    struct timeval ad_timestamp;	/* timestamp sent */
+    des_block ad_xkey;		/* encrypted conversation key */
+    u_char ad_pkey[1024];	/* Servers actual public key */
+  };
+
+
+/*
+ * Create the client des authentication object
+ */
+AUTH *
+authdes_create (const char *servername, u_int window, 
+		struct sockaddr *syncaddr, des_block * ckey)
+  /* servername - network name of server */
+  /* window     - time to live */
+  /* syncaddr   - optional addr of host to sync with */
+  /* ckey       - optional conversation key to use */
+{
+  u_char pkey_data[1024];
+  netobj pkey;
+
+  if (!getpublickey (servername, pkey_data))
+    return (NULL);
+
+  pkey.n_bytes = (char *) pkey_data;
+  pkey.n_len = strlen ((char *) pkey_data) + 1;
+  return authdes_pk_create (servername, &pkey, window, syncaddr, ckey);
+}
+
+AUTH *
+authdes_pk_create (const char *servername, netobj * pkey, u_int window,
+		   struct sockaddr * syncaddr, des_block * ckey)
+{
+  AUTH *auth;
+  struct ad_private *ad;
+  char namebuf[MAXNETNAMELEN + 1];
+
+  /*
+   * Allocate everything now
+   */
+  auth = ALLOC (AUTH);
+  ad = ALLOC (struct ad_private);
+  memcpy (ad->ad_pkey, pkey->n_bytes, pkey->n_len);
+  if (!getnetname (namebuf))
+    goto failed;
+  ad->ad_fullnamelen = RNDUP (strlen (namebuf));
+  ad->ad_fullname = mem_alloc (ad->ad_fullnamelen + 1);
+
+  ad->ad_servernamelen = strlen (servername);
+  ad->ad_servername = mem_alloc (ad->ad_servernamelen + 1);
+
+  if (auth == NULL || ad == NULL || ad->ad_fullname == NULL ||
+      ad->ad_servername == NULL)
+    {
+      debug ("authdes_create: out of memory");
+      goto failed;
+    }
+
+  /*
+   * Set up private data
+   */
+  bcopy (namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1);
+  bcopy (servername, ad->ad_servername, ad->ad_servernamelen + 1);
+  if (syncaddr != NULL)
+    {
+      ad->ad_syncaddr = *syncaddr;
+      ad->ad_dosync = TRUE;
+    }
+  else
+    ad->ad_dosync = FALSE;
+
+  ad->ad_window = window;
+  if (ckey == NULL)
+    {
+      if (key_gendes (&auth->ah_key) < 0)
+	{
+	  debug ("authdes_create: unable to gen conversation key");
+	  return (NULL);
+	}
+    }
+  else
+    auth->ah_key = *ckey;
+
+  /*
+   * Set up auth handle
+   */
+  auth->ah_cred.oa_flavor = AUTH_DES;
+  auth->ah_verf.oa_flavor = AUTH_DES;
+  auth->ah_ops = &authdes_ops;
+  auth->ah_private = (caddr_t) ad;
+
+  if (!authdes_refresh (auth))
+    goto failed;
+
+  return (auth);
+
+failed:
+  if (auth != NULL)
+    FREE (auth, sizeof (AUTH));
+  if (ad != NULL)
+    FREE (ad, sizeof (struct ad_private));
+  if (ad->ad_fullname != NULL)
+    FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
+  if (ad->ad_servername != NULL)
+    FREE (ad->ad_servername, ad->ad_servernamelen + 1);
+  return (NULL);
+}
+
+/*
+ * Implement the five authentication operations
+ */
+
+
+/*
+ * 1. Next Verifier
+ */
+/*ARGSUSED */
+static void
+authdes_nextverf (AUTH * auth)
+{
+  /* what the heck am I supposed to do??? */
+}
+
+
+
+/*
+ * 2. Marshal
+ */
+static bool_t
+authdes_marshal (AUTH * auth, XDR * xdrs)
+{
+  struct ad_private *ad = AUTH_PRIVATE (auth);
+  struct authdes_cred *cred = &ad->ad_cred;
+  struct authdes_verf *verf = &ad->ad_verf;
+  des_block cryptbuf[2];
+  des_block ivec;
+  int status;
+  int len;
+  register long *ixdr;
+
+  /*
+   * Figure out the "time", accounting for any time difference
+   * with the server if necessary.
+   */
+  gettimeofday (&ad->ad_timestamp, (struct timezone *) NULL);
+  ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
+  ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
+  if (ad->ad_timestamp.tv_usec >= MILLION)
+    {
+      ad->ad_timestamp.tv_usec -= MILLION;
+      ad->ad_timestamp.tv_sec += 1;
+    }
+
+  /*
+   * XDR the timestamp and possibly some other things, then
+   * encrypt them.
+   */
+  ixdr = (long *) cryptbuf;
+  IXDR_PUT_LONG (ixdr, ad->ad_timestamp.tv_sec);
+  IXDR_PUT_LONG (ixdr, ad->ad_timestamp.tv_usec);
+  if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+    {
+      IXDR_PUT_U_LONG (ixdr, ad->ad_window);
+      IXDR_PUT_U_LONG (ixdr, ad->ad_window - 1);
+      ivec.key.high = ivec.key.low = 0;
+      status = cbc_crypt ((char *) &auth->ah_key, (char *) cryptbuf,
+	      2 * sizeof (des_block), DES_ENCRYPT | DES_HW, (char *) &ivec);
+    }
+  else
+    {
+      status = ecb_crypt ((char *) &auth->ah_key, (char *) cryptbuf,
+			  sizeof (des_block), DES_ENCRYPT | DES_HW);
+    }
+  if (DES_FAILED (status))
+    {
+      debug ("authdes_marshal: DES encryption failure");
+      return (FALSE);
+    }
+  ad->ad_verf.adv_xtimestamp = cryptbuf[0];
+  if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+    {
+      ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high;
+      ad->ad_verf.adv_winverf = cryptbuf[1].key.low;
+    }
+  else
+    {
+      ad->ad_cred.adc_nickname = ad->ad_nickname;
+      ad->ad_verf.adv_winverf = 0;
+    }
+
+  /*
+   * Serialize the credential and verifier into opaque
+   * authentication data.
+   */
+  if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+    {
+      len = ((1 + 1 + 2 + 1) * BYTES_PER_XDR_UNIT + ad->ad_fullnamelen);
+    }
+  else
+    {
+      len = (1 + 1) * BYTES_PER_XDR_UNIT;
+    }
+
+  if ((ixdr = xdr_inline (xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL)
+    {
+      IXDR_PUT_LONG (ixdr, AUTH_DES);
+      IXDR_PUT_LONG (ixdr, len);
+    }
+  else
+    {
+      ATTEMPT (xdr_putlong (xdrs, (long *)&auth->ah_cred.oa_flavor));
+      ATTEMPT (xdr_putlong (xdrs, (long *)&len));
+    }
+  ATTEMPT (xdr_authdes_cred (xdrs, cred));
+
+  len = (2 + 1) * BYTES_PER_XDR_UNIT;
+  if ((ixdr = xdr_inline (xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL)
+    {
+      IXDR_PUT_LONG (ixdr, AUTH_DES);
+      IXDR_PUT_LONG (ixdr, len);
+    }
+  else
+    {
+      ATTEMPT (xdr_putlong (xdrs, (long *)&auth->ah_verf.oa_flavor));
+      ATTEMPT (xdr_putlong (xdrs, (long *)&len));
+    }
+  ATTEMPT (xdr_authdes_verf (xdrs, verf));
+  return (TRUE);
+}
+
+
+/*
+ * 3. Validate
+ */
+static bool_t
+authdes_validate (AUTH * auth, struct opaque_auth *rverf)
+{
+  struct ad_private *ad = AUTH_PRIVATE (auth);
+  struct authdes_verf verf;
+  int status;
+  register u_long *ixdr;
+
+  if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT)
+    return (FALSE);
+
+  ixdr = (u_long *) rverf->oa_base;
+  verf.adv_xtimestamp.key.high = (u_long) * ixdr++;
+  verf.adv_xtimestamp.key.low = (u_long) * ixdr++;
+  verf.adv_int_u = (u_long) * ixdr++;	/* nickname not XDR'd ! */
+
+  /*
+   * Decrypt the timestamp
+   */
+  status = ecb_crypt ((char *) &auth->ah_key, (char *) &verf.adv_xtimestamp,
+		      sizeof (des_block), DES_DECRYPT | DES_HW);
+
+  if (DES_FAILED (status))
+    {
+      debug ("authdes_validate: DES decryption failure");
+      return (FALSE);
+    }
+
+  /*
+   * xdr the decrypted timestamp
+   */
+  ixdr = (u_long *) verf.adv_xtimestamp.c;
+  verf.adv_timestamp.tv_sec = IXDR_GET_LONG (ixdr) + 1;
+  verf.adv_timestamp.tv_usec = IXDR_GET_LONG (ixdr);
+
+  /*
+   * validate
+   */
+  if (bcmp ((char *) &ad->ad_timestamp, (char *) &verf.adv_timestamp,
+	    sizeof (struct timeval)) != 0)
+    {
+      debug ("authdes_validate: verifier mismatch\n");
+      return (FALSE);
+    }
+
+  /*
+   * We have a nickname now, let's use it
+   */
+  ad->ad_nickname = verf.adv_nickname;
+  ad->ad_cred.adc_namekind = ADN_NICKNAME;
+  return (TRUE);
+}
+
+/*
+ * 4. Refresh
+ */
+static bool_t
+authdes_refresh (AUTH * auth)
+{
+  netobj pkey;
+  struct ad_private *ad = AUTH_PRIVATE (auth);
+  struct authdes_cred *cred = &ad->ad_cred;
+
+  if (ad->ad_dosync &&
+      !synchronize (&ad->ad_syncaddr, &ad->ad_timediff))
+    {
+      /*
+       * Hope the clocks are synced!
+       */
+      ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
+      debug ("authdes_refresh: unable to synchronize with server");
+    }
+  ad->ad_xkey = auth->ah_key;
+  pkey.n_bytes = (char *) (ad->ad_pkey);
+  pkey.n_len = strlen ((char *) ad->ad_pkey) + 1;
+  if (key_encryptsession_pk (ad->ad_servername, &pkey, &ad->ad_xkey) < 0)
+    {
+      debug ("authdes_create: unable to encrypt conversation key");
+      return (FALSE);
+    }
+  cred->adc_fullname.key = ad->ad_xkey;
+  cred->adc_namekind = ADN_FULLNAME;
+  cred->adc_fullname.name = ad->ad_fullname;
+  return (TRUE);
+}
+
+/*
+ * 5. Destroy
+ */
+static void
+authdes_destroy (AUTH * auth)
+{
+  struct ad_private *ad = AUTH_PRIVATE (auth);
+
+  FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
+  FREE (ad->ad_servername, ad->ad_servernamelen + 1);
+  FREE (ad, sizeof (struct ad_private));
+  FREE (auth, sizeof (AUTH));
+}
+
+/*
+ * Synchronize with the server at the given address, that is,
+ * adjust timep to reflect the delta between our clocks
+ */
+static bool_t
+synchronize (struct sockaddr *syncaddr, struct timeval *timep)
+{
+  struct timeval mytime;
+  struct timeval timeout;
+
+  timeout.tv_sec = RTIME_TIMEOUT;
+  timeout.tv_usec = 0;
+  if (rtime ((struct sockaddr_in *) syncaddr, timep, &timeout) < 0)
+    return (FALSE);
+
+  gettimeofday (&mytime, (struct timezone *) NULL);
+  timep->tv_sec -= mytime.tv_sec;
+  if (mytime.tv_usec > timep->tv_usec)
+    {
+      timep->tv_sec -= 1;
+      timep->tv_usec += MILLION;
+    }
+  timep->tv_usec -= mytime.tv_usec;
+  return (TRUE);
+}
diff --git a/sunrpc/authdes_prot.c b/sunrpc/authdes_prot.c
new file mode 100644
index 0000000000..3c6eacced6
--- /dev/null
+++ b/sunrpc/authdes_prot.c
@@ -0,0 +1,81 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)authdes_prot.c	2.1 88/07/29 4.0 RPCSRC; from 1.6 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * authdes_prot.c, XDR routines for DES authentication
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+
+#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
+
+bool_t
+xdr_authdes_cred (XDR * xdrs, struct authdes_cred *cred)
+{
+  /*
+   * Unrolled xdr
+   */
+  ATTEMPT (xdr_enum (xdrs, (enum_t *) & cred->adc_namekind));
+  switch (cred->adc_namekind)
+    {
+    case ADN_FULLNAME:
+      ATTEMPT (xdr_string (xdrs, &cred->adc_fullname.name, MAXNETNAMELEN));
+      ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_fullname.key, sizeof (des_block)));
+      ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_fullname.window, sizeof (cred->adc_fullname.window)));
+      return (TRUE);
+    case ADN_NICKNAME:
+      ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_nickname, sizeof (cred->adc_nickname)));
+      return TRUE;
+    default:
+      return FALSE;
+    }
+}
+
+
+bool_t
+xdr_authdes_verf (register XDR * xdrs, register struct authdes_verf * verf)
+{
+  /*
+   * Unrolled xdr
+   */
+  ATTEMPT (xdr_opaque (xdrs, (caddr_t) & verf->adv_xtimestamp,
+		       sizeof (des_block)));
+  ATTEMPT (xdr_opaque (xdrs, (caddr_t) & verf->adv_int_u,
+		       sizeof (verf->adv_int_u)));
+  return TRUE;
+}
diff --git a/sunrpc/des.h b/sunrpc/des.h
new file mode 100644
index 0000000000..68bd7c47ab
--- /dev/null
+++ b/sunrpc/des.h
@@ -0,0 +1,83 @@
+/*  @(#)des.h   2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI  */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*
+ * Generic DES driver interface
+ * Keep this file hardware independent!
+ * Copyright (c) 1986 by Sun Microsystems, Inc.
+ */
+
+#ifndef _DES_H
+#define _DES_H
+
+#include <sys/types.h>
+
+#define DES_MAXLEN 	65536	/* maximum # of bytes to encrypt  */
+#define DES_QUICKLEN	16	/* maximum # of bytes to encrypt quickly */
+
+enum desdir
+  {
+    ENCRYPT, DECRYPT
+  };
+enum desmode
+  {
+    CBC, ECB
+  };
+
+/*
+ * parameters to ioctl call
+ */
+struct desparams
+  {
+    u_char des_key[8];		/* key (with low bit parity) */
+    enum desdir des_dir;	/* direction */
+    enum desmode des_mode;	/* mode */
+    u_char des_ivec[8];		/* input vector */
+    unsigned des_len;		/* number of bytes to crypt */
+    union
+      {
+	u_char UDES_data[DES_QUICKLEN];
+	u_char *UDES_buf;
+      }
+    UDES;
+#define des_data UDES.UDES_data	/* direct data here if quick */
+#define des_buf	UDES.UDES_buf	/* otherwise, pointer to data */
+  };
+
+/*
+ * Encrypt an arbitrary sized buffer
+ */
+#define	DESIOCBLOCK	_IOWR(d, 6, struct desparams)
+
+/* 
+ * Encrypt of small amount of data, quickly
+ */
+#define DESIOCQUICK	_IOWR(d, 7, struct desparams)
+
+#endif
diff --git a/sunrpc/des_crypt.c b/sunrpc/des_crypt.c
new file mode 100644
index 0000000000..7a4bc5d6cf
--- /dev/null
+++ b/sunrpc/des_crypt.c
@@ -0,0 +1,120 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSID)
+static char sccsid[] = "@(#)des_crypt.c	2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
+#endif
+/*
+ * des_crypt.c, DES encryption library routines
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+#include <sys/types.h>
+#include <rpc/des_crypt.h>
+#include "des.h"
+
+extern int _des_crypt (char *, unsigned, struct desparams *);
+
+/*
+ * Copy 8 bytes
+ */
+#define COPY8(src, dst) { \
+	register char *a = (char *) dst; \
+	register char *b = (char *) src; \
+	*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+	*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+}
+
+/*
+ * Copy multiple of 8 bytes
+ */
+#define DESCOPY(src, dst, len) { \
+	register char *a = (char *) dst; \
+	register char *b = (char *) src; \
+	register int i; \
+	for (i = (int) len; i > 0; i -= 8) { \
+		*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+		*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+	} \
+}
+
+/*
+ * Common code to cbc_crypt() & ecb_crypt()
+ */
+static int
+common_crypt (char *key, char *buf, register unsigned len,
+	      unsigned mode, register struct desparams *desp)
+{
+  register int desdev;
+
+  if ((len % 8) != 0 || len > DES_MAXDATA)
+    return DESERR_BADPARAM;
+
+  desp->des_dir =
+    ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
+
+  desdev = mode & DES_DEVMASK;
+  COPY8 (key, desp->des_key);
+  /* 
+   * software
+   */
+  if (!_des_crypt (buf, len, desp))
+    return DESERR_HWERROR;
+
+  return desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE;
+}
+
+/*
+ * CBC mode encryption
+ */
+int
+cbc_crypt (char *key, char *buf, unsigned int len, unsigned int mode,
+	   char *ivec)
+{
+  int err;
+  struct desparams dp;
+
+  dp.des_mode = CBC;
+  COPY8 (ivec, dp.des_ivec);
+  err = common_crypt (key, buf, len, mode, &dp);
+  COPY8 (dp.des_ivec, ivec);
+  return err;
+}
+
+
+/*
+ * ECB mode encryption
+ */
+int
+ecb_crypt (char *key, char *buf, unsigned int len, unsigned int mode)
+{
+  struct desparams dp;
+
+  dp.des_mode = ECB;
+  return common_crypt (key, buf, len, mode, &dp);
+}
diff --git a/sunrpc/des_soft.c b/sunrpc/des_soft.c
new file mode 100644
index 0000000000..ae12d7b0a6
--- /dev/null
+++ b/sunrpc/des_soft.c
@@ -0,0 +1,68 @@
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)des_soft.c	2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*
+ * Table giving odd parity in the low bit for ASCII characters
+ */
+static char partab[128] =
+{
+  0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
+  0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
+  0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+  0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
+  0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
+  0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
+  0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
+  0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
+  0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+  0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
+  0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
+  0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
+  0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
+  0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
+  0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+  0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
+};
+
+/*
+ * Add odd parity to low bit of 8 byte key
+ */
+void
+des_setparity (char *p)
+{
+  int i;
+
+  for (i = 0; i < 8; i++)
+    {
+      *p = partab[*p & 0x7f];
+      p++;
+    }
+}
diff --git a/sunrpc/key_call.c b/sunrpc/key_call.c
new file mode 100644
index 0000000000..ba1c2638fb
--- /dev/null
+++ b/sunrpc/key_call.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * The original source is from the RPCSRC 4.0 package from Sun Microsystems.
+ * The Interface to keyserver protocoll 2 was added by 
+ * Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/auth.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <rpc/key_prot.h>
+
+#define KEY_TIMEOUT	5	/* per-try timeout in seconds */
+#define KEY_NRETRY	12	/* number of retries */
+
+#define debug(msg)		/* turn off debugging */
+
+extern int _openchild (char *command, FILE ** fto, FILE ** ffrom);
+
+
+static int key_call (u_long, xdrproc_t xdr_arg, char *,
+		     xdrproc_t xdr_rslt, char *);
+
+static struct timeval trytimeout = {KEY_TIMEOUT, 0};
+static struct timeval tottimeout = {KEY_TIMEOUT * KEY_NRETRY, 0};
+
+int
+key_setsecret (char *secretkey)
+{
+  keystatus status;
+
+  if (!key_call ((u_long) KEY_SET, (xdrproc_t) xdr_keybuf, secretkey, 
+		 (xdrproc_t) xdr_keystatus, (char *) &status))
+    return -1;
+  if (status != KEY_SUCCESS)
+    {
+      debug ("set status is nonzero");
+      return -1;
+    }
+  return 0;
+}
+
+/* key_secretkey_is_set() returns 1 if the keyserver has a secret key
+ * stored for the caller's effective uid; it returns 0 otherwise
+ *
+ * N.B.:  The KEY_NET_GET key call is undocumented.  Applications shouldn't
+ * be using it, because it allows them to get the user's secret key.
+ */
+int
+key_secretkey_is_set (void)
+{
+  struct key_netstres kres;
+
+  memset (&kres, 0, sizeof (kres));
+  if (key_call ((u_long) KEY_NET_GET, (xdrproc_t) xdr_void, (char *) NULL,
+		(xdrproc_t) xdr_key_netstres, (char *) &kres) &&
+      (kres.status == KEY_SUCCESS) &&
+      (kres.key_netstres_u.knet.st_priv_key[0] != 0))
+    {
+      /* avoid leaving secret key in memory */
+      memset (kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
+      return 1;
+    }
+  return 0;
+}
+
+int
+key_encryptsession (char *remotename, des_block * deskey)
+{
+  cryptkeyarg arg;
+  cryptkeyres res;
+
+  arg.remotename = remotename;
+  arg.deskey = *deskey;
+  if (!key_call ((u_long) KEY_ENCRYPT, (xdrproc_t) xdr_cryptkeyarg, 
+		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+    return -1;
+
+  if (res.status != KEY_SUCCESS)
+    {
+      debug ("encrypt status is nonzero");
+      return -1;
+    }
+  *deskey = res.cryptkeyres_u.deskey;
+  return 0;
+}
+
+int
+key_decryptsession (char *remotename, des_block * deskey)
+{
+  cryptkeyarg arg;
+  cryptkeyres res;
+
+  arg.remotename = remotename;
+  arg.deskey = *deskey;
+  if (!key_call ((u_long) KEY_DECRYPT, (xdrproc_t) xdr_cryptkeyarg,
+		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+    return -1;
+  if (res.status != KEY_SUCCESS)
+    {
+      debug ("decrypt status is nonzero");
+      return -1;
+    }
+  *deskey = res.cryptkeyres_u.deskey;
+  return 0;
+}
+
+int
+key_encryptsession_pk (char *remotename, netobj * remotekey,
+		       des_block * deskey)
+{
+  cryptkeyarg2 arg;
+  cryptkeyres res;
+
+  arg.remotename = remotename;
+  arg.remotekey = *remotekey;
+  arg.deskey = *deskey;
+  if (!key_call ((u_long) KEY_ENCRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2, 
+		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+    return -1;
+
+  if (res.status != KEY_SUCCESS)
+    {
+      debug ("encrypt status is nonzero");
+      return -1;
+    }
+  *deskey = res.cryptkeyres_u.deskey;
+  return 0;
+}
+
+int
+key_decryptsession_pk (char *remotename, netobj * remotekey,
+		       des_block * deskey)
+{
+  cryptkeyarg2 arg;
+  cryptkeyres res;
+
+  arg.remotename = remotename;
+  arg.remotekey = *remotekey;
+  arg.deskey = *deskey;
+  if (!key_call ((u_long) KEY_DECRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2, 
+		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+    return -1;
+
+  if (res.status != KEY_SUCCESS)
+    {
+      debug ("decrypt status is nonzero");
+      return -1;
+    }
+  *deskey = res.cryptkeyres_u.deskey;
+  return 0;
+}
+
+int
+key_gendes (des_block * key)
+{
+  struct sockaddr_in sin;
+  CLIENT *client;
+  int socket;
+  enum clnt_stat stat;
+
+  sin.sin_family = AF_INET;
+  sin.sin_port = 0;
+  sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+  bzero (sin.sin_zero, sizeof (sin.sin_zero));
+  socket = RPC_ANYSOCK;
+  client = clntudp_bufcreate (&sin, (u_long) KEY_PROG, (u_long) KEY_VERS,
+			      trytimeout, &socket, RPCSMALLMSGSIZE,
+			      RPCSMALLMSGSIZE);
+  if (client == NULL)
+    return -1;
+
+  stat = clnt_call (client, KEY_GEN, (xdrproc_t) xdr_void, NULL,
+		    (xdrproc_t) xdr_des_block, (caddr_t) key, tottimeout);
+  clnt_destroy (client);
+  close (socket);
+  if (stat != RPC_SUCCESS)
+    return -1;
+
+  return 0;
+}
+
+int
+key_setnet (struct key_netstarg *arg)
+{
+  keystatus status;
+
+  if (!key_call ((u_long) KEY_NET_PUT, (xdrproc_t) xdr_key_netstarg, 
+		 (char *) arg,(xdrproc_t) xdr_keystatus, (char *) &status))
+    return -1;
+
+  if (status != KEY_SUCCESS)
+    {
+      debug ("key_setnet status is nonzero");
+      return -1;
+    }
+  return 1;
+}
+
+int
+key_get_conv (char *pkey, des_block * deskey)
+{
+  cryptkeyres res;
+
+  if (!key_call ((u_long) KEY_GET_CONV, (xdrproc_t) xdr_keybuf, pkey,
+		 (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+    return -1;
+
+  if (res.status != KEY_SUCCESS)
+    {
+      debug ("get_conv status is nonzero");
+      return -1;
+    }
+  *deskey = res.cryptkeyres_u.deskey;
+  return 0;
+}
+
+/*
+ * Hack to allow the keyserver to use AUTH_DES (for authenticated
+ * NIS+ calls, for example).  The only functions that get called
+ * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
+ *
+ * The approach is to have the keyserver fill in pointers to local
+ * implementations of these functions, and to call those in key_call().
+ */
+
+cryptkeyres *(*__key_encryptsession_pk_LOCAL) (uid_t, char *) = 0;
+cryptkeyres *(*__key_decryptsession_pk_LOCAL) (uid_t, char *) = 0;
+des_block *(*__key_gendes_LOCAL) (uid_t, char *) = 0;
+
+static int
+key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
+	  xdrproc_t xdr_rslt, char *rslt)
+{
+  XDR xdrargs;
+  XDR xdrrslt;
+  FILE *fargs;
+  FILE *frslt;
+  void (*osigchild) (int);
+  union wait status;
+  int pid;
+  int success;
+  uid_t ruid;
+  uid_t euid;
+  static char MESSENGER[] = "/usr/etc/keyenvoy";
+
+  success = 1;
+  osigchild = signal (SIGCHLD, SIG_IGN);
+
+  if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL)
+    {
+      cryptkeyres *res;
+      res = (*__key_encryptsession_pk_LOCAL) (geteuid (), arg);
+      *(cryptkeyres *) rslt = *res;
+      return 1;
+    }
+  else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL)
+    {
+      cryptkeyres *res;
+      res = (*__key_decryptsession_pk_LOCAL) (geteuid (), arg);
+      *(cryptkeyres *) rslt = *res;
+      return 1;
+    }
+  else if (proc == KEY_GEN && __key_gendes_LOCAL)
+    {
+      des_block *res;
+      res = (*__key_gendes_LOCAL) (geteuid (), 0);
+      *(des_block *) rslt = *res;
+      return 1;
+    }
+
+  /*
+   * We are going to exec a set-uid program which makes our effective uid
+   * zero, and authenticates us with our real uid. We need to make the
+   * effective uid be the real uid for the setuid program, and
+   * the real uid be the effective uid so that we can change things back.
+   */
+  euid = geteuid ();
+  ruid = getuid ();
+  setreuid (euid, ruid);
+  pid = _openchild (MESSENGER, &fargs, &frslt);
+  setreuid (ruid, euid);
+  if (pid < 0)
+    {
+      debug ("open_streams");
+      return (0);
+    }
+  xdrstdio_create (&xdrargs, fargs, XDR_ENCODE);
+  xdrstdio_create (&xdrrslt, frslt, XDR_DECODE);
+
+  if (!xdr_u_long (&xdrargs, &proc) || !(*xdr_arg) (&xdrargs, arg))
+    {
+      debug ("xdr args");
+      success = 0;
+    }
+  fclose (fargs);
+
+  if (success && !(*xdr_rslt) (&xdrrslt, rslt))
+    {
+      debug ("xdr rslt");
+      success = 0;
+    }
+
+#ifdef NOTDEF
+  /*
+   * WARNING! XXX
+   * The original code appears first.  wait4 returns only after the process
+   * with the requested pid terminates.  The effect of using wait() instead
+   * has not been determined.
+   */
+  fclose (frslt);
+  if (wait4 (pid, &status, 0, NULL) < 0 || status.w_retcode != 0)
+    {
+      debug ("wait4");
+      success = 0;
+    }
+#endif /* def NOTDEF */
+  if (wait (&status) < 0 || status.w_retcode != 0)
+    {
+      debug ("wait");
+      success = 0;
+    }
+  signal (SIGCHLD, osigchild);
+
+  return (success);
+}
diff --git a/sunrpc/key_prot.c b/sunrpc/key_prot.c
new file mode 100644
index 0000000000..5de8e25420
--- /dev/null
+++ b/sunrpc/key_prot.c
@@ -0,0 +1,161 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#pragma ident	"@(#)key_prot.x	1.7	94/04/29 SMI"
+
+/* Copyright (c)  1990, 1991 Sun Microsystems, Inc. */
+
+#include "rpc/key_prot.h"
+
+bool_t
+xdr_keystatus (XDR * xdrs, keystatus * objp)
+{
+  if (!xdr_enum (xdrs, (enum_t *) objp))
+    return FALSE;
+
+  return TRUE;
+}
+
+bool_t
+xdr_keybuf (XDR * xdrs, keybuf objp)
+{
+  if (!xdr_opaque (xdrs, objp, HEXKEYBYTES))
+    return FALSE;
+
+  return TRUE;
+}
+
+bool_t
+xdr_netnamestr (XDR * xdrs, netnamestr * objp)
+{
+  if (!xdr_string (xdrs, objp, MAXNETNAMELEN))
+    return FALSE;
+
+  return TRUE;
+}
+
+bool_t
+xdr_cryptkeyarg (XDR * xdrs, cryptkeyarg * objp)
+{
+  if (!xdr_netnamestr (xdrs, &objp->remotename))
+    return FALSE;
+
+  if (!xdr_des_block (xdrs, &objp->deskey))
+    return FALSE;
+
+  return TRUE;
+}
+
+bool_t
+xdr_cryptkeyarg2 (XDR * xdrs, cryptkeyarg2 * objp)
+{
+  if (!xdr_netnamestr (xdrs, &objp->remotename))
+    return FALSE;
+  if (!xdr_netobj (xdrs, &objp->remotekey))
+    return FALSE;
+  if (!xdr_des_block (xdrs, &objp->deskey))
+    return FALSE;
+  return TRUE;
+}
+
+bool_t
+xdr_cryptkeyres (XDR * xdrs, cryptkeyres * objp)
+{
+  if (!xdr_keystatus (xdrs, &objp->status))
+    return FALSE;
+  switch (objp->status)
+    {
+    case KEY_SUCCESS:
+      if (!xdr_des_block (xdrs, &objp->cryptkeyres_u.deskey))
+	return FALSE;
+      break;
+    default:
+      break;
+    }
+  return TRUE;
+}
+
+bool_t
+xdr_unixcred (XDR * xdrs, unixcred * objp)
+{
+  if (!xdr_u_int (xdrs, &objp->uid))
+    return FALSE;
+  if (!xdr_u_int (xdrs, &objp->gid))
+    return FALSE;
+  if (!xdr_array (xdrs, (char **) &objp->gids.gids_val,
+		  (u_int *) & objp->gids.gids_len, MAXGIDS,
+		  sizeof (u_int), (xdrproc_t) xdr_u_int))
+    return FALSE;
+  return TRUE;
+}
+
+bool_t
+xdr_getcredres (XDR * xdrs, getcredres * objp)
+{
+  if (!xdr_keystatus (xdrs, &objp->status))
+    return FALSE;
+  switch (objp->status)
+    {
+    case KEY_SUCCESS:
+      if (!xdr_unixcred (xdrs, &objp->getcredres_u.cred))
+	return FALSE;
+      break;
+    default:
+      break;
+    }
+  return TRUE;
+}
+
+bool_t
+xdr_key_netstarg (XDR * xdrs, key_netstarg * objp)
+{
+  if (!xdr_keybuf (xdrs, objp->st_priv_key))
+    return FALSE;
+  if (!xdr_keybuf (xdrs, objp->st_pub_key))
+    return FALSE;
+  if (!xdr_netnamestr (xdrs, &objp->st_netname))
+    return FALSE;
+  return TRUE;
+}
+
+bool_t
+xdr_key_netstres (XDR * xdrs, key_netstres * objp)
+{
+  if (!xdr_keystatus (xdrs, &objp->status))
+    return FALSE;
+  switch (objp->status)
+    {
+    case KEY_SUCCESS:
+      if (!xdr_key_netstarg (xdrs, &objp->key_netstres_u.knet))
+	return FALSE;
+      break;
+    default:
+      break;
+    }
+  return TRUE;
+}
diff --git a/sunrpc/netname.c b/sunrpc/netname.c
new file mode 100644
index 0000000000..be6c2f2ae1
--- /dev/null
+++ b/sunrpc/netname.c
@@ -0,0 +1,201 @@
+/* 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 <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+#include "nsswitch.h"
+
+#define	OPSYS_LEN 4
+#define	MAXIPRINT (11)		/* max length of printed integer */
+static const char *OPSYS = "unix";
+
+int
+user2netname (char netname[MAXNETNAMELEN + 1], const uid_t uid,
+	      const char *domain)
+{
+  char dfltdom[MAXNETNAMELEN + 1];
+  size_t i;
+
+  if (domain == NULL)
+    {
+      if (getdomainname (dfltdom, sizeof (dfltdom)) < 0)
+	return 0;
+    }
+  else
+    {
+      strncpy (dfltdom, domain, MAXNETNAMELEN);
+      dfltdom[MAXNETNAMELEN] = '\0';
+    }
+
+  if ((strlen (dfltdom) + OPSYS_LEN + 3 + MAXIPRINT) > (size_t) MAXNETNAMELEN)
+    return 0;
+
+  sprintf (netname, "%s.%d@%s", OPSYS, uid, dfltdom);
+  i = strlen (netname);
+  if (netname[i - 1] == '.')
+    netname[i - 1] = '\0';
+  return 1;
+}
+
+int
+host2netname (char netname[MAXNETNAMELEN + 1], const char *host,
+	      const char *domain)
+{
+  char *p;
+  char hostname[MAXHOSTNAMELEN + 1];
+  char domainname[MAXHOSTNAMELEN + 1];
+  char *dot_in_host;
+  size_t i;
+
+  netname[0] = '\0';		/* make null first (no need for memset) */
+
+  if (host == NULL)
+    gethostname (hostname, MAXHOSTNAMELEN);
+  else
+    {
+      strncpy (hostname, host, MAXHOSTNAMELEN);
+      hostname[MAXHOSTNAMELEN] = '\0';
+    }
+
+  dot_in_host = strchr (hostname, '.');
+  if (domain == NULL)
+    {
+      p = dot_in_host;
+      if (p)
+	{
+	  strncpy (domainname, p, MAXHOSTNAMELEN);
+	  domainname[MAXHOSTNAMELEN] = '\0';
+	}
+      else
+	{
+	  domainname[0] = 0;
+	  getdomainname (domainname, MAXHOSTNAMELEN);
+	}
+    }
+  else
+    {
+      strncpy (domainname, domain, MAXHOSTNAMELEN);
+      domainname[MAXHOSTNAMELEN] = '\0';
+    }
+
+  i = strlen (domainname);
+  if (i == 0)
+    /* No domainname */
+    return 0;
+  if (domainname[i - 1] == '.')
+    domainname[i - 1] = 0;
+
+  if (dot_in_host)		/* strip off rest of name */
+    *dot_in_host = '\0';
+
+  if ((strlen (domainname) + strlen (hostname) + OPSYS_LEN + 3)
+      > MAXNETNAMELEN)
+    return 0;
+
+  sprintf (netname, "%s.%s@%s", OPSYS, hostname, domainname);
+  return 1;
+}
+
+int
+getnetname (char name[MAXNETNAMELEN + 1])
+{
+  uid_t uid;
+  int dummy;
+
+  uid = geteuid ();
+  if (uid == 0)
+    dummy = host2netname (name, NULL, NULL);
+  else
+    dummy = user2netname (name, uid, NULL);
+  return (dummy);
+}
+
+/* Type of the lookup function for netname2user.  */
+typedef int (*netname2user_function) (const char netname[MAXNETNAMELEN + 1],
+				      uid_t *, gid_t *, int *, gid_t *);
+/* The lookup function for the first entry of this service.  */
+extern int __nss_publickey_lookup (service_user ** nip, const char *name,
+				   void **fctp);
+
+int
+netname2user (const char netname[MAXNETNAMELEN + 1], uid_t * uidp, gid_t * gidp,
+	      int *gidlenp, gid_t * gidlist)
+{
+  static service_user *startp = NULL;
+  static netname2user_function start_fct;
+  service_user *nip;
+  netname2user_function fct;
+  enum nss_status status = NSS_STATUS_UNAVAIL;
+  int no_more;
+
+  if (startp == NULL)
+    {
+      no_more = __nss_publickey_lookup (&nip, "netname2user", (void **) &fct);
+      if (no_more)
+	startp = (service_user *) - 1;
+      else
+	{
+	  startp = nip;
+	  start_fct = fct;
+	}
+    }
+  else
+    {
+      fct = start_fct;
+      no_more = (nip = startp) == (service_user *) - 1;
+    }
+
+  while (!no_more)
+    {
+      status = (*fct) (netname, uidp, gidp, gidlenp, gidlist);
+
+      no_more = __nss_next (&nip, "netname2user", (void **) &fct, status, 0);
+    }
+
+  return status == NSS_STATUS_SUCCESS;
+}
+
+int
+netname2host (const char netname[MAXNETNAMELEN + 1], char *hostname,
+	      const int hostlen)
+{
+  char *p1, *p2;
+  char buffer[MAXNETNAMELEN + 1];
+
+  p1 = strchr (buffer, '.');
+  if (p1 == NULL)
+    return 0;
+  p1++;
+
+  p2 = strchr (p1, '@');
+  if (p2 == NULL)
+    return 0;
+  *p2 = '\0';
+
+  if (hostlen > MAXNETNAMELEN)
+    return 0;
+
+  strncpy (hostname, p1, hostlen);
+  hostname[hostlen] = '\0';
+
+  return 1;
+}
diff --git a/sunrpc/openchild.c b/sunrpc/openchild.c
new file mode 100644
index 0000000000..2fa26fae45
--- /dev/null
+++ b/sunrpc/openchild.c
@@ -0,0 +1,112 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)openchild.c	2.3 88/08/15 4.0 RPCSRC; from 1.7 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * Open two pipes to a child process, one for reading, one for writing.
+ * The pipes are accessed by FILE pointers. This is NOT a public
+ * interface, but for internal use only!
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/clnt.h>
+
+static char SHELL[] = "/bin/sh";
+
+/*
+ * returns pid, or -1 for failure
+ */
+int
+_openchild (char *command, FILE ** fto, FILE ** ffrom)
+{
+  int i;
+  int pid;
+  int pdto[2];
+  int pdfrom[2];
+  char *com;
+
+  if (pipe (pdto) < 0)
+    goto error1;
+  if (pipe (pdfrom) < 0)
+    goto error2;
+  switch (pid = vfork ())
+    {
+    case -1:
+      goto error3;
+
+    case 0:
+      /*
+       * child: read from pdto[0], write into pdfrom[1]
+       */
+      close (0);
+      dup (pdto[0]);
+      close (1);
+      dup (pdfrom[1]);
+      for (i = _rpc_dtablesize () - 1; i >= 3; i--)
+	close (i);
+      com = malloc (strlen (command) + 6);
+      if (com == NULL)
+	_exit (~0);
+      sprintf (com, "exec %s", command);
+      execl (SHELL, basename (SHELL), "-c", com, NULL);
+      _exit (~0);
+
+    default:
+      /*
+       * parent: write into pdto[1], read from pdfrom[0]
+       */
+      *fto = fdopen (pdto[1], "w");
+      close (pdto[0]);
+      *ffrom = fdopen (pdfrom[0], "r");
+      close (pdfrom[1]);
+      break;
+    }
+  return pid;
+
+  /*
+   * error cleanup and return
+   */
+error3:
+  close (pdfrom[0]);
+  close (pdfrom[1]);
+error2:
+  close (pdto[0]);
+  close (pdto[1]);
+error1:
+  return -1;
+}
diff --git a/sysdeps/generic/rpc/auth.h b/sunrpc/rpc/auth.h
index b4022853d5..22174193d4 100644
--- a/sysdeps/generic/rpc/auth.h
+++ b/sunrpc/rpc/auth.h
@@ -42,8 +42,6 @@
 
 #define _RPC_AUTH_H	1
 #include <features.h>
-#include <sys/types.h>
-#include <rpc/types.h>
 #include <rpc/xdr.h>
 
 __BEGIN_DECLS
@@ -101,7 +99,7 @@ struct AUTH {
   struct auth_ops {
     void (*ah_nextverf) __P ((AUTH *));
     int  (*ah_marshal) __P ((AUTH *, XDR *));	/* nextverf & serialize */
-    int  (*ah_validate) __P ((AUTH *, struct opaque_auth *));
+    int  (*ah_validate) __P ((AUTH *, struct opaque_auth *));	
 						/* validate verifier */
     int  (*ah_refresh) __P ((AUTH *));		/* refresh credentials */
     void (*ah_destroy) __P ((AUTH *));     	/* destroy this structure */
@@ -165,7 +163,7 @@ extern AUTH *authunix_create __P ((char *__machname, __uid_t __uid,
 				   __gid_t *__aup_gids));
 extern AUTH *authunix_create_default __P ((void));
 extern AUTH *authnone_create __P ((void));
-extern AUTH *authdes_create __P ((char *__servername, u_int __window,
+extern AUTH *authdes_create __P ((const char *__servername, u_int __window, 
 				  struct sockaddr *__syncaddr,
 				  des_block *__ckey));
 
@@ -178,10 +176,35 @@ extern AUTH *authdes_create __P ((char *__servername, u_int __window,
 #define AUTH_KERB       4               /* kerberos style */
 
 /*
- * XDR an opaque authentication struct.
+ *  Netname manipulating functions
+ *
  */
-extern bool_t xdr_opaque_auth __P ((XDR *__xdrs, struct opaque_auth *__ap));
+extern int getnetname __P ((char *));
+extern int host2netname __P ((char *, __const char *, __const char *));
+extern int user2netname __P ((char *, __const uid_t, __const char *));
+extern int netname2user __P ((__const char *, uid_t *, gid_t *, int *, 
+			      gid_t *));
+extern int netname2host __P ((__const char *, char *, __const int));
+
+/*
+ *
+ * These routines interface to the keyserv daemon
+ *
+ */
+extern int key_decryptsession __P ((char *, des_block *));
+extern int key_decryptsession_pk __P ((char *, netobj *, des_block *));
+extern int key_encryptsession __P ((char *, des_block *));
+extern int key_encryptsession_pk __P ((char *, netobj *, des_block *));
+extern int key_gendes __P ((des_block *));
+extern int key_setsecret __P ((char *));
+extern int key_secretkey_is_set __P ((void));
+extern int key_get_conv __P ((char *, des_block *));
 
 __END_DECLS
 
+/* This is for compiling the glibc NIS+ code with DES auth. */
+#ifdef _LIBC
+#define HAVE_SECURE_RPC 1
+#endif
+
 #endif /* rpc/auth.h */
diff --git a/sunrpc/rpc/auth_des.h b/sunrpc/rpc/auth_des.h
new file mode 100644
index 0000000000..87fb8f0e99
--- /dev/null
+++ b/sunrpc/rpc/auth_des.h
@@ -0,0 +1,104 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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.  */
+
+#ifndef _RPC_AUTH_DES_H
+
+#define _RPC_AUTH_DES_H	1
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/* There are two kinds of "names": fullnames and nicknames */
+enum authdes_namekind
+  {
+    ADN_FULLNAME,
+    ADN_NICKNAME
+  };
+
+/* A fullname contains the network name of the client,
+   a conversation key and the window */
+struct authdes_fullname
+  {
+    char *name;			/* network name of client, up to MAXNETNAMELEN */
+    des_block key;		/* conversation key */
+    u_long window;		/* associated window */
+  };
+
+/* A credential */
+struct authdes_cred
+  {
+    enum authdes_namekind adc_namekind;
+    struct authdes_fullname adc_fullname;
+    u_long adc_nickname;
+  };
+
+/* A des authentication verifier */
+struct authdes_verf
+  {
+    union
+      {
+	struct timeval adv_ctime;	/* clear time */
+	des_block adv_xtime;	/* crypt time */
+      }
+    adv_time_u;
+    u_long adv_int_u;
+  };
+
+/* des authentication verifier: client variety
+
+   adv_timestamp is the current time.
+   adv_winverf is the credential window + 1.
+   Both are encrypted using the conversation key. */
+#define adv_timestamp  adv_time_u.adv_ctime
+#define adv_xtimestamp adv_time_u.adv_xtime
+#define adv_winverf    adv_int_u
+
+/* des authentication verifier: server variety
+
+   adv_timeverf is the client's timestamp + client's window
+   adv_nickname is the server's nickname for the client.
+   adv_timeverf is encrypted using the conversation key. */
+#define adv_timeverf   adv_time_u.adv_ctime
+#define adv_xtimeverf  adv_time_u.adv_xtime
+#define adv_nickname   adv_int_u
+
+/* Map a des credential into a unix cred. */
+extern int authdes_getucred __P ((__const struct authdes_cred * __adc,
+				  uid_t * __uid, gid_t * __gid,
+				  short *__grouplen, gid_t * __groups));
+
+/* Get the public key for NAME and place it in KEY.  NAME can only be
+   up to MAXNETNAMELEN bytes long and the destination buffer KEY should
+   have HEXKEYBATES + 1 bytes long to fit all characters from the key.  */
+extern int getpublickey __P ((__const char *__name, char *__key));
+
+/* Get the secret key for NAME and place it in KEY.  PASSWD is used to
+   decrypt the encrypted key stored in the database.  NAME can only be
+   up to MAXNETNAMELEN bytes long and the destination buffer KEY
+   should have HEXKEYBATES + 1 bytes long to fit all characters from
+   the key.  */
+extern int getsecretkey __P ((__const char *__name, char *__key,
+			      __const char *__passwd));
+
+extern int rtime __P ((struct sockaddr_in *__addrp,  struct timeval *__timep,
+		       struct timeval *__timeout));
+
+__END_DECLS
+
+
+#endif /* rpc/auth_des.h */
diff --git a/sunrpc/rpc/des_crypt.h b/sunrpc/rpc/des_crypt.h
new file mode 100644
index 0000000000..e20cc38243
--- /dev/null
+++ b/sunrpc/rpc/des_crypt.h
@@ -0,0 +1,97 @@
+/*
+ * @(#)des_crypt.h	2.1 88/08/11 4.0 RPCSRC;	from 1.4 88/02/08 (C) 1986 SMI
+ *
+ * des_crypt.h, des library routine interface
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#ifndef __DES_CRYPT_H__
+#define __DES_CRYPT_H__ 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+#define DES_MAXDATA 8192	/* max bytes encrypted in one call */
+#define DES_DIRMASK (1 << 0)
+#define DES_ENCRYPT (0*DES_DIRMASK)	/* Encrypt */
+#define DES_DECRYPT (1*DES_DIRMASK)	/* Decrypt */
+
+
+#define DES_DEVMASK (1 << 1)
+#define	DES_HW (0*DES_DEVMASK)	/* Use hardware device */ 
+#define DES_SW (1*DES_DEVMASK)	/* Use software device */
+
+
+#define DESERR_NONE 0	/* succeeded */
+#define DESERR_NOHWDEVICE 1	/* succeeded, but hw device not available */
+#define DESERR_HWERROR 2	/* failed, hardware/driver error */
+#define DESERR_BADPARAM 3	/* failed, bad parameter to call */
+
+#define DES_FAILED(err) \
+	((err) > DESERR_NOHWDEVICE)
+
+/*
+ * cbc_crypt()
+ * ecb_crypt()
+ *
+ * Encrypt (or decrypt) len bytes of a buffer buf.
+ * The length must be a multiple of eight.
+ * The key should have odd parity in the low bit of each byte.
+ * ivec is the input vector, and is updated to the new one (cbc only).
+ * The mode is created by oring together the appropriate parameters.
+ * DESERR_NOHWDEVICE is returned if DES_HW was specified but
+ * there was no hardware to do it on (the data will still be
+ * encrypted though, in software).
+ */
+
+
+/*
+ * Cipher Block Chaining mode
+ */
+extern int cbc_crypt __P ((char *__key, char *__buf, unsigned __len,
+			   unsigned __mode, char *__ivec));
+
+/*
+ * Electronic Code Book mode
+ */
+extern int ecb_crypt __P ((char *__key, char *__buf, unsigned __len,
+			   unsigned __mode));
+
+/* 
+ * Set des parity for a key.
+ * DES parity is odd and in the low bit of each byte
+ */
+extern void des_setparity __P ((char *__key));
+
+__END_DECLS
+
+#endif
diff --git a/sunrpc/rpc/key_prot.h b/sunrpc/rpc/key_prot.h
new file mode 100644
index 0000000000..a23f2cd21b
--- /dev/null
+++ b/sunrpc/rpc/key_prot.h
@@ -0,0 +1,345 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _KEY_PROT_H_RPCGEN
+#define _KEY_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#pragma ident	"@(#)key_prot.x	1.7	94/04/29 SMI"
+
+/* Copyright (c)  1990, 1991 Sun Microsystems, Inc. */
+
+/* 
+ * Compiled from key_prot.x using rpcgen.
+ * DO NOT EDIT THIS FILE!
+ * This is NOT source code!
+ */
+#define PROOT 3
+#define HEXMODULUS "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"
+#define HEXKEYBYTES 48
+#define KEYSIZE 192
+#define KEYBYTES 24
+#define KEYCHECKSUMSIZE 16
+
+enum keystatus {
+	KEY_SUCCESS = 0,
+	KEY_NOSECRET = 1,
+	KEY_UNKNOWN = 2,
+	KEY_SYSTEMERR = 3,
+};
+typedef enum keystatus keystatus;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_keystatus(XDR *, keystatus*);
+#elif __STDC__ 
+extern  bool_t xdr_keystatus(XDR *, keystatus*);
+#else /* Old Style C */ 
+bool_t xdr_keystatus();
+#endif /* Old Style C */ 
+
+
+typedef char keybuf[HEXKEYBYTES];
+#ifdef __cplusplus 
+extern "C" bool_t xdr_keybuf(XDR *, keybuf);
+#elif __STDC__ 
+extern  bool_t xdr_keybuf(XDR *, keybuf);
+#else /* Old Style C */ 
+bool_t xdr_keybuf();
+#endif /* Old Style C */ 
+
+
+typedef char *netnamestr;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_netnamestr(XDR *, netnamestr*);
+#elif __STDC__ 
+extern  bool_t xdr_netnamestr(XDR *, netnamestr*);
+#else /* Old Style C */ 
+bool_t xdr_netnamestr();
+#endif /* Old Style C */ 
+
+
+struct cryptkeyarg {
+	netnamestr remotename;
+	des_block deskey;
+};
+typedef struct cryptkeyarg cryptkeyarg;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#elif __STDC__ 
+extern  bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#else /* Old Style C */ 
+bool_t xdr_cryptkeyarg();
+#endif /* Old Style C */ 
+
+
+struct cryptkeyarg2 {
+	netnamestr remotename;
+	netobj remotekey;
+	des_block deskey;
+};
+typedef struct cryptkeyarg2 cryptkeyarg2;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#elif __STDC__ 
+extern  bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#else /* Old Style C */ 
+bool_t xdr_cryptkeyarg2();
+#endif /* Old Style C */ 
+
+
+struct cryptkeyres {
+	keystatus status;
+	union {
+		des_block deskey;
+	} cryptkeyres_u;
+};
+typedef struct cryptkeyres cryptkeyres;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#elif __STDC__ 
+extern  bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#else /* Old Style C */ 
+bool_t xdr_cryptkeyres();
+#endif /* Old Style C */ 
+
+#define MAXGIDS 16
+
+struct unixcred {
+	u_int uid;
+	u_int gid;
+	struct {
+		u_int gids_len;
+		u_int *gids_val;
+	} gids;
+};
+typedef struct unixcred unixcred;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_unixcred(XDR *, unixcred*);
+#elif __STDC__ 
+extern  bool_t xdr_unixcred(XDR *, unixcred*);
+#else /* Old Style C */ 
+bool_t xdr_unixcred();
+#endif /* Old Style C */ 
+
+
+struct getcredres {
+	keystatus status;
+	union {
+		unixcred cred;
+	} getcredres_u;
+};
+typedef struct getcredres getcredres;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_getcredres(XDR *, getcredres*);
+#elif __STDC__ 
+extern  bool_t xdr_getcredres(XDR *, getcredres*);
+#else /* Old Style C */ 
+bool_t xdr_getcredres();
+#endif /* Old Style C */ 
+
+
+struct key_netstarg {
+	keybuf st_priv_key;
+	keybuf st_pub_key;
+	netnamestr st_netname;
+};
+typedef struct key_netstarg key_netstarg;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#elif __STDC__ 
+extern  bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#else /* Old Style C */ 
+bool_t xdr_key_netstarg();
+#endif /* Old Style C */ 
+
+
+struct key_netstres {
+	keystatus status;
+	union {
+		key_netstarg knet;
+	} key_netstres_u;
+};
+typedef struct key_netstres key_netstres;
+#ifdef __cplusplus 
+extern "C" bool_t xdr_key_netstres(XDR *, key_netstres*);
+#elif __STDC__ 
+extern  bool_t xdr_key_netstres(XDR *, key_netstres*);
+#else /* Old Style C */ 
+bool_t xdr_key_netstres();
+#endif /* Old Style C */ 
+
+
+#ifndef opaque
+#define opaque char
+#endif
+
+
+#define KEY_PROG ((u_long)100029)
+#define KEY_VERS ((u_long)1)
+
+#ifdef __cplusplus
+#define KEY_SET ((u_long)1)
+extern "C" keystatus * key_set_1(opaque *, CLIENT *);
+extern "C" keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern "C" cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern "C" cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern "C" des_block * key_gen_1(void *, CLIENT *);
+extern "C" des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern "C" getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#elif __STDC__
+#define KEY_SET ((u_long)1)
+extern  keystatus * key_set_1(opaque *, CLIENT *);
+extern  keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern  cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern  cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern  cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern  cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern  des_block * key_gen_1(void *, CLIENT *);
+extern  des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern  getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern  getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#else /* Old Style C */ 
+#define KEY_SET ((u_long)1)
+extern  keystatus * key_set_1();
+extern  keystatus * key_set_1_svc();
+#define KEY_ENCRYPT ((u_long)2)
+extern  cryptkeyres * key_encrypt_1();
+extern  cryptkeyres * key_encrypt_1_svc();
+#define KEY_DECRYPT ((u_long)3)
+extern  cryptkeyres * key_decrypt_1();
+extern  cryptkeyres * key_decrypt_1_svc();
+#define KEY_GEN ((u_long)4)
+extern  des_block * key_gen_1();
+extern  des_block * key_gen_1_svc();
+#define KEY_GETCRED ((u_long)5)
+extern  getcredres * key_getcred_1();
+extern  getcredres * key_getcred_1_svc();
+#endif /* Old Style C */ 
+#define KEY_VERS2 ((u_long)2)
+
+#ifdef __cplusplus
+extern "C" keystatus * key_set_2(opaque *, CLIENT *);
+extern "C" keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern "C" cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" des_block * key_gen_2(void *, CLIENT *);
+extern "C" des_block * key_gen_2_svc(void *, struct svc_req *);
+extern "C" getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern "C" cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern "C" cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern "C" keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern "C" keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern "C" key_netstres * key_net_get_2(void *, CLIENT *);
+extern "C" key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern "C" cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern "C" cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#elif __STDC__
+extern  keystatus * key_set_2(opaque *, CLIENT *);
+extern  keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern  cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern  cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern  cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern  cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern  des_block * key_gen_2(void *, CLIENT *);
+extern  des_block * key_gen_2_svc(void *, struct svc_req *);
+extern  getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern  getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern  cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern  cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern  cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern  cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern  keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern  keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern  key_netstres * key_net_get_2(void *, CLIENT *);
+extern  key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern  cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern  cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#else /* Old Style C */ 
+extern  keystatus * key_set_2();
+extern  keystatus * key_set_2_svc();
+extern  cryptkeyres * key_encrypt_2();
+extern  cryptkeyres * key_encrypt_2_svc();
+extern  cryptkeyres * key_decrypt_2();
+extern  cryptkeyres * key_decrypt_2_svc();
+extern  des_block * key_gen_2();
+extern  des_block * key_gen_2_svc();
+extern  getcredres * key_getcred_2();
+extern  getcredres * key_getcred_2_svc();
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern  cryptkeyres * key_encrypt_pk_2();
+extern  cryptkeyres * key_encrypt_pk_2_svc();
+#define KEY_DECRYPT_PK ((u_long)7)
+extern  cryptkeyres * key_decrypt_pk_2();
+extern  cryptkeyres * key_decrypt_pk_2_svc();
+#define KEY_NET_PUT ((u_long)8)
+extern  keystatus * key_net_put_2();
+extern  keystatus * key_net_put_2_svc();
+#define KEY_NET_GET ((u_long)9)
+extern  key_netstres * key_net_get_2();
+extern  key_netstres * key_net_get_2_svc();
+#define KEY_GET_CONV ((u_long)10)
+extern  cryptkeyres * key_get_conv_2();
+extern  cryptkeyres * key_get_conv_2_svc();
+#endif /* Old Style C */ 
+
+#endif /* !_KEY_PROT_H_RPCGEN */
diff --git a/sunrpc/rpcsvc/key_prot.x b/sunrpc/rpcsvc/key_prot.x
new file mode 100644
index 0000000000..af22a208c5
--- /dev/null
+++ b/sunrpc/rpcsvc/key_prot.x
@@ -0,0 +1,284 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part.  Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California  94043
+% */
+/*
+ * Key server protocol definition
+ * Copyright (C) 1990, 1991 Sun Microsystems, Inc.
+ *
+ * The keyserver is a public key storage/encryption/decryption service
+ * The encryption method used is based on the Diffie-Hellman exponential
+ * key exchange technology.
+ *
+ * The key server is local to each machine, akin to the portmapper.
+ * Under TI-RPC, communication with the keyserver is through the
+ * loopback transport.
+ *
+ * NOTE: This .x file generates the USER level headers for the keyserver.
+ * the KERNEL level headers are created by hand as they kernel has special
+ * requirements.
+ */
+
+%#pragma ident	"@(#)key_prot.x	1.7	94/04/29 SMI"
+%
+%/* Copyright (c)  1990, 1991 Sun Microsystems, Inc. */
+%
+%/* 
+% * Compiled from key_prot.x using rpcgen.
+% * DO NOT EDIT THIS FILE!
+% * This is NOT source code!
+% */
+
+/*
+ * PROOT and MODULUS define the way the Diffie-Hellman key is generated.
+ *
+ * MODULUS should be chosen as a prime of the form: MODULUS == 2*p + 1,
+ * where p is also prime.
+ *
+ * PROOT satisfies the following two conditions:
+ * (1) (PROOT ** 2) % MODULUS != 1
+ * (2) (PROOT ** p) % MODULUS != 1
+ *
+ */
+
+const PROOT = 3;
+const HEXMODULUS = "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b";
+
+const HEXKEYBYTES = 48;		/* HEXKEYBYTES == strlen(HEXMODULUS) */
+const KEYSIZE = 192;		/* KEYSIZE == bit length of key */
+const KEYBYTES = 24;		/* byte length of key */
+
+/*
+ * The first 16 hex digits of the encrypted secret key are used as
+ * a checksum in the database.
+ */
+const KEYCHECKSUMSIZE = 16;
+
+/*
+ * status of operation
+ */
+enum keystatus {
+	KEY_SUCCESS,	/* no problems */
+	KEY_NOSECRET,	/* no secret key stored */
+	KEY_UNKNOWN,	/* unknown netname */
+	KEY_SYSTEMERR 	/* system error (out of memory, encryption failure) */
+};
+
+typedef opaque keybuf[HEXKEYBYTES];	/* store key in hex */
+
+typedef string netnamestr<MAXNETNAMELEN>;
+
+/*
+ * Argument to ENCRYPT or DECRYPT 
+ */
+struct cryptkeyarg {
+	netnamestr remotename;
+	des_block deskey;
+};
+
+/*
+ * Argument to ENCRYPT_PK or DECRYPT_PK
+ */
+struct cryptkeyarg2 {
+	netnamestr remotename;
+	netobj	remotekey;	/* Contains a length up to 1024 bytes */
+	des_block deskey;
+};
+
+
+/*
+ * Result of ENCRYPT, DECRYPT, ENCRYPT_PK, and DECRYPT_PK
+ */
+union cryptkeyres switch (keystatus status) {
+case KEY_SUCCESS:
+	des_block deskey;
+default:
+	void;
+};
+
+const MAXGIDS  = 16;	/* max number of gids in gid list */
+
+/*
+ * Unix credential 
+ */	
+struct unixcred {
+	u_int uid;
+	u_int gid;
+	u_int gids<MAXGIDS>;	
+};
+
+/*
+ * Result returned from GETCRED
+ */
+union getcredres switch (keystatus status) {
+case KEY_SUCCESS:
+	unixcred cred;
+default:
+	void;
+};
+/*
+ * key_netstarg;
+ */
+
+struct key_netstarg {
+	keybuf st_priv_key;
+	keybuf st_pub_key;
+	netnamestr st_netname;
+};
+
+union key_netstres switch (keystatus status){
+case KEY_SUCCESS:
+	key_netstarg knet;
+default:
+	void;
+};	
+
+#ifdef RPC_HDR
+%
+%#ifndef opaque
+%#define opaque char
+%#endif
+%
+#endif
+program KEY_PROG {
+	version KEY_VERS {
+
+		/*
+		 * This is my secret key.
+	 	 * Store it for me.
+		 */
+		keystatus 
+		KEY_SET(keybuf) = 1;	
+	
+		/*
+		 * I want to talk to X.
+		 * Encrypt a conversation key for me.
+	 	 */
+		cryptkeyres
+		KEY_ENCRYPT(cryptkeyarg) = 2;	
+
+		/*
+		 * X just sent me a message.
+		 * Decrypt the conversation key for me.
+		 */
+		cryptkeyres
+		KEY_DECRYPT(cryptkeyarg) = 3;
+
+		/*
+		 * Generate a secure conversation key for me
+		 */
+		des_block 
+		KEY_GEN(void) = 4;
+
+		/*
+		 * Get me the uid, gid and group-access-list associated
+		 * with this netname (for kernel which cannot use NIS)
+		 */
+		getcredres
+		KEY_GETCRED(netnamestr) = 5;
+	} = 1;
+	version KEY_VERS2 {
+
+		/*
+		 * #######
+		 * Procedures 1-5 are identical to version 1
+		 * #######
+		 */
+
+		/*
+		 * This is my secret key.
+	 	 * Store it for me.
+		 */
+		keystatus 
+		KEY_SET(keybuf) = 1;	
+	
+		/*
+		 * I want to talk to X.
+		 * Encrypt a conversation key for me.
+	 	 */
+		cryptkeyres
+		KEY_ENCRYPT(cryptkeyarg) = 2;	
+
+		/*
+		 * X just sent me a message.
+		 * Decrypt the conversation key for me.
+		 */
+		cryptkeyres
+		KEY_DECRYPT(cryptkeyarg) = 3;
+
+		/*
+		 * Generate a secure conversation key for me
+		 */
+		des_block 
+		KEY_GEN(void) = 4;
+
+		/*
+		 * Get me the uid, gid and group-access-list associated
+		 * with this netname (for kernel which cannot use NIS)
+		 */
+		getcredres
+		KEY_GETCRED(netnamestr) = 5;
+		
+		/*
+		 * I want to talk to X. and I know X's public key
+		 * Encrypt a conversation key for me.
+	 	 */
+		cryptkeyres
+		KEY_ENCRYPT_PK(cryptkeyarg2) = 6;	
+
+		/*
+		 * X just sent me a message. and I know X's public key
+		 * Decrypt the conversation key for me.
+		 */
+		cryptkeyres
+		KEY_DECRYPT_PK(cryptkeyarg2) = 7;
+		
+		/* 
+		 * Store my public key, netname and private key. 
+		 */
+		keystatus
+		KEY_NET_PUT(key_netstarg) = 8;
+		
+		/*
+		 * Retrieve my public key, netname and private key. 
+		 */
+ 		key_netstres
+		KEY_NET_GET(void) = 9;
+		
+		/*
+		 * Return me the conversation key that is constructed 
+		 * from my secret key and this publickey. 
+		 */
+
+		cryptkeyres 
+		KEY_GET_CONV(keybuf) = 10; 
+
+		
+	} = 2;
+} = 100029;
+
+
diff --git a/sunrpc/rtime.c b/sunrpc/rtime.c
new file mode 100644
index 0000000000..baaced0d5d
--- /dev/null
+++ b/sunrpc/rtime.c
@@ -0,0 +1,146 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rtime.c	2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+/*
+ * rtime - get time from remote machine
+ *
+ * gets time, obtaining value from host
+ * on the udp/time socket.  Since timeserver returns
+ * with time of day in seconds since Jan 1, 1900,  must
+ * subtract seconds before Jan 1, 1970 to get
+ * what unix uses.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/clnt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <rpc/auth_des.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#define NYEARS	(u_long)(1970 - 1900)
+#define TOFFSET (u_long)(60*60*24*(365*NYEARS + (NYEARS/4)))
+
+static void do_close (int);
+
+static void
+do_close (int s)
+{
+  int save;
+
+  save = errno;
+  close (s);
+  __set_errno (save);
+}
+
+int
+rtime (struct sockaddr_in *addrp, struct timeval *timep,
+       struct timeval *timeout)
+{
+  int s;
+  fd_set readfds;
+  int res;
+  unsigned long thetime;
+  struct sockaddr_in from;
+  int fromlen;
+  int type;
+
+  if (timeout == NULL)
+    type = SOCK_STREAM;
+  else
+    type = SOCK_DGRAM;
+
+  s = socket (AF_INET, type, 0);
+  if (s < 0)
+    return (-1);
+
+  addrp->sin_family = AF_INET;
+  addrp->sin_port = htons (IPPORT_TIMESERVER);
+  if (type == SOCK_DGRAM)
+    {
+      res = sendto (s, (char *) &thetime, sizeof (thetime), 0,
+		    (struct sockaddr *) addrp, sizeof (*addrp));
+      if (res < 0)
+	{
+	  do_close (s);
+	  return -1;
+	}
+      do
+	{
+	  FD_ZERO (&readfds);
+	  FD_SET (s, &readfds);
+	  res = select (_rpc_dtablesize (), &readfds, (void *) NULL,
+			(void *) NULL, timeout);
+	}
+      while (res < 0 && errno == EINTR);
+      if (res <= 0)
+	{
+	  if (res == 0)
+	    __set_errno (ETIMEDOUT);
+	  do_close (s);
+	  return (-1);
+	}
+      fromlen = sizeof (from);
+      res = recvfrom (s, (char *) &thetime, sizeof (thetime), 0,
+		      (struct sockaddr *) &from, &fromlen);
+      do_close (s);
+      if (res < 0)
+	return -1;
+    }
+  else
+    {
+      if (connect (s, (struct sockaddr *) addrp, sizeof (*addrp)) < 0)
+	{
+	  do_close (s);
+	  return -1;
+	}
+      res = read (s, (char *) &thetime, sizeof (thetime));
+      do_close (s);
+      if (res < 0)
+	return (-1);
+    }
+  if (res != sizeof (thetime))
+    {
+      __set_errno (EIO);
+      return -1;
+    }
+  thetime = ntohl (thetime);
+  timep->tv_sec = thetime - TOFFSET;
+  timep->tv_usec = 0;
+  return 0;
+}
diff --git a/sysdeps/generic/svc_auth.c b/sunrpc/svc_auth.c
index 9f7ed5eca6..f0aebd5358 100644
--- a/sysdeps/generic/svc_auth.c
+++ b/sunrpc/svc_auth.c
@@ -33,7 +33,6 @@ static char sccsid[] = "@(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro";
 
 /*
  * svc_auth.c, Server-side rpc authenticator interface.
- * *WITHOUT* DES authentication.
  *
  * Copyright (C) 1984, Sun Microsystems, Inc.
  */
@@ -63,6 +62,8 @@ extern enum auth_stat _svcauth_unix (struct svc_req *, struct rpc_msg *);
 				/* unix style (uid, gids) */
 extern enum auth_stat _svcauth_short (struct svc_req *, struct rpc_msg *);
 				/* short hand unix style */
+extern enum auth_stat _svcauth_des (struct svc_req *, struct rpc_msg *);
+				/* des style */
 
 static const struct
   {
@@ -72,9 +73,10 @@ svcauthsw[] =
 {
   { _svcauth_null },		/* AUTH_NULL */
   { _svcauth_unix },		/* AUTH_UNIX */
-  { _svcauth_short }		/* AUTH_SHORT */
+  { _svcauth_short },		/* AUTH_SHORT */
+  { _svcauth_des }		/* AUTH_DES */
 };
-#define	AUTH_MAX	2	/* HIGHEST AUTH NUMBER */
+#define	AUTH_MAX	3	/* HIGHEST AUTH NUMBER */
 
 
 /*
diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c
new file mode 100644
index 0000000000..3547830267
--- /dev/null
+++ b/sunrpc/svcauth_des.c
@@ -0,0 +1,548 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)svcauth_des.c	2.3 89/07/11 4.0 RPCSRC; from 1.15 88/02/08 SMI";
+#endif
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svcauth_des.c, server-side des authentication
+ *
+ * We insure for the service the following:
+ * (1) The timestamp microseconds do not exceed 1 million.
+ * (2) The timestamp plus the window is less than the current time.
+ * (3) The timestamp is not less than the one previously
+ *     seen in the current session.
+ *
+ * It is up to the server to determine if the window size is
+ * too small .
+ *
+ */
+
+#include <string.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+#include <rpc/svc_auth.h>
+#include <rpc/svc.h>
+#include <rpc/des_crypt.h>
+
+#define debug(msg)		/*printf("svcauth_des: %s\n", msg) */
+
+#define USEC_PER_SEC ((u_long) 1000000L)
+#define BEFORE(t1, t2) timercmp(t1, t2, <)
+
+/*
+ * LRU cache of conversation keys and some other useful items.
+ */
+#define AUTHDES_CACHESZ 64
+struct cache_entry
+  {
+    des_block key;		/* conversation key */
+    char *rname;		/* client's name */
+    u_int window;		/* credential lifetime window */
+    struct timeval laststamp;	/* detect replays of creds */
+    char *localcred;		/* generic local credential */
+  };
+static struct cache_entry *authdes_cache /* [AUTHDES_CACHESZ] */ ;
+static short *authdes_lru /* [AUTHDES_CACHESZ] */ ;
+
+static void cache_init (void);	/* initialize the cache */
+static short cache_spot (des_block *, char *, struct timeval *);
+					/* find an entry in the cache */
+static void cache_ref (short sid);	/* note that sid was ref'd */
+
+static void invalidate (char *cred);	/* invalidate entry in cache */
+
+/*
+ * cache statistics
+ */
+struct
+  {
+    u_long ncachehits;		/* times cache hit, and is not replay */
+    u_long ncachereplays;	/* times cache hit, and is replay */
+    u_long ncachemisses;	/* times cache missed */
+  }
+svcauthdes_stats;
+
+/*
+ * Service side authenticator for AUTH_DES
+ */
+enum auth_stat
+_svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg)
+{
+  register long *ixdr;
+  des_block cryptbuf[2];
+  register struct authdes_cred *cred;
+  struct authdes_verf verf;
+  int status;
+  register struct cache_entry *entry;
+  short sid = 0;
+  des_block *sessionkey;
+  des_block ivec;
+  u_int window;
+  struct timeval timestamp;
+  u_long namelen;
+  struct area
+    {
+      struct authdes_cred area_cred;
+      char area_netname[MAXNETNAMELEN + 1];
+    }
+   *area;
+
+  if (authdes_cache == NULL)
+    cache_init ();
+
+  area = (struct area *) rqst->rq_clntcred;
+  cred = (struct authdes_cred *) &area->area_cred;
+
+  /*
+   * Get the credential
+   */
+  ixdr = (long *) msg->rm_call.cb_cred.oa_base;
+  cred->adc_namekind = IXDR_GET_ENUM (ixdr, enum authdes_namekind);
+  switch (cred->adc_namekind)
+    {
+    case ADN_FULLNAME:
+      namelen = IXDR_GET_U_LONG (ixdr);
+      if (namelen > MAXNETNAMELEN)
+	{
+	  return AUTH_BADCRED;
+	}
+      cred->adc_fullname.name = area->area_netname;
+      bcopy ((char *) ixdr, cred->adc_fullname.name,
+	     (u_int) namelen);
+      cred->adc_fullname.name[namelen] = 0;
+      ixdr += (RNDUP (namelen) / BYTES_PER_XDR_UNIT);
+      cred->adc_fullname.key.key.high = (u_long) * ixdr++;
+      cred->adc_fullname.key.key.low = (u_long) * ixdr++;
+      cred->adc_fullname.window = (u_long) * ixdr++;
+      break;
+    case ADN_NICKNAME:
+      cred->adc_nickname = (u_long) * ixdr++;
+      break;
+    default:
+      return AUTH_BADCRED;
+    }
+
+  /*
+   * Get the verifier
+   */
+  ixdr = (long *) msg->rm_call.cb_verf.oa_base;
+  verf.adv_xtimestamp.key.high = (u_long) * ixdr++;
+  verf.adv_xtimestamp.key.low = (u_long) * ixdr++;
+  verf.adv_int_u = (u_long) * ixdr++;
+
+
+  /*
+   * Get the conversation key
+   */
+  if (cred->adc_namekind == ADN_FULLNAME)
+    {
+      sessionkey = &cred->adc_fullname.key;
+      if (key_decryptsession (cred->adc_fullname.name,
+			      sessionkey) < 0)
+	{
+	  debug ("decryptsessionkey");
+	  return AUTH_BADCRED;	/* key not found */
+	}
+    }
+  else
+    {				/* ADN_NICKNAME */
+      sid = (short) cred->adc_nickname;
+      if (sid >= AUTHDES_CACHESZ)
+	{
+	  debug ("bad nickname");
+	  return AUTH_BADCRED;	/* garbled credential */
+	}
+      sessionkey = &authdes_cache[sid].key;
+    }
+
+
+  /*
+   * Decrypt the timestamp
+   */
+  cryptbuf[0] = verf.adv_xtimestamp;
+  if (cred->adc_namekind == ADN_FULLNAME)
+    {
+      cryptbuf[1].key.high = cred->adc_fullname.window;
+      cryptbuf[1].key.low = verf.adv_winverf;
+      ivec.key.high = ivec.key.low = 0;
+      status = cbc_crypt ((char *) sessionkey, (char *) cryptbuf,
+			  2 * sizeof (des_block), DES_DECRYPT | DES_HW,
+			  (char *) &ivec);
+    }
+  else
+    {
+      status = ecb_crypt ((char *) sessionkey, (char *) cryptbuf,
+			  sizeof (des_block), DES_DECRYPT | DES_HW);
+    }
+  if (DES_FAILED (status))
+    {
+      debug ("decryption failure");
+      return AUTH_FAILED;	/* system error */
+    }
+
+  /*
+   * XDR the decrypted timestamp
+   */
+  ixdr = (long *) cryptbuf;
+  timestamp.tv_sec = IXDR_GET_LONG (ixdr);
+  timestamp.tv_usec = IXDR_GET_LONG (ixdr);
+
+  /*
+   * Check for valid credentials and verifiers.
+   * They could be invalid because the key was flushed
+   * out of the cache, and so a new session should begin.
+   * Be sure and send AUTH_REJECTED{CRED, VERF} if this is the case.
+   */
+  {
+    struct timeval current;
+    int nick;
+    u_int winverf;
+
+    if (cred->adc_namekind == ADN_FULLNAME)
+      {
+	window = IXDR_GET_U_LONG (ixdr);
+	winverf = IXDR_GET_U_LONG (ixdr);
+	if (winverf != window - 1)
+	  {
+	    debug ("window verifier mismatch");
+	    return AUTH_BADCRED;	/* garbled credential */
+	  }
+	sid = cache_spot (sessionkey, cred->adc_fullname.name,
+			  &timestamp);
+	if (sid < 0)
+	  {
+	    debug ("replayed credential");
+	    return AUTH_REJECTEDCRED;		/* replay */
+	  }
+	nick = 0;
+      }
+    else
+      {				/* ADN_NICKNAME */
+	window = authdes_cache[sid].window;
+	nick = 1;
+      }
+
+    if ((u_long) timestamp.tv_usec >= USEC_PER_SEC)
+      {
+	debug ("invalid usecs");
+	/* cached out (bad key), or garbled verifier */
+	return nick ? AUTH_REJECTEDVERF : AUTH_BADVERF;
+      }
+    if (nick && BEFORE (&timestamp,
+			&authdes_cache[sid].laststamp))
+      {
+	debug ("timestamp before last seen");
+	return (AUTH_REJECTEDVERF);	/* replay */
+      }
+    gettimeofday (&current, (struct timezone *) NULL);
+    current.tv_sec -= window;	/* allow for expiration */
+    if (!BEFORE (&current, &timestamp))
+      {
+	debug ("timestamp expired");
+	/* replay, or garbled credential */
+	return nick ? AUTH_REJECTEDVERF : AUTH_BADCRED;
+      }
+  }
+
+  /*
+   * Set up the reply verifier
+   */
+  verf.adv_nickname = (u_long) sid;
+
+  /*
+   * xdr the timestamp before encrypting
+   */
+  ixdr = (long *) cryptbuf;
+  IXDR_PUT_LONG (ixdr, timestamp.tv_sec - 1);
+  IXDR_PUT_LONG (ixdr, timestamp.tv_usec);
+
+  /*
+   * encrypt the timestamp
+   */
+  status = ecb_crypt ((char *) sessionkey, (char *) cryptbuf,
+		      sizeof (des_block), DES_ENCRYPT | DES_HW);
+  if (DES_FAILED (status))
+    {
+      debug ("encryption failure");
+      return AUTH_FAILED;	/* system error */
+    }
+  verf.adv_xtimestamp = cryptbuf[0];
+
+  /*
+   * Serialize the reply verifier, and update rqst
+   */
+  ixdr = (long *) msg->rm_call.cb_verf.oa_base;
+  *ixdr++ = (long) verf.adv_xtimestamp.key.high;
+  *ixdr++ = (long) verf.adv_xtimestamp.key.low;
+  *ixdr++ = (long) verf.adv_int_u;
+
+  rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES;
+  rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
+  rqst->rq_xprt->xp_verf.oa_length =
+    (char *) ixdr - msg->rm_call.cb_verf.oa_base;
+
+  /*
+   * We succeeded, commit the data to the cache now and
+   * finish cooking the credential.
+   */
+  entry = &authdes_cache[sid];
+  entry->laststamp = timestamp;
+  cache_ref (sid);
+  if (cred->adc_namekind == ADN_FULLNAME)
+    {
+      cred->adc_fullname.window = window;
+      cred->adc_nickname = (u_long) sid;	/* save nickname */
+      if (entry->rname != NULL)
+	{
+	  mem_free (entry->rname, strlen (entry->rname) + 1);
+	}
+      entry->rname = mem_alloc ((u_int) strlen (cred->adc_fullname.name)
+				+ 1);
+      if (entry->rname != NULL)
+	{
+	  strcpy (entry->rname, cred->adc_fullname.name);
+	}
+      else
+	{
+	  debug ("out of memory");
+	}
+      entry->key = *sessionkey;
+      entry->window = window;
+      invalidate (entry->localcred);	/* mark any cached cred invalid */
+    }
+  else
+    {				/* ADN_NICKNAME */
+      /*
+       * nicknames are cooked into fullnames
+       */
+      cred->adc_namekind = ADN_FULLNAME;
+      cred->adc_fullname.name = entry->rname;
+      cred->adc_fullname.key = entry->key;
+      cred->adc_fullname.window = entry->window;
+    }
+  return AUTH_OK;		/* we made it! */
+}
+
+
+/*
+ * Initialize the cache
+ */
+static void
+cache_init (void)
+{
+  register int i;
+
+  authdes_cache = (struct cache_entry *)
+    mem_alloc (sizeof (struct cache_entry) * AUTHDES_CACHESZ);
+  bzero ((char *) authdes_cache,
+	 sizeof (struct cache_entry) * AUTHDES_CACHESZ);
+
+  authdes_lru = (short *) mem_alloc (sizeof (short) * AUTHDES_CACHESZ);
+  /*
+   * Initialize the lru list
+   */
+  for (i = 0; i < AUTHDES_CACHESZ; i++)
+    {
+      authdes_lru[i] = i;
+    }
+}
+
+
+/*
+ * Find the lru victim
+ */
+static short
+cache_victim (void)
+{
+  return (authdes_lru[AUTHDES_CACHESZ - 1]);
+}
+
+/*
+ * Note that sid was referenced
+ */
+static void
+cache_ref (register short sid)
+{
+  register int i;
+  register short curr;
+  register short prev;
+
+  prev = authdes_lru[0];
+  authdes_lru[0] = sid;
+  for (i = 1; prev != sid; i++)
+    {
+      curr = authdes_lru[i];
+      authdes_lru[i] = prev;
+      prev = curr;
+    }
+}
+
+
+/*
+ * Find a spot in the cache for a credential containing
+ * the items given.  Return -1 if a replay is detected, otherwise
+ * return the spot in the cache.
+ */
+static short
+cache_spot (register des_block * key, char *name, struct timeval *timestamp)
+{
+  register struct cache_entry *cp;
+  register int i;
+  register u_long hi;
+
+  hi = key->key.high;
+  for (cp = authdes_cache, i = 0; i < AUTHDES_CACHESZ; i++, cp++)
+    {
+      if (cp->key.key.high == hi &&
+	  cp->key.key.low == key->key.low &&
+	  cp->rname != NULL &&
+	  bcmp (cp->rname, name, strlen (name) + 1) == 0)
+	{
+	  if (BEFORE (timestamp, &cp->laststamp))
+	    {
+	      svcauthdes_stats.ncachereplays++;
+	      return -1;	/* replay */
+	    }
+	  svcauthdes_stats.ncachehits++;
+	  return i;		/* refresh */
+	}
+    }
+  svcauthdes_stats.ncachemisses++;
+  return cache_victim ();	/* new credential */
+}
+
+
+/*
+ * Local credential handling stuff.
+ * NOTE: bsd unix dependent.
+ * Other operating systems should put something else here.
+ */
+#define UNKNOWN 	-2	/* grouplen, if cached cred is unknown user */
+#define INVALID		-1	/* grouplen, if cache entry is invalid */
+
+struct bsdcred
+{
+  uid_t uid;			/* cached uid */
+  gid_t gid;			/* cached gid */
+  short grouplen;		/* length of cached groups */
+  gid_t groups[NGROUPS];	/* cached groups */
+};
+
+/*
+ * Map a des credential into a unix cred.
+ * We cache the credential here so the application does
+ * not have to make an rpc call every time to interpret
+ * the credential.
+ */
+int
+authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
+		  short *grouplen, gid_t * groups)
+{
+  unsigned sid;
+  register int i;
+  uid_t i_uid;
+  gid_t i_gid;
+  int i_grouplen;
+  struct bsdcred *cred;
+
+  sid = adc->adc_nickname;
+  if (sid >= AUTHDES_CACHESZ)
+    {
+      debug ("invalid nickname");
+      return 0;
+    }
+  cred = (struct bsdcred *) authdes_cache[sid].localcred;
+  if (cred == NULL)
+    {
+      cred = (struct bsdcred *) mem_alloc (sizeof (struct bsdcred));
+      authdes_cache[sid].localcred = (char *) cred;
+      cred->grouplen = INVALID;
+    }
+  if (cred->grouplen == INVALID)
+    {
+      /*
+       * not in cache: lookup
+       */
+      if (!netname2user (adc->adc_fullname.name, &i_uid, &i_gid,
+			 &i_grouplen, groups))
+	{
+	  debug ("unknown netname");
+	  cred->grouplen = UNKNOWN;	/* mark as lookup up, but not found */
+	  return 0;
+	}
+      debug ("missed ucred cache");
+      *uid = cred->uid = i_uid;
+      *gid = cred->gid = i_gid;
+      *grouplen = cred->grouplen = i_grouplen;
+      for (i = i_grouplen - 1; i >= 0; i--)
+	{
+	  cred->groups[i] = groups[i];	/* int to short */
+	}
+      return 1;
+    }
+  else if (cred->grouplen == UNKNOWN)
+    {
+      /*
+       * Already lookup up, but no match found
+       */
+      return 0;
+    }
+
+  /*
+   * cached credentials
+   */
+  *uid = cred->uid;
+  *gid = cred->gid;
+  *grouplen = cred->grouplen;
+  for (i = cred->grouplen - 1; i >= 0; i--)
+    {
+      groups[i] = cred->groups[i];	/* short to int */
+    }
+  return 1;
+}
+
+static void
+invalidate (char *cred)
+{
+  if (cred == NULL)
+    {
+      return;
+    }
+  ((struct bsdcred *) cred)->grouplen = INVALID;
+}
diff --git a/sunrpc/xcrypt.c b/sunrpc/xcrypt.c
new file mode 100644
index 0000000000..97c30d149f
--- /dev/null
+++ b/sunrpc/xcrypt.c
@@ -0,0 +1,180 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1986-1991 by Sun Microsystems Inc.
+ */
+
+#ident	"@(#)xcrypt.c	1.11	94/08/23 SMI"
+
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xcrypt.c 1.3 89/03/24 Copyr 1986 Sun Micro";
+#endif
+
+/*
+ * xcrypt.c: Hex encryption/decryption and utility routines
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <rpc/des_crypt.h>
+
+static char hex[16] =
+{
+  '0', '1', '2', '3', '4', '5', '6', '7',
+  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
+};
+
+static char hexval (char);
+static void hex2bin (int, char *, char *);
+static void bin2hex (int, unsigned char *, char *);
+void passwd2des (char *pw, char *key);
+
+/*
+ * Encrypt a secret key given passwd
+ * The secret key is passed and returned in hex notation.
+ * Its length must be a multiple of 16 hex digits (64 bits).
+ */
+int
+xencrypt (char *secret, char *passwd)
+{
+  char key[8];
+  char ivec[8];
+  char *buf;
+  int err;
+  int len;
+
+  len = strlen (secret) / 2;
+  buf = malloc ((unsigned) len);
+  hex2bin (len, secret, buf);
+  passwd2des (passwd, key);
+  memset (ivec, 0, 8);
+
+  err = cbc_crypt (key, buf, len, DES_ENCRYPT | DES_HW, ivec);
+  if (DES_FAILED (err))
+    {
+      free (buf);
+      return 0;
+    }
+  bin2hex (len, (unsigned char *) buf, secret);
+  free (buf);
+  return 1;
+}
+
+/*
+ * Decrypt secret key using passwd
+ * The secret key is passed and returned in hex notation.
+ * Once again, the length is a multiple of 16 hex digits
+ */
+int
+xdecrypt (char *secret, char *passwd)
+{
+  char key[8];
+  char ivec[8];
+  char *buf;
+  int err;
+  int len;
+
+  len = strlen (secret) / 2;
+  buf = malloc ((unsigned) len);
+
+  hex2bin (len, secret, buf);
+  passwd2des (passwd, key);
+  memset (ivec, 0, 8);
+
+  err = cbc_crypt (key, buf, len, DES_DECRYPT | DES_HW, ivec);
+  if (DES_FAILED (err))
+    {
+      free (buf);
+      return 0;
+    }
+  bin2hex (len, (unsigned char *) buf, secret);
+  free (buf);
+  return 1;
+}
+
+/*
+ * Turn password into DES key
+ */
+void
+passwd2des (char *pw, char *key)
+{
+  int i;
+
+  memset (key, 0, 8);
+  for (i = 0; *pw; i = (i + 1) % 8)
+    key[i] ^= *pw++ << 1;
+
+  des_setparity (key);
+}
+
+/*
+ * Hex to binary conversion
+ */
+static void
+hex2bin (int len, char *hexnum, char *binnum)
+{
+  int i;
+
+  for (i = 0; i < len; i++)
+    *binnum++ = 16 * hexval (hexnum[2 * i]) + hexval (hexnum[2 * i + 1]);
+}
+
+/*
+ * Binary to hex conversion
+ */
+static void
+bin2hex (int len, unsigned char *binnum, char *hexnum)
+{
+  int i;
+  unsigned val;
+
+  for (i = 0; i < len; i++)
+    {
+      val = binnum[i];
+      hexnum[i * 2] = hex[val >> 4];
+      hexnum[i * 2 + 1] = hex[val & 0xf];
+    }
+  hexnum[len * 2] = 0;
+}
+
+static char
+hexval (char c)
+{
+  if (c >= '0' && c <= '9')
+    return (c - '0');
+  else if (c >= 'a' && c <= 'z')
+    return (c - 'a' + 10);
+  else if (c >= 'A' && c <= 'Z')
+    return (c - 'A' + 10);
+  else
+    return -1;
+}
diff --git a/sysdeps/generic/rpc/auth_des.h b/sysdeps/generic/rpc/auth_des.h
deleted file mode 100644
index 8c2f794691..0000000000
--- a/sysdeps/generic/rpc/auth_des.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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.  */
-
-#ifndef _RPC_AUTH_DES_H
-
-#define _RPC_AUTH_DES_H	1
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-/* This is no complete version of this header.  More definitions with
-   the real authentication stuff will come in 1997.  For now we only
-   need to define the function for handling public keys.  */
-
-
-/* Get the public key for NAME and place it in KEY.  NAME can only be
-   up to MAXNETNAMELEN bytes long and the destination buffer KEY should
-   have HEXKEYBATES + 1 bytes long to fit all characters from the key.  */
-extern int getpublickey __P ((__const char *__name, char *__key));
-
-/* Get the secret key for NAME and place it in KEY.  PASSWD is used to
-   decrypt the encrypted key stored in the database.  NAME can only be
-   up to MAXNETNAMELEN bytes long and the destination buffer KEY
-   should have HEXKEYBATES + 1 bytes long to fit all characters from
-   the key.  */
-extern int getsecretkey __P ((__const char *__name, char *__key,
-			      __const char *__passwd));
-
-__END_DECLS
-
-#endif /* rpc/auth_des.h */
diff --git a/sysdeps/mach/hurd/Dist b/sysdeps/mach/hurd/Dist
index e6067b8a73..084c314649 100644
--- a/sysdeps/mach/hurd/Dist
+++ b/sysdeps/mach/hurd/Dist
@@ -1,4 +1,11 @@
-errnos.awk err_hurd.sub
+errnos.awk
+err_hurd.sub
 libc-ldscript
 libc_p-ldscript
 cthreads.c
+net/ethernet.h
+net/if.h
+net/if_arp.h
+net/if_ether.h
+net/if_ppp.h
+net/route.h
diff --git a/sysdeps/mach/hurd/mips/Dist b/sysdeps/mach/hurd/mips/Dist
new file mode 100644
index 0000000000..b6f3ffa4c3
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/Dist
@@ -0,0 +1,3 @@
+longjmp-ctx.c
+init-fault.c
+dl-machine.c
diff --git a/sysdeps/powerpc/Dist b/sysdeps/powerpc/Dist
index 282cf1394e..a3de7b3c96 100644
--- a/sysdeps/powerpc/Dist
+++ b/sysdeps/powerpc/Dist
@@ -1,3 +1,5 @@
 fenv_const.c
 fenv_libc.h
 quad_float.h
+fe_nomask.c
+t_sqrt.c
diff --git a/sysdeps/powerpc/add_n.s b/sysdeps/powerpc/add_n.s
new file mode 100644
index 0000000000..609f0a502a
--- /dev/null
+++ b/sysdeps/powerpc/add_n.s
@@ -0,0 +1,68 @@
+ # Add two limb vectors of equal, non-zero length for PowerPC.
+ # Copyright (C) 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+ # mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ #                      mp_size_t size)
+ # Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.
+
+ # Note on optimisation: This code is optimal for the 601.  Almost every other
+ # possible 2-unrolled inner loop will not be.  Also, watch out for the
+ # alignment...
+
+	.align 3
+	.globl __mpn_add_n
+	.type	 __mpn_add_n,@function
+__mpn_add_n:
+ # Set up for loop below.
+	mtcrf 0x01,%r6
+	srwi. %r7,%r6,1
+	li    %r10,0
+	mtctr %r7
+	bt    31,2f
+
+ # Clear the carry.
+	addic %r0,%r0,0
+ # Adjust pointers for loop.
+	addi  %r3,%r3,-4
+	addi  %r4,%r4,-4
+	addi  %r5,%r5,-4
+	b     0f
+
+2:	lwz  %r7,0(%r5)
+	lwz  %r6,0(%r4)
+	addc %r6,%r6,%r7
+	stw  %r6,0(%r3)
+        beq  1f
+
+ # The loop.
+
+ # Align start of loop to an odd word boundary to guarantee that the
+ # last two words can be fetched in one access (for 601).
+0:	lwz  %r9,4(%r4)
+	lwz  %r8,4(%r5)
+	lwzu %r6,8(%r4)
+	lwzu %r7,8(%r5)
+	adde %r8,%r9,%r8
+	stw  %r8,4(%r3)
+	adde %r6,%r6,%r7
+	stwu %r6,8(%r3)
+	bdnz 0b
+ # return the carry
+1:	addze %r3,%r10
+	blr
diff --git a/sysdeps/powerpc/addmul_1.s b/sysdeps/powerpc/addmul_1.s
new file mode 100644
index 0000000000..cf8fd2a555
--- /dev/null
+++ b/sysdeps/powerpc/addmul_1.s
@@ -0,0 +1,50 @@
+ # Multiply a limb vector by a single limb, for PowerPC.
+ # Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+ # mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ #                         mp_size_t s1_size, mp_limb_t s2_limb)
+ # Calculate res+s1*s2 and put result back in res; return carry.
+
+	.align 2
+	.globl __mpn_addmul_1
+	.type	 __mpn_addmul_1,@function
+__mpn_addmul_1:
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,0(%r3)
+	addc	%r8,%r7,%r9
+	addi	%r3,%r3,-4		# adjust res_ptr
+	bdz	Lend
+
+Loop:	lwzu	%r0,4(%r4)
+	stwu	%r8,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,4(%r3)
+	addze   %r10,%r10
+	addc    %r8,%r7,%r9
+	bdnz	Loop
+
+Lend:	stw	%r8,4(%r3)
+	addze	%r3,%r10
+	blr
diff --git a/sysdeps/powerpc/lshift.s b/sysdeps/powerpc/lshift.s
new file mode 100644
index 0000000000..9612a3dbec
--- /dev/null
+++ b/sysdeps/powerpc/lshift.s
@@ -0,0 +1,479 @@
+ # Shift a limb left, low level routine.
+ # Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+ # mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+ #			 unsigned int cnt)
+
+	.align 3
+	.globl __mpn_lshift
+	.type	 __mpn_lshift,@function
+__mpn_lshift:
+	mtctr	%r5		# copy size into CTR
+	cmplwi	%cr0,%r5,16	# is size < 16
+	slwi	%r0,%r5,2
+	add	%r7,%r3,%r0	# make r7 point at end of res
+	add	%r4,%r4,%r0	# make r4 point at end of s1
+	lwzu	%r11,-4(%r4)	# load first s1 limb
+	subfic	%r8,%r6,32
+	srw	%r3,%r11,%r8	# compute function return value
+	bge	%cr0,Lbig	# branch if size >= 16
+
+	bdz	Lend1
+
+Loop:	lwzu	%r10,-4(%r4)
+	slw	%r9,%r11,%r6
+	srw	%r12,%r10,%r8
+	or	%r9,%r9,%r12
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slw	%r9,%r10,%r6
+	srw	%r12,%r11,%r8
+	or	%r9,%r9,%r12
+	stwu	%r9,-4(%r7)
+	bdnz	Loop
+	b	Lend1
+
+ # Guaranteed not to succeed.
+LBoom:	tweq    %r0,%r0
+
+ # We imitate a case statement, by using (yuk!) fixed-length code chunks,
+ # of size 4*12 bytes.  We have to do this (or something) to make this PIC.
+Lbig:	mflr    %r9
+	bltl    %cr0,LBoom      # Never taken, only used to set LR.
+	slwi    %r10,%r6,4
+	mflr    %r12
+	add     %r10,%r12,%r10
+	slwi	%r8,%r6,5
+	add     %r10,%r8,%r10
+	mtctr   %r10
+	addi	%r5,%r5,-1
+	mtlr    %r9
+	bctr
+
+Lend1:	slw	%r0,%r11,%r6
+	stw	%r0,-4(%r7)
+	blr
+
+	mtctr	%r5
+Loop1:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,1
+	inslwi	%r9,%r10,1,31
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,1
+	inslwi	%r9,%r11,1,31
+	stwu	%r9,-4(%r7)
+	bdnz	Loop1
+	b	Lend1
+
+	mtctr	%r5
+Loop2:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,2
+	inslwi	%r9,%r10,2,30
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,2
+	inslwi	%r9,%r11,2,30
+	stwu	%r9,-4(%r7)
+	bdnz	Loop2
+	b	Lend1
+
+	mtctr	%r5
+Loop3:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,3
+	inslwi	%r9,%r10,3,29
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,3
+	inslwi	%r9,%r11,3,29
+	stwu	%r9,-4(%r7)
+	bdnz	Loop3
+	b	Lend1
+
+	mtctr	%r5
+Loop4:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,4
+	inslwi	%r9,%r10,4,28
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,4
+	inslwi	%r9,%r11,4,28
+	stwu	%r9,-4(%r7)
+	bdnz	Loop4
+	b	Lend1
+
+	mtctr	%r5
+Loop5:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,5
+	inslwi	%r9,%r10,5,27
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,5
+	inslwi	%r9,%r11,5,27
+	stwu	%r9,-4(%r7)
+	bdnz	Loop5
+	b	Lend1
+
+	mtctr	%r5
+Loop6:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,6
+	inslwi	%r9,%r10,6,26
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,6
+	inslwi	%r9,%r11,6,26
+	stwu	%r9,-4(%r7)
+	bdnz	Loop6
+	b	Lend1
+
+	mtctr	%r5
+Loop7:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,7
+	inslwi	%r9,%r10,7,25
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,7
+	inslwi	%r9,%r11,7,25
+	stwu	%r9,-4(%r7)
+	bdnz	Loop7
+	b	Lend1
+
+	mtctr	%r5
+Loop8:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,8
+	inslwi	%r9,%r10,8,24
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,8
+	inslwi	%r9,%r11,8,24
+	stwu	%r9,-4(%r7)
+	bdnz	Loop8
+	b	Lend1
+
+	mtctr	%r5
+Loop9:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,9
+	inslwi	%r9,%r10,9,23
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,9
+	inslwi	%r9,%r11,9,23
+	stwu	%r9,-4(%r7)
+	bdnz	Loop9
+	b	Lend1
+
+	mtctr	%r5
+Loop10:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,10
+	inslwi	%r9,%r10,10,22
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,10
+	inslwi	%r9,%r11,10,22
+	stwu	%r9,-4(%r7)
+	bdnz	Loop10
+	b	Lend1
+
+	mtctr	%r5
+Loop11:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,11
+	inslwi	%r9,%r10,11,21
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,11
+	inslwi	%r9,%r11,11,21
+	stwu	%r9,-4(%r7)
+	bdnz	Loop11
+	b	Lend1
+
+	mtctr	%r5
+Loop12:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,12
+	inslwi	%r9,%r10,12,20
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,12
+	inslwi	%r9,%r11,12,20
+	stwu	%r9,-4(%r7)
+	bdnz	Loop12
+	b	Lend1
+
+	mtctr	%r5
+Loop13:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,13
+	inslwi	%r9,%r10,13,19
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,13
+	inslwi	%r9,%r11,13,19
+	stwu	%r9,-4(%r7)
+	bdnz	Loop13
+	b	Lend1
+
+	mtctr	%r5
+Loop14:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,14
+	inslwi	%r9,%r10,14,18
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,14
+	inslwi	%r9,%r11,14,18
+	stwu	%r9,-4(%r7)
+	bdnz	Loop14
+	b	Lend1
+
+	mtctr	%r5
+Loop15:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,15
+	inslwi	%r9,%r10,15,17
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,15
+	inslwi	%r9,%r11,15,17
+	stwu	%r9,-4(%r7)
+	bdnz	Loop15
+	b	Lend1
+
+	mtctr	%r5
+Loop16:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,16
+	inslwi	%r9,%r10,16,16
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,16
+	inslwi	%r9,%r11,16,16
+	stwu	%r9,-4(%r7)
+	bdnz	Loop16
+	b	Lend1
+
+	mtctr	%r5
+Loop17:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,17
+	inslwi	%r9,%r10,17,15
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,17
+	inslwi	%r9,%r11,17,15
+	stwu	%r9,-4(%r7)
+	bdnz	Loop17
+	b	Lend1
+
+	mtctr	%r5
+Loop18:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,18
+	inslwi	%r9,%r10,18,14
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,18
+	inslwi	%r9,%r11,18,14
+	stwu	%r9,-4(%r7)
+	bdnz	Loop18
+	b	Lend1
+
+	mtctr	%r5
+Loop19:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,19
+	inslwi	%r9,%r10,19,13
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,19
+	inslwi	%r9,%r11,19,13
+	stwu	%r9,-4(%r7)
+	bdnz	Loop19
+	b	Lend1
+
+	mtctr	%r5
+Loop20:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,20
+	inslwi	%r9,%r10,20,12
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,20
+	inslwi	%r9,%r11,20,12
+	stwu	%r9,-4(%r7)
+	bdnz	Loop20
+	b	Lend1
+
+	mtctr	%r5
+Loop21:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,21
+	inslwi	%r9,%r10,21,11
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,21
+	inslwi	%r9,%r11,21,11
+	stwu	%r9,-4(%r7)
+	bdnz	Loop21
+	b	Lend1
+
+	mtctr	%r5
+Loop22:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,22
+	inslwi	%r9,%r10,22,10
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,22
+	inslwi	%r9,%r11,22,10
+	stwu	%r9,-4(%r7)
+	bdnz	Loop22
+	b	Lend1
+
+	mtctr	%r5
+Loop23:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,23
+	inslwi	%r9,%r10,23,9
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,23
+	inslwi	%r9,%r11,23,9
+	stwu	%r9,-4(%r7)
+	bdnz	Loop23
+	b	Lend1
+
+	mtctr	%r5
+Loop24:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,24
+	inslwi	%r9,%r10,24,8
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,24
+	inslwi	%r9,%r11,24,8
+	stwu	%r9,-4(%r7)
+	bdnz	Loop24
+	b	Lend1
+
+	mtctr	%r5
+Loop25:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,25
+	inslwi	%r9,%r10,25,7
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,25
+	inslwi	%r9,%r11,25,7
+	stwu	%r9,-4(%r7)
+	bdnz	Loop25
+	b	Lend1
+
+	mtctr	%r5
+Loop26:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,26
+	inslwi	%r9,%r10,26,6
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,26
+	inslwi	%r9,%r11,26,6
+	stwu	%r9,-4(%r7)
+	bdnz	Loop26
+	b	Lend1
+
+	mtctr	%r5
+Loop27:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,27
+	inslwi	%r9,%r10,27,5
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,27
+	inslwi	%r9,%r11,27,5
+	stwu	%r9,-4(%r7)
+	bdnz	Loop27
+	b	Lend1
+
+	mtctr	%r5
+Loop28:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,28
+	inslwi	%r9,%r10,28,4
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,28
+	inslwi	%r9,%r11,28,4
+	stwu	%r9,-4(%r7)
+	bdnz	Loop28
+	b	Lend1
+
+	mtctr	%r5
+Loop29:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,29
+	inslwi	%r9,%r10,29,3
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,29
+	inslwi	%r9,%r11,29,3
+	stwu	%r9,-4(%r7)
+	bdnz	Loop29
+	b	Lend1
+
+	mtctr	%r5
+Loop30:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,30
+	inslwi	%r9,%r10,30,2
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,30
+	inslwi	%r9,%r11,30,2
+	stwu	%r9,-4(%r7)
+	bdnz	Loop30
+	b	Lend1
+
+	mtctr	%r5
+Loop31:	lwzu	%r10,-4(%r4)
+	slwi	%r9,%r11,31
+	inslwi	%r9,%r10,31,1
+	stwu	%r9,-4(%r7)
+	bdz	Lend2
+	lwzu	%r11,-4(%r4)
+	slwi	%r9,%r10,31
+	inslwi	%r9,%r11,31,1
+	stwu	%r9,-4(%r7)
+	bdnz	Loop31
+	b	Lend1
+
+Lend2:	slw	%r0,%r10,%r6
+	stw	%r0,-4(%r7)
+	blr
diff --git a/sysdeps/powerpc/memset.s b/sysdeps/powerpc/memset.s
new file mode 100644
index 0000000000..4c8bf8c6b4
--- /dev/null
+++ b/sysdeps/powerpc/memset.s
@@ -0,0 +1,202 @@
+ # Optimized memset implementation for PowerPC.
+ # Copyright (C) 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+	.section ".text"
+	.align 5
+	nop
+	
+	.globl memset
+	.type memset,@function
+memset:	
+ # __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
+ # Returns 's'.
+
+ # The memset is done in three sizes: byte (8 bits), word (32 bits),
+ # cache line (256 bits). There is a special case for setting cache lines
+ # to 0, to take advantage of the dcbz instruction.
+ # r6:	current address we are storing at
+ # r7:	number of bytes we are setting now (when aligning)
+
+ # take care of case for size <= 4
+	cmplwi %cr1,%r5,4	
+	andi.  %r7,%r3,3
+	mr     %r6,%r3
+	ble-   %cr1,small
+ # align to word boundary
+	cmplwi %cr5,%r5,31
+	rlwimi %r4,%r4,8,16,23
+	beq+   aligned			# 8th instruction from .align
+	mtcrf  0x01,%r3
+	subfic %r7,%r7,4
+	add    %r6,%r6,%r7
+	sub    %r5,%r5,%r7
+	bf+    31,0f
+	stb    %r4,0(%r3)
+	bt     30,aligned
+0:	sth    %r4,-2(%r6)		#  16th instruction from .align
+ # take care of case for size < 31
+aligned:
+	mtcrf  0x01,%r5
+	rlwimi %r4,%r4,16,0,15
+	ble    %cr5,medium
+ # align to cache line boundary...
+	andi.  %r7,%r6,0x1C
+	subfic %r7,%r7,0x20
+	beq    caligned
+	mtcrf  0x01,%r7
+	add    %r6,%r6,%r7
+	sub    %r5,%r5,%r7
+	cmplwi %cr1,%r7,0x10
+	mr     %r8,%r6
+	bf     28,1f
+	stw    %r4,-4(%r8)
+	stwu   %r4,-8(%r8)
+1:	blt    %cr1,2f
+	stw    %r4,-4(%r8)	# 32nd instruction from .align
+	stw    %r4,-8(%r8)
+	stw    %r4,-12(%r8)
+	stwu   %r4,-16(%r8)
+2:	bf     29,caligned
+	stw    %r4,-4(%r8)
+ # now aligned to a cache line.
+caligned:
+	cmplwi %cr1,%r4,0
+	clrrwi. %r7,%r5,5
+	mtcrf  0x01,%r5		# 40th instruction from .align
+	beq    %cr1,zloopstart	# special case for clearing memory using dcbz
+	srwi   %r0,%r7,5
+	mtctr  %r0
+	beq    medium		# we may not actually get to do a full line
+	clrlwi. %r5,%r5,27
+	add    %r6,%r6,%r7
+0:	li     %r8,-0x40
+	bdz    cloopdone	# 48th instruction from .align
+	
+cloop:	dcbz   %r8,%r6
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stw    %r4,-16(%r6)
+	nop			# let 601 fetch last 4 instructions of loop
+	stw    %r4,-20(%r6)
+	stw    %r4,-24(%r6)	# 56th instruction from .align
+	nop			# let 601 fetch first 8 instructions of loop
+	stw    %r4,-28(%r6)
+	stwu   %r4,-32(%r6)
+	bdnz   cloop
+cloopdone:
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stw    %r4,-16(%r6)	# 64th instruction from .align
+	stw    %r4,-20(%r6)
+	cmplwi %cr1,%r5,16
+	stw    %r4,-24(%r6)
+	stw    %r4,-28(%r6)
+	stwu   %r4,-32(%r6)
+	beqlr
+	add    %r6,%r6,%r7
+	b      medium_tail2	# 72nd instruction from .align
+
+	.align 5
+	nop
+# clear lines of memory in 128-byte chunks.
+zloopstart:
+	clrlwi %r5,%r5,27
+	mtcrf  0x02,%r7
+	srwi.  %r0,%r7,7
+	mtctr  %r0
+	li     %r7,0x20
+	li     %r8,-0x40
+	cmplwi %cr1,%r5,16	# 8
+	bf     26,0f	
+	dcbz   0,%r6
+	addi   %r6,%r6,0x20
+0:	li     %r9,-0x20
+	bf     25,1f
+	dcbz   0,%r6
+	dcbz   %r7,%r6
+	addi   %r6,%r6,0x40	# 16
+1:	cmplwi %cr5,%r5,0
+	beq    medium
+zloop:	
+	dcbz   0,%r6
+	dcbz   %r7,%r6
+	addi   %r6,%r6,0x80
+	dcbz   %r8,%r6
+	dcbz   %r9,%r6
+	bdnz   zloop
+	beqlr  %cr5
+	b      medium_tail2
+	
+	.align 5	
+small:
+ # Memset of 4 bytes or less.
+	cmplwi %cr5,%r5,1
+	cmplwi %cr1,%r5,3
+	bltlr  %cr5
+	stb    %r4,0(%r6)
+	beqlr  %cr5
+	nop
+	stb    %r4,1(%r6)
+	bltlr  %cr1
+	stb    %r4,2(%r6)
+	beqlr  %cr1
+	nop
+	stb    %r4,3(%r6)
+	blr
+
+# memset of 0-31 bytes
+	.align 5
+medium:
+	cmplwi %cr1,%r5,16
+medium_tail2:
+	add    %r6,%r6,%r5
+medium_tail:
+	bt-    31,medium_31t
+	bt-    30,medium_30t
+medium_30f:
+	bt-    29,medium_29t
+medium_29f:
+	bge-   %cr1,medium_27t
+	bflr-  28
+	stw    %r4,-4(%r6)	# 8th instruction from .align
+	stw    %r4,-8(%r6)
+	blr
+
+medium_31t:	
+	stbu   %r4,-1(%r6)
+	bf-    30,medium_30f
+medium_30t:
+	sthu   %r4,-2(%r6)
+	bf-    29,medium_29f
+medium_29t:
+	stwu   %r4,-4(%r6)
+	blt-   %cr1,medium_27f	# 16th instruction from .align
+medium_27t:
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stwu   %r4,-16(%r6)
+medium_27f:
+	bflr-  28
+medium_28t:
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	blr
diff --git a/sysdeps/powerpc/mul_1.s b/sysdeps/powerpc/mul_1.s
new file mode 100644
index 0000000000..d6eb623bd4
--- /dev/null
+++ b/sysdeps/powerpc/mul_1.s
@@ -0,0 +1,47 @@
+ # Multiply a limb vector by a limb, for PowerPC.
+ # Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+ # mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ #                      mp_size_t s1_size, mp_limb_t s2_limb)
+ # Calculate s1*s2 and put result in res_ptr; return carry.
+
+	.align 2
+	.globl __mpn_mul_1
+	.type	 __mpn_mul_1,@function
+
+__mpn_mul_1:
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	addi	%r3,%r3,-4		# adjust res_ptr
+	addic	%r5,%r5,0		# clear cy with dummy insn
+	bdz	Lend
+
+Loop:	lwzu	%r0,4(%r4)
+	stwu	%r7,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	bdnz	Loop
+
+Lend:	stw	%r7,4(%r3)
+	addze	%r3,%r10
+	blr
diff --git a/sysdeps/powerpc/rshift.s b/sysdeps/powerpc/rshift.s
new file mode 100644
index 0000000000..20f09ad86a
--- /dev/null
+++ b/sysdeps/powerpc/rshift.s
@@ -0,0 +1,59 @@
+# PowerPC-32 __mpn_rshift --
+
+# Copyright (C) 1995 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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 MP 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.
+
+
+# INPUT PARAMETERS
+# res_ptr	r3
+# s1_ptr	r4
+# size		r5
+# cnt		r6
+
+	.align 3
+	.globl __mpn_rshift
+	.type	 __mpn_rshift,@function
+__mpn_rshift:
+	mtctr	5		# copy size into CTR
+	addi	7,3,-4		# move adjusted res_ptr to free return reg
+	subfic	8,6,32
+	lwz	11,0(4)		# load first s1 limb
+	slw	3,11,8		# compute function return value
+	bdz	Lend1
+
+Loop:	lwzu	10,4(4)
+	srw	9,11,6
+	slw	12,10,8
+	or	9,9,12
+	stwu	9,4(7)
+	bdz	Lend2
+	lwzu	11,4(4)
+	srw	9,10,6
+	slw	12,11,8
+	or	9,9,12
+	stwu	9,4(7)
+	bdnz	Loop
+
+Lend1:	srw	0,11,6
+	stw	0,4(7)
+	blr
+
+Lend2:	srw	0,10,6
+	stw	0,4(7)
+	blr
diff --git a/sysdeps/powerpc/strchr.s b/sysdeps/powerpc/strchr.s
new file mode 100644
index 0000000000..c1df66f8dc
--- /dev/null
+++ b/sysdeps/powerpc/strchr.s
@@ -0,0 +1,118 @@
+ # Optimized strchr implementation for PowerPC.
+ # Copyright (C) 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+ # See strlen.s for comments on how this works.
+
+	.section ".text"
+	.align 2
+	.globl strchr
+	.type strchr,@function
+strchr:
+ # char * [r3] strchr (const char *s [r3] , int c [r4] )
+
+ # r0:	a temporary
+ # r3:	our return result.
+ # r4:	byte we're looking for, spread over the whole word
+ # r5:	the current word
+ # r6:	the constant 0xfefefeff (-0x01010101)
+ # r7:	the constant 0x7f7f7f7f
+ # r8:	pointer to the current word.
+ # r9:	a temporary
+ # r10:	the number of bits we should ignore in the first word
+ # r11:	a mask with the bits to ignore set to 0
+ # r12:	a temporary
+	
+	rlwimi %r4,%r4,8,16,23
+	li   %r11,-1
+	rlwimi %r4,%r4,16,0,15
+	lis  %r6,0xfeff
+	lis  %r7,0x7f7f
+	clrrwi %r8,%r3,2
+	addi %r7,%r7,0x7f7f
+	addi %r6,%r6,0xfffffeff
+	rlwinm %r10,%r3,3,27,28
+ # Test the first (partial?) word.
+	lwz  %r5,0(%r8)
+	srw  %r11,%r11,%r10
+	orc  %r5,%r5,%r11
+	add  %r0,%r6,%r5
+	nor  %r9,%r7,%r5
+	and. %r0,%r0,%r9
+	xor  %r12,%r4,%r5
+	orc  %r12,%r12,%r11
+	b    loopentry
+	
+ # The loop.
+
+loop:	lwzu %r5,4(%r8)
+	and. %r0,%r0,%r9
+ # Test for 0
+	add  %r0,%r6,%r5
+	nor  %r9,%r7,%r5
+	bne  foundit
+	and. %r0,%r0,%r9
+ # Start test for the bytes we're looking for
+	xor  %r12,%r4,%r5
+loopentry:
+	add  %r0,%r6,%r12
+	nor  %r9,%r7,%r12
+	beq  loop
+ # There is a zero byte in the word, but may also be a matching byte (either
+ # before or after the zero byte). In fact, we may be looking for a
+ # zero byte, in which case we return a match. We guess that this hasn't
+ # happened, though.
+missed:	
+	and. %r0,%r0,%r9
+	li   %r3,0
+	beqlr
+ # It did happen. Decide which one was first...
+ # I'm not sure if this is actually faster than a sequence of
+ # rotates, compares, and branches (we use it anyway because it's shorter).
+	and  %r6,%r7,%r5
+	or   %r11,%r7,%r5
+	and  %r0,%r7,%r12
+	or   %r10,%r7,%r12
+	add  %r6,%r6,%r7
+	add  %r0,%r0,%r7
+	nor  %r5,%r11,%r6
+	nor  %r9,%r10,%r0
+	cmplw %r5,%r9
+	bgtlr
+	cntlzw %r4,%r9
+	srwi %r4,%r4,3
+	add  %r3,%r8,%r4
+	blr
+
+foundit:
+	and  %r0,%r7,%r12
+	or   %r10,%r7,%r12
+	add  %r0,%r0,%r7
+	nor  %r9,%r10,%r0
+	cntlzw %r4,%r9
+	subi %r8,%r8,4
+	srwi %r4,%r4,3
+	add  %r3,%r8,%r4
+	blr
+
+0:
+	.size	 strchr,0b-strchr
+
+	.globl index
+	.weak index
+	.set index,strchr
diff --git a/sysdeps/powerpc/strcmp.s b/sysdeps/powerpc/strcmp.s
new file mode 100644
index 0000000000..f901b82ab1
--- /dev/null
+++ b/sysdeps/powerpc/strcmp.s
@@ -0,0 +1,273 @@
+ # Optimized strcmp implementation for PowerPC.
+ # Copyright (C) 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+ # See strlen.s for comments on how the end-of-string testing works.
+
+	.section ".text"
+	.align 3
+	.globl strcmp
+	.type strcmp,@function
+strcmp:
+ # int [r3] strcmp (const char *p1 [r3], const char *p2 [r4])
+
+ # General register assignments:
+ # r0:	temporary
+ # r3:	pointer to previous word in s1
+ # r4:	pointer to previous word in s2
+ # r5:	current first word in s1
+ # r6:	current first word in s2 (after re-alignment)
+ # r7:	0xfefefeff
+ # r8:	0x7f7f7f7f
+ # r9:	~(word in s1 | 0x7f7f7f7f)
+	
+ # Register assignments in the prologue:
+ # r10:	low 2 bits of p2-p1
+ # r11:	mask to orc with r5/r6
+	
+	subf. %r10,%r4,%r3
+	beq-  equal
+	andi. %r10,%r10,3
+	cmpi  %cr1,%r10,2
+	beq-  %cr1,align2
+	lis   %r7,0xfeff
+	lis   %r8,0x7f7f
+	addi  %r8,%r8,0x7f7f
+	addi  %r7,%r7,0xfffffeff
+	bgt-  %cr1,align3
+strcmp3:
+	rlwinm %r0,%r3,3,27,28
+	li    %r11,-1
+	srw   %r11,%r11,%r0
+	clrrwi %r3,%r3,2
+	clrrwi %r4,%r4,2
+	lwz   %r5,0(%r3)
+	lwz   %r6,0(%r4)
+	bne-  align1
+
+ # The loop, case when both strings are aligned the same.
+ # on entry, cr1.eq must be 1.
+ # r10:	second word in s1
+ # r11:	second word in s2 OR mask to orc with first two words.
+align0:	
+	andi. %r0,%r3,4
+	orc   %r5,%r5,%r11
+	orc   %r6,%r6,%r11
+	beq+  a0start
+	add   %r0,%r7,%r5
+	nor   %r9,%r8,%r5
+	and.  %r0,%r0,%r9
+	cmplw %cr1,%r5,%r6
+	subi  %r3,%r3,4
+	bne-  endstringeq
+	subi  %r4,%r4,4
+	bne-  %cr1,difference
+
+loopalign0:
+	lwzu  %r5,8(%r3)
+	bne-  %cr1,difference2
+	lwzu  %r6,8(%r4)
+a0start:
+	add   %r0,%r7,%r5
+	nor   %r9,%r8,%r5
+	and.  %r0,%r0,%r9
+	cmplw %cr1,%r5,%r6
+	lwz   %r10,4(%r3)
+	bne-  endstringeq
+	add   %r0,%r7,%r10
+	bne-  %cr1,difference
+	nor   %r9,%r8,%r10
+	lwz   %r11,4(%r4)
+	and.  %r0,%r0,%r9
+	cmplw %cr1,%r10,%r11
+	beq+  loopalign0
+
+	mr    %r5,%r10
+	mr    %r6,%r11
+
+ # fall through to...
+
+endstringeq:
+ # (like 'endstring', but an equality code is in cr1)
+	beq  %cr1,equal
+endstring:
+ # OK. We've hit the end of the string. We need to be careful that
+ # we don't compare two strings as different because of gunk beyond
+ # the end of the strings. We do it like this...
+	and  %r0,%r8,%r5
+	add  %r0,%r0,%r8
+	xor. %r10,%r5,%r6
+	andc %r9,%r9,%r0
+	cntlzw %r10,%r10
+	cntlzw %r9,%r9
+	addi %r9,%r9,7
+	cmpw %cr1,%r9,%r10
+	blt  %cr1,equal
+	sub  %r3,%r5,%r6
+	bgelr+
+	mr   %r3,%r6
+	blr
+equal:	li   %r3,0
+	blr
+	
+ # The loop, case when s2 is aligned 1 char behind s1.
+ # r10:	current word in s2 (before re-alignment)
+
+align1:
+	cmpwi %cr1,%r0,0
+	orc   %r5,%r5,%r11
+	bne   %cr1,align1_123
+ # When s1 is aligned to a word boundary, the startup processing is special.
+	slwi. %r6,%r6,24
+	bne+  a1entry_0
+	nor   %r9,%r8,%r5
+	b     endstring
+
+align1_123:
+ # Otherwise (s1 not aligned to a word boundary):
+	mr    %r10,%r6
+	add   %r0,%r7,%r5
+	nor   %r9,%r8,%r5
+	and.  %r0,%r0,%r9
+	srwi  %r6,%r6,8
+	orc   %r6,%r6,%r11
+	cmplw %cr1,%r5,%r6
+	bne-  endstringeq
+	bne-  %cr1,difference
+
+loopalign1:
+	slwi. %r6,%r10,24
+	bne-  %cr1,a1difference
+	lwzu  %r5,4(%r3)
+	beq-  endstring1
+a1entry_0:
+	lwzu  %r10,4(%r4)
+a1entry_123:	
+	add   %r0,%r7,%r5
+	nor   %r9,%r8,%r5
+	and.  %r0,%r0,%r9
+	rlwimi %r6,%r10,24,8,31
+	cmplw %cr1,%r5,%r6
+	beq+  loopalign1
+	b     endstringeq
+
+endstring1:
+	srwi  %r3,%r5,24
+	blr
+
+a1difference:
+	lbz   %r6,-1(%r4)
+	slwi  %r6,%r6,24
+	rlwimi %r6,%r10,24,8,31
+
+ # fall through to...
+		
+difference:	
+ # The idea here is that we could just return '%r5 - %r6', except
+ # that the result might overflow. Overflow can only happen when %r5
+ # and %r6 have different signs (thus the xor), in which case we want to
+ # return negative iff %r6 has its high bit set so %r5 < %r6.
+ # A branch-free implementation of this is
+ #	xor  %r0,%r5,%r6
+ #	rlwinm %r0,%r0,1,31,31
+ #	rlwnm %r5,%r5,%r0,1,31
+ #	rlwnm %r6,%r6,%r0,1,31
+ #	sub  %r3,%r5,%r6
+ #	blr
+ # but this is usually more expensive.
+	xor. %r0,%r5,%r6
+	sub  %r3,%r5,%r6
+	bgelr+
+	mr   %r3,%r6
+	blr
+
+difference2:
+ # As for 'difference', but use registers r10 and r11 instead of r5 and r6.
+	xor. %r0,%r10,%r11
+	sub  %r3,%r10,%r11
+	bgelr+
+	mr   %r3,%r11
+	blr
+	
+ # For the case when s2 is aligned 3 chars behind s1, we switch
+ # s1 and s2...
+ # r10:	used by 'align2' (see below)
+ # r11:	used by 'align2' (see below)
+ # r12:	saved link register
+ # cr0.eq: must be left as 1.
+
+align3:	mflr %r12
+	mr   %r0,%r3
+	mr   %r3,%r4
+	mr   %r4,%r0
+	bl   strcmp3
+	mtlr %r12
+	neg  %r3,%r3
+	blr
+	
+ # The loop, case when s2 and s1's alignments differ by 2
+ # This is the ugly case...
+ # FIXME: on a 601, the loop takes 7 cycles instead of the 6 you'd expect,
+ # because there are too many branches. This loop should probably be
+ # coded like the align1 case.
+	
+a2even:	lhz   %r5,0(%r3)
+	lhz   %r6,0(%r4)
+	b     a2entry
+	
+align2:
+	andi. %r0,%r3,1
+	beq+  a2even
+	subi  %r3,%r3,1
+	subi  %r4,%r4,1
+	lbz   %r5,1(%r3)
+	lbz   %r6,1(%r4)
+	cmpwi %cr0,%r5,0
+	cmpw  %cr1,%r5,%r6
+	beq-  align2end2
+	lhzu  %r5,2(%r3)
+	beq+  %cr1,a2entry1
+	lbz   %r5,-1(%r3)
+	sub   %r3,%r5,%r6
+	blr
+
+loopalign2:
+	cmpw  %cr1,%r5,%r6
+	beq-  align2end2
+	lhzu  %r5,2(%r3)
+	bne-  %cr1,align2different
+a2entry1:
+	lhzu  %r6,2(%r4)
+a2entry:	
+	cmpwi %cr5,%r5,0x00ff
+	andi. %r0,%r5,0x00ff
+	bgt+  %cr5,loopalign2
+
+align2end:
+	andi. %r3,%r6,0xff00
+	neg   %r3,%r3
+	blr
+
+align2different:
+	lhzu  %r5,-2(%r3)
+align2end2:
+	sub   %r3,%r5,%r6
+	blr
+		
+0:
+	.size	 strcmp,0b-strcmp
diff --git a/sysdeps/powerpc/sub_n.s b/sysdeps/powerpc/sub_n.s
new file mode 100644
index 0000000000..8711bf9a40
--- /dev/null
+++ b/sysdeps/powerpc/sub_n.s
@@ -0,0 +1,69 @@
+ # Subtract two limb vectors of equal, non-zero length for PowerPC.
+ # Copyright (C) 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+ # mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ #                      mp_size_t size)
+ # Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1.
+
+ # Note on optimisation: This code is optimal for the 601.  Almost every other
+ # possible 2-unrolled inner loop will not be.  Also, watch out for the
+ # alignment...
+
+	.align 3
+	.globl __mpn_sub_n
+	.type	 __mpn_sub_n,@function
+	nop
+__mpn_sub_n:
+ # Set up for loop below.
+	mtcrf 0x01,%r6
+	srwi. %r7,%r6,1
+	mtctr %r7
+	bt    31,2f
+
+ # Set the carry (clear the borrow).
+	subfc %r0,%r0,%r0
+ # Adjust pointers for loop.
+	addi  %r3,%r3,-4
+	addi  %r4,%r4,-4
+	addi  %r5,%r5,-4
+	b     0f
+
+2:	lwz   %r7,0(%r5)
+	lwz   %r6,0(%r4)
+	subfc %r6,%r7,%r6
+	stw   %r6,0(%r3)
+        beq   1f
+
+ # Align start of loop to an odd word boundary to guarantee that the
+ # last two words can be fetched in one access (for 601).  This turns
+ # out to be important.
+0:
+	lwz   %r9,4(%r4)
+	lwz   %r8,4(%r5)
+	lwzu  %r6,8(%r4)
+	lwzu  %r7,8(%r5)
+	subfe %r8,%r8,%r9
+	stw   %r8,4(%r3)
+	subfe %r6,%r7,%r6
+	stwu  %r6,8(%r3)
+	bdnz  0b
+ # return the borrow
+1:	subfe %r3,%r3,%r3
+	neg   %r3,%r3
+	blr
diff --git a/sysdeps/powerpc/submul_1.s b/sysdeps/powerpc/submul_1.s
new file mode 100644
index 0000000000..999430d744
--- /dev/null
+++ b/sysdeps/powerpc/submul_1.s
@@ -0,0 +1,52 @@
+ # Multiply a limb vector by a single limb, for PowerPC.
+ # Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ # This file is part of the GNU C Library.
+ #
+ # 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.
+
+ # mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ #                         mp_size_t s1_size, mp_limb_t s2_limb)
+ # Calculate res-s1*s2 and put result back in res; return carry.
+
+	.align 2
+	.globl __mpn_submul_1
+	.type	 __mpn_submul_1,@function
+__mpn_submul_1:
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,0(%r3)
+	subf 	%r8,%r7,%r9
+	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
+	addi	%r3,%r3,-4		# adjust res_ptr
+	bdz	Lend
+
+Loop:	lwzu	%r0,4(%r4)
+	stwu	%r8,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,4(%r3)
+	addze   %r10,%r10
+	subf    %r8,%r7,%r9
+	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
+	bdnz	Loop
+
+Lend:	stw	%r8,4(%r3)
+	addze	%r3,%r10
+	blr
diff --git a/sysdeps/sparc/Dist b/sysdeps/sparc/Dist
new file mode 100644
index 0000000000..7832507772
--- /dev/null
+++ b/sysdeps/sparc/Dist
@@ -0,0 +1 @@
+sys/trap.h
diff --git a/sysdeps/sparc/sparc32/Dist b/sysdeps/sparc/sparc32/Dist
index 6c3b23baa5..8bd3729740 100644
--- a/sysdeps/sparc/sparc32/Dist
+++ b/sysdeps/sparc/sparc32/Dist
@@ -1,4 +1,3 @@
 dotmul.S umul.S
 divrem.m4 sdiv.S udiv.S rem.S urem.S
 alloca.S
-sys/trap.h
diff --git a/sysdeps/sparc/sparc32/sparcv8/Dist b/sysdeps/sparc/sparc32/sparcv8/Dist
new file mode 100644
index 0000000000..6318172684
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/Dist
@@ -0,0 +1,6 @@
+urem.S
+umul.S
+udiv.S
+sdiv.S
+rem.S
+dotmul.S
diff --git a/sysdeps/stub/des_impl.c b/sysdeps/stub/des_impl.c
new file mode 100644
index 0000000000..b6a4a8eb13
--- /dev/null
+++ b/sysdeps/stub/des_impl.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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.  */
+
+/* We must not distribute the DES implementation as part of the glibc.
+   So we have to provide a dummy version here.  */
+int
+_des_crypt (char *buf, unsigned len, struct desparams *desp)
+{
+  return 0;
+}
+
+stub_warning (_des_crypt)
diff --git a/sysdeps/unix/sysv/linux/mips/Dist b/sysdeps/unix/sysv/linux/mips/Dist
index 6be6876fe7..0f106cf8fa 100644
--- a/sysdeps/unix/sysv/linux/mips/Dist
+++ b/sysdeps/unix/sysv/linux/mips/Dist
@@ -6,6 +6,7 @@ kernel_termios.h
 entry.h
 regdef.h
 fpregdef.h
+sgidefs.h
 sys/acct.h
 sys/asm.h
 sys/cachectl.h
diff --git a/sysdeps/unix/sysv/linux/sparc/Dist b/sysdeps/unix/sysv/linux/sparc/Dist
new file mode 100644
index 0000000000..7832507772
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/Dist
@@ -0,0 +1 @@
+sys/trap.h
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Dist b/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
index 9729f0709b..ed8fc080c1 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
@@ -5,4 +5,3 @@ pipe.S
 fork.S
 kernel_stat.h
 init-first.h
-sys/trap.h