Browse Source

Rework RPC code once again. By default, only enable the
stuff needed for NFS mounts, rsh, and similar.
-Erik

Eric Andersen 22 years ago
parent
commit
17a1a692cb

+ 13 - 3
libc/inet/rpc/Makefile

@@ -23,8 +23,9 @@
 
 TOPDIR=../../../
 include $(TOPDIR)Rules.mak
-#CFLAGS+=-Werror
+CFLAGS+=-I$(TOPDIR)libpthread/linuxthreads/sysdeps/pthread
 
+ifeq ($(strip $(INCLUDE_FULL_RPC)),true)
 CSRC :=auth_none.c auth_unix.c authunix_prot.c bindresvport.c \
 	clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \
 	clnt_udp.c rpc_dtablesize.c get_myaddress.c getrpcent.c getrpcport.c \
@@ -34,8 +35,17 @@ CSRC :=auth_none.c auth_unix.c authunix_prot.c bindresvport.c \
 	svc_tcp.c svc_udp.c xdr.c xdr_array.c xdr_float.c xdr_mem.c \
 	xdr_rec.c xdr_reference.c xdr_stdio.c \
 	rtime.c clnt_unix.c svc_unix.c create_xid.c xdr_intXX_t.c rcmd.c \
-	rpc_thread.c
-#openchild.c xdr_sizeof.c
+	rexec.c sa_len.c ruserpass.c rpc_thread.c
+else
+# For now, only compile the stuff needed to do an NFS mount....
+CSRC:=create_xid.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
+	pmap_prot.c pmap_prot2.c clnt_simple.c clnt_perror.c \
+	clnt_tcp.c clnt_udp.c bindresvport.c authunix_prot.c \
+	auth_none.c auth_unix.c xdr.c xdr_array.c xdr_rec.c \
+	xdr_reference.c xdr_mem.c svc.c svc_auth.c svc_auth_unix.c \
+	rpc_callmsg.c rpc_prot.c rpc_dtablesize.c rpc_commondata.c \
+	rpc_thread.c rcmd.c rexec.c sa_len.c ruserpass.c rtime.c 
+endif
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 OBJS=$(COBJS)
 

+ 4 - 2
libc/inet/rpc/auth_none.c

@@ -35,7 +35,9 @@
  * credentials and verifiers to remote systems.
  */
 
-#include <rpc/rpc.h>
+#define __FORCE_GLIBC
+#include <features.h>
+#include "rpc_private.h"
 
 #define MAX_MARSHEL_SIZE 20
 
@@ -61,7 +63,7 @@ struct authnone_private_s {
   char marshalled_client[MAX_MARSHEL_SIZE];
   u_int mcnt;
 };
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 #define authnone_private ((struct authnone_private_s *)RPC_THREAD_VARIABLE(authnone_private_s))
 #else
 static struct authnone_private_s *authnone_private;

+ 2 - 2
libc/inet/rpc/clnt_perror.c

@@ -42,7 +42,7 @@ static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
 
 #include <stdio.h>
 #include <string.h>
-#include <rpc/rpc.h>
+#include "rpc_private.h"
 
 #ifdef USE_IN_LIBIO
 # include <wchar.h>
@@ -52,7 +52,7 @@ static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
 
 static char *auth_errmsg (enum auth_stat stat) internal_function;
 
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 /*
  * Making buf a preprocessor macro requires renaming the local
  * buf variable in a few functions.  Overriding a global variable

+ 4 - 2
libc/inet/rpc/clnt_raw.c

@@ -42,7 +42,9 @@ static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
  * any interference from the kernel.
  */
 
-#include <rpc/rpc.h>
+#define __FORCE_GLIBC
+#include <features.h>
+#include "rpc_private.h"
 #include <rpc/svc.h>
 #include <rpc/xdr.h>
 
@@ -59,7 +61,7 @@ struct clntraw_private_s
     char mashl_callmsg[MCALL_MSG_SIZE];
     u_int mcnt;
   };
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 #define clntraw_private ((struct clntraw_private_s *)RPC_THREAD_VARIABLE(clntraw_private_s))
 #else
 static struct clntraw_private_s *clntraw_private;

+ 4 - 4
libc/inet/rpc/clnt_simple.c

@@ -45,7 +45,7 @@ static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
 #include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <rpc/rpc.h>
+#include "rpc_private.h"
 #include <sys/socket.h>
 #include <netdb.h>
 #include <string.h>
@@ -57,7 +57,7 @@ struct callrpc_private_s
     u_long oldprognum, oldversnum, valid;
     char *oldhost;
   };
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 #define callrpc_private ((struct callrpc_private_s *)RPC_THREAD_VARIABLE(callrpc_private_s))
 #else
 static struct callrpc_private_s *callrpc_private;
@@ -149,7 +149,7 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
   return (int) clnt_stat;
 }
 
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 void
 __rpc_thread_clnt_cleanup (void)
 {
@@ -161,4 +161,4 @@ __rpc_thread_clnt_cleanup (void)
 		free (rcp);
 	}
 }
-#endif /* _RPC_THREAD_SAFE_ */
+#endif /* __UCLIBC_HAS_THREADS__ */

+ 1 - 1
libc/inet/rpc/create_xid.c

@@ -27,7 +27,7 @@
 
 /* The RPC code is not threadsafe, but new code should be threadsafe. */
 
-#ifdef _RPC_THREAD_SAFE_ //__UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_THREADS__
 #include <pthread.h>
 static pthread_mutex_t createxid_lock = PTHREAD_MUTEX_INITIALIZER;
 # define LOCK	pthread_mutex_lock(&createxid_lock)

+ 191 - 0
libc/inet/rpc/rexec.c

@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1980, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <alloca.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define SA_LEN(_x)      __libc_sa_len((_x)->sa_family)
+extern int __libc_sa_len (sa_family_t __af) __THROW;
+
+int	rexecoptions;
+char	ahostbuf[NI_MAXHOST];
+extern int ruserpass(const char *host, const char **aname, const char **apass);
+
+int
+rexec_af(ahost, rport, name, pass, cmd, fd2p, af)
+	char **ahost;
+	int rport;
+	const char *name, *pass, *cmd;
+	int *fd2p;
+	sa_family_t af;
+{
+	struct sockaddr_storage sa2, from;
+	struct addrinfo hints, *res0;
+	const char *orig_name = name;
+	const char *orig_pass = pass;
+	u_short port = 0;
+	int s, timo = 1, s3;
+	char c;
+	int gai;
+	char servbuff[NI_MAXSERV];
+
+	snprintf(servbuff, sizeof(servbuff), "%d", ntohs(rport));
+	servbuff[sizeof(servbuff) - 1] = '\0';
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = af;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_CANONNAME;
+	gai = getaddrinfo(*ahost, servbuff, &hints, &res0);
+	if (gai){
+		/* XXX: set errno? */
+		return -1;
+	}
+
+	if (res0->ai_canonname){
+		strncpy(ahostbuf, res0->ai_canonname, sizeof(ahostbuf));
+		ahostbuf[sizeof(ahostbuf)-1] = '\0';
+		*ahost = ahostbuf;
+	}
+	else{
+		*ahost = NULL;
+	}
+	ruserpass(res0->ai_canonname, &name, &pass);
+retry:
+	s = socket(res0->ai_family, res0->ai_socktype, 0);
+	if (s < 0) {
+		perror("rexec: socket");
+		return (-1);
+	}
+	if (connect(s, res0->ai_addr, res0->ai_addrlen) < 0) {
+		if (errno == ECONNREFUSED && timo <= 16) {
+			(void) close(s);
+			sleep(timo);
+			timo *= 2;
+			goto retry;
+		}
+		perror(res0->ai_canonname);
+		return (-1);
+	}
+	if (fd2p == 0) {
+		(void) write(s, "", 1);
+		port = 0;
+	} else {
+		char num[32];
+		int s2, sa2len;
+
+		s2 = socket(res0->ai_family, res0->ai_socktype, 0);
+		if (s2 < 0) {
+			(void) close(s);
+			return (-1);
+		}
+		listen(s2, 1);
+		sa2len = sizeof (sa2);
+		if (getsockname(s2, (struct sockaddr *)&sa2, &sa2len) < 0) {
+			perror("getsockname");
+			(void) close(s2);
+			goto bad;
+		} else if (sa2len != SA_LEN((struct sockaddr *)&sa2)) {
+			__set_errno(EINVAL);
+			(void) close(s2);
+			goto bad;
+		}
+		port = 0;
+		if (!getnameinfo((struct sockaddr *)&sa2, sa2len,
+				 NULL, 0, servbuff, sizeof(servbuff),
+				 NI_NUMERICSERV))
+			port = atoi(servbuff);
+		(void) sprintf(num, "%u", port);
+		(void) write(s, num, strlen(num)+1);
+		{ int len = sizeof (from);
+		  s3 = accept(s2, (struct sockaddr *)&from, &len);
+		  close(s2);
+		  if (s3 < 0) {
+			perror("accept");
+			port = 0;
+			goto bad;
+		  }
+		}
+		*fd2p = s3;
+	}
+	(void) write(s, name, strlen(name) + 1);
+	/* should public key encypt the password here */
+	(void) write(s, pass, strlen(pass) + 1);
+	(void) write(s, cmd, strlen(cmd) + 1);
+
+	/* We don't need the memory allocated for the name and the password
+	   in ruserpass anymore.  */
+	if (name != orig_name)
+	  free ((char *) name);
+	if (pass != orig_pass)
+	  free ((char *) pass);
+
+	if (read(s, &c, 1) != 1) {
+		perror(*ahost);
+		goto bad;
+	}
+	if (c != 0) {
+		while (read(s, &c, 1) == 1) {
+			(void) write(2, &c, 1);
+			if (c == '\n')
+				break;
+		}
+		goto bad;
+	}
+	freeaddrinfo(res0);
+	return (s);
+bad:
+	if (port)
+		(void) close(*fd2p);
+	(void) close(s);
+	freeaddrinfo(res0);
+	return (-1);
+}
+
+int
+rexec(ahost, rport, name, pass, cmd, fd2p)
+	char **ahost;
+	int rport;
+	const char *name, *pass, *cmd;
+	int *fd2p;
+{
+	return rexec_af(ahost, rport, name, pass, cmd, fd2p, AF_INET);
+}

+ 54 - 0
libc/inet/rpc/rpc_private.h

@@ -0,0 +1,54 @@
+#ifndef _RPC_RPC_H
+#include <rpc/rpc.h>
+
+/* Now define the internal interfaces.  */
+extern unsigned long _create_xid (void);
+
+/*
+ * Multi-threaded support
+ * Group all global and static variables into a single spot.
+ * This area is allocated on a per-thread basis
+ */
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+struct rpc_thread_variables {
+	fd_set		svc_fdset_s;		/* Global, rpc_common.c */
+	struct rpc_createerr rpc_createerr_s;	/* Global, rpc_common.c */
+	struct pollfd	*svc_pollfd_s;		/* Global, rpc_common.c */
+	int		svc_max_pollfd_s;	/* Global, rpc_common.c */
+
+	void		*authnone_private_s;	/* auth_none.c */
+
+	void		*clnt_perr_buf_s;	/* clnt_perr.c */
+
+	void		*clntraw_private_s;	/* clnt_raw.c */
+
+	void		*callrpc_private_s;	/* clnt_simp.c */
+
+	void		*key_call_private_s;	/* key_call.c */
+
+	void		*authdes_cache_s;	/* svcauth_des.c */
+	void		*authdes_lru_s;		/* svcauth_des.c */
+
+	void		*svc_xports_s;		/* svc.c */
+	void		*svc_head_s;		/* svc.c */
+
+	void		*svcraw_private_s;	/* svc_raw.c */
+
+	void		*svcsimple_proglst_s;	/* svc_simple.c */
+	void		*svcsimple_transp_s;	/* svc_simple.c */
+};
+
+extern struct rpc_thread_variables *__rpc_thread_variables(void)
+     __attribute__ ((const));
+extern void __rpc_thread_svc_cleanup (void);
+extern void __rpc_thread_clnt_cleanup (void);
+extern void __rpc_thread_key_cleanup (void);
+
+extern void __rpc_thread_destroy (void);
+
+#define RPC_THREAD_VARIABLE(x) (__rpc_thread_variables()->x)
+
+#endif /* __UCLIBC_HAS_THREADS__ */
+
+#endif

+ 34 - 9
libc/inet/rpc/rpc_thread.c

@@ -1,21 +1,37 @@
 #define __FORCE_GLIBC
 #include <features.h>
-
 #include <stdio.h>
-#include <rpc/rpc.h>
 #include <assert.h>
-
-#ifdef _RPC_THREAD_SAFE_
-
-#include <bits/libc-lock.h>
 #include <bits/libc-tsd.h>
-
+#include "rpc_private.h"
 
 /* Variable used in non-threaded applications or for the first thread.  */
 static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
 static struct rpc_thread_variables *__libc_tsd_RPC_VARS_data =
      &__libc_tsd_RPC_VARS_mem;
 
+#ifdef __UCLIBC_HAS_THREADS__
+
+
+extern int __pthread_once (pthread_once_t *__once_control,
+			   void (*__init_routine) (void));
+asm (".weak __pthread_once");
+
+
+# define __libc_once_define(CLASS, NAME) \
+  CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT
+
+/* Call handler iff the first call.  */
+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
+  do {									      \
+    if (__pthread_once != NULL)						      \
+      __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION));		      \
+    else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) {			      \
+      INIT_FUNCTION ();							      \
+      (ONCE_CONTROL) = !PTHREAD_ONCE_INIT;				      \
+    }									      \
+  } while (0)
+
 /*
  * Task-variable destructor
  */
@@ -27,7 +43,7 @@ __rpc_thread_destroy (void)
 	if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem) {
 		__rpc_thread_svc_cleanup ();
 		__rpc_thread_clnt_cleanup ();
-		__rpc_thread_key_cleanup ();
+		//__rpc_thread_key_cleanup ();
 		free (tvp->authnone_private_s);
 		free (tvp->clnt_perr_buf_s);
 		free (tvp->clntraw_private_s);
@@ -39,6 +55,8 @@ __rpc_thread_destroy (void)
 }
 
 
+#if 0
+#warning fix multithreaded initialization...
 /*
  * Initialize RPC multi-threaded operation
  */
@@ -69,6 +87,12 @@ __rpc_thread_variables (void)
 	}
 	return tvp;
 }
+#else
+struct rpc_thread_variables * __rpc_thread_variables (void)
+{
+    return __libc_tsd_RPC_VARS_data;
+}
+#endif
 
 
 /* Global variables If we're single-threaded, or if this is the first
@@ -154,4 +178,5 @@ int * __rpc_thread_svc_max_pollfd (void)
     return &(svc_max_pollfd);
 }
 
-#endif /* _RPC_THREAD_SAFE_ */
+#endif /* __UCLIBC_HAS_THREADS__ */
+

+ 327 - 0
libc/inet/rpc/ruserpass.c

@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 1985, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define _(X)  (X)
+/* #include "ftp_var.h" */
+
+static	int token (void);
+static	FILE *cfile;
+
+#define	DEFAULT	1
+#define	LOGIN	2
+#define	PASSWD	3
+#define	ACCOUNT 4
+#define MACDEF  5
+#define	ID	10
+#define	MACHINE	11
+
+static char tokval[100];
+
+static const char tokstr[] =
+{
+#define TOK_DEFAULT_IDX	0
+  "default\0"
+#define TOK_LOGIN_IDX	(TOK_DEFAULT_IDX + sizeof "default")
+  "login\0"
+#define TOK_PASSWORD_IDX (TOK_LOGIN_IDX + sizeof "login")
+  "password\0"
+#define TOK_PASSWD_IDX	(TOK_PASSWORD_IDX + sizeof "password")
+  "passwd\0"
+#define TOK_ACCOUNT_IDX	(TOK_PASSWD_IDX + sizeof "passwd")
+  "account\0"
+#define TOK_MACHINE_IDX	(TOK_ACCOUNT_IDX + sizeof "account")
+  "machine\0"
+#define TOK_MACDEF_IDX	(TOK_MACHINE_IDX + sizeof "machine")
+  "macdef"
+};
+
+static const struct toktab {
+	int tokstr_off;
+	int tval;
+} toktab[]= {
+	{ TOK_DEFAULT_IDX,	DEFAULT },
+	{ TOK_LOGIN_IDX,	LOGIN },
+	{ TOK_PASSWORD_IDX,	PASSWD },
+	{ TOK_PASSWD_IDX,	PASSWD },
+	{ TOK_ACCOUNT_IDX,	ACCOUNT },
+	{ TOK_MACHINE_IDX,	MACHINE },
+	{ TOK_MACDEF_IDX,	MACDEF }
+};
+
+
+
+int ruserpass(const char *host, const char **aname, const char **apass)
+{
+	char *hdir, *buf, *tmp;
+	char myname[1024], *mydomain;
+	int t, usedefault = 0;
+	struct stat64 stb;
+
+	/* Give up when running a setuid or setgid app. */
+	if ((getuid() != geteuid()) || getgid() != getegid())
+	    return -1;
+	hdir = getenv("HOME");
+	if (hdir == NULL) {
+		/* If we can't get HOME, fail instead of trying ".",
+		   which is no improvement. */
+	  	return -1;
+	}
+
+	buf = alloca (strlen(hdir) + 8);
+	strcpy(buf, hdir);
+	strcat(buf, "/.netrc");
+	cfile = fopen(buf, "r");
+	if (cfile == NULL) {
+		if (errno != ENOENT)
+			printf("%s", buf);
+		return (0);
+	}
+	/* No threads use this stream.  */
+	__fsetlocking (cfile, FSETLOCKING_BYCALLER);
+	if (gethostname(myname, sizeof(myname)) < 0)
+		myname[0] = '\0';
+	mydomain = strchr(myname, '.');
+	if (mydomain==NULL) {
+	    mydomain=myname + strlen(myname);
+	}
+next:
+	while ((t = token())) switch(t) {
+
+	case DEFAULT:
+		usedefault = 1;
+		/* FALL THROUGH */
+
+	case MACHINE:
+		if (!usedefault) {
+			if (token() != ID)
+				continue;
+			/*
+			 * Allow match either for user's input host name
+			 * or official hostname.  Also allow match of
+			 * incompletely-specified host in local domain.
+			 */
+			if (strcasecmp(host, tokval) == 0)
+				goto match;
+/*			if (__strcasecmp(hostname, tokval) == 0)
+				goto match;
+			if ((tmp = strchr(hostname, '.')) != NULL &&
+			    __strcasecmp(tmp, mydomain) == 0 &&
+			    __strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
+			    tokval[tmp - hostname] == '\0')
+				goto match; */
+			if ((tmp = strchr(host, '.')) != NULL &&
+			    strcasecmp(tmp, mydomain) == 0 &&
+			    strncasecmp(host, tokval, tmp - host) == 0 &&
+			    tokval[tmp - host] == '\0')
+				goto match;
+			continue;
+		}
+	match:
+		while ((t = token()) && t != MACHINE && t != DEFAULT) switch(t) {
+
+		case LOGIN:
+			if (token()) {
+				if (*aname == 0) {
+				  char *newp;
+				  newp = malloc((unsigned) strlen(tokval) + 1);
+				  if (newp == NULL)
+				    {
+				      printf(_("out of memory"));
+				      goto bad;
+				    }
+				  *aname = strcpy(newp, tokval);
+				} else {
+					if (strcmp(*aname, tokval))
+						goto next;
+				}
+			}
+			break;
+		case PASSWD:
+			if (strcmp(*aname, "anonymous") &&
+			    fstat64(fileno(cfile), &stb) >= 0 &&
+			    (stb.st_mode & 077) != 0) {
+	printf(_("Error: .netrc file is readable by others."));
+	printf(_("Remove password or make file unreadable by others."));
+				goto bad;
+			}
+			if (token() && *apass == 0) {
+				char *newp;
+				newp = malloc((unsigned) strlen(tokval) + 1);
+				if (newp == NULL)
+				  {
+				    printf(_("out of memory"));
+				    goto bad;
+				  }
+				*apass = strcpy(newp, tokval);
+			}
+			break;
+		case ACCOUNT:
+#if 0
+			if (fstat64(fileno(cfile), &stb) >= 0
+			    && (stb.st_mode & 077) != 0) {
+	printf("Error: .netrc file is readable by others.");
+	printf("Remove account or make file unreadable by others.");
+				goto bad;
+			}
+			if (token() && *aacct == 0) {
+				*aacct = malloc((unsigned) strlen(tokval) + 1);
+				(void) strcpy(*aacct, tokval);
+			}
+#endif
+			break;
+		case MACDEF:
+#if 0
+			if (proxy) {
+				(void) fclose(cfile);
+				return (0);
+			}
+			while ((c=getc_unlocked(cfile)) != EOF && c == ' '
+			       || c == '\t');
+			if (c == EOF || c == '\n') {
+				printf("Missing macdef name argument.\n");
+				goto bad;
+			}
+			if (macnum == 16) {
+				printf("Limit of 16 macros have already been defined\n");
+				goto bad;
+			}
+			tmp = macros[macnum].mac_name;
+			*tmp++ = c;
+			for (i=0; i < 8 && (c=getc_unlocked(cfile)) != EOF &&
+			    !isspace(c); ++i) {
+				*tmp++ = c;
+			}
+			if (c == EOF) {
+				printf("Macro definition missing null line terminator.\n");
+				goto bad;
+			}
+			*tmp = '\0';
+			if (c != '\n') {
+				while ((c=getc_unlocked(cfile)) != EOF
+				       && c != '\n');
+			}
+			if (c == EOF) {
+				printf("Macro definition missing null line terminator.\n");
+				goto bad;
+			}
+			if (macnum == 0) {
+				macros[macnum].mac_start = macbuf;
+			}
+			else {
+				macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
+			}
+			tmp = macros[macnum].mac_start;
+			while (tmp != macbuf + 4096) {
+				if ((c=getc_unlocked(cfile)) == EOF) {
+				printf("Macro definition missing null line terminator.\n");
+					goto bad;
+				}
+				*tmp = c;
+				if (*tmp == '\n') {
+					if (*(tmp-1) == '\0') {
+					   macros[macnum++].mac_end = tmp - 1;
+					   break;
+					}
+					*tmp = '\0';
+				}
+				tmp++;
+			}
+			if (tmp == macbuf + 4096) {
+				printf("4K macro buffer exceeded\n");
+				goto bad;
+			}
+#endif
+			break;
+		default:
+			printf(_("Unknown .netrc keyword %s"), tokval);
+			break;
+		}
+		goto done;
+	}
+done:
+	(void) fclose(cfile);
+	return (0);
+bad:
+	(void) fclose(cfile);
+	return (-1);
+}
+
+static int
+token()
+{
+	char *cp;
+	int c;
+	int i;
+
+	if (feof_unlocked(cfile) || ferror_unlocked(cfile))
+		return (0);
+	while ((c = getc_unlocked(cfile)) != EOF &&
+	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
+		continue;
+	if (c == EOF)
+		return (0);
+	cp = tokval;
+	if (c == '"') {
+		while ((c = getc_unlocked(cfile)) != EOF && c != '"') {
+			if (c == '\\')
+				c = getc_unlocked(cfile);
+			*cp++ = c;
+		}
+	} else {
+		*cp++ = c;
+		while ((c = getc_unlocked(cfile)) != EOF
+		    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
+			if (c == '\\')
+				c = getc_unlocked(cfile);
+			*cp++ = c;
+		}
+	}
+	*cp = 0;
+	if (tokval[0] == 0)
+		return (0);
+	for (i = 0; i < (int) (sizeof (toktab) / sizeof (toktab[0])); ++i)
+		if (!strcmp(&tokstr[toktab[i].tokstr_off], tokval))
+			return toktab[i].tval;
+	return (ID);
+}

+ 62 - 0
libc/inet/rpc/sa_len.c

@@ -0,0 +1,62 @@
+/* Copyright (C) 1998, 1999 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define __FORCE_GLIBC
+#include <features.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netipx/ipx.h>
+#include <sys/un.h>
+#if 0
+#include <netash/ash.h>
+#include <netatalk/at.h>
+#include <netax25/ax25.h>
+#include <neteconet/ec.h>
+#include <netpacket/packet.h>
+#include <netrose/rose.h>
+#endif
+
+int __libc_sa_len (sa_family_t af)
+{
+  switch (af)
+    {
+#if 0
+    case AF_APPLETALK:
+      return sizeof (struct sockaddr_at);
+    case AF_ASH:
+      return sizeof (struct sockaddr_ash);
+    case AF_AX25:
+      return sizeof (struct sockaddr_ax25);
+    case AF_ECONET:
+      return sizeof (struct sockaddr_ec);
+    case AF_ROSE:
+      return sizeof (struct sockaddr_rose);
+    case AF_PACKET:
+      return sizeof (struct sockaddr_ll);
+#endif
+    case AF_INET:
+      return sizeof (struct sockaddr_in);
+    case AF_INET6:
+      return sizeof (struct sockaddr_in6);
+    case AF_IPX:
+      return sizeof (struct sockaddr_ipx);
+    case AF_LOCAL:
+      return sizeof (struct sockaddr_un);
+    }
+  return 0;
+}

+ 5 - 5
libc/inet/rpc/svc.c

@@ -42,12 +42,12 @@
 
 #include <errno.h>
 #include <unistd.h>
-#include <rpc/rpc.h>
+#include "rpc_private.h"
 #include <rpc/svc.h>
 #include <rpc/pmap_clnt.h>
 #include <sys/poll.h>
 
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 #define xports ((SVCXPRT **)RPC_THREAD_VARIABLE(svc_xports_s))
 #else
 static SVCXPRT **xports;
@@ -66,7 +66,7 @@ struct svc_callout {
   rpcvers_t sc_vers;
   void (*sc_dispatch) (struct svc_req *, SVCXPRT *);
 };
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 #define svc_head ((struct svc_callout *)RPC_THREAD_VARIABLE(svc_head_s))
 #else
 static struct svc_callout *svc_head;
@@ -478,7 +478,7 @@ svc_getreq_common (const int fd)
   while (stat == XPRT_MOREREQS);
 }
 
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 
 void
 __rpc_thread_svc_cleanup (void)
@@ -489,4 +489,4 @@ __rpc_thread_svc_cleanup (void)
     svc_unregister (svcp->sc_prog, svcp->sc_vers);
 }
 
-#endif /* _RPC_THREAD_SAFE_ */
+#endif /* __UCLIBC_HAS_THREADS__ */

+ 4 - 2
libc/inet/rpc/svc_raw.c

@@ -40,7 +40,9 @@ static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";
  * Copyright (C) 1984, Sun Microsystems, Inc.
  */
 
-#include <rpc/rpc.h>
+#define __FORCE_GLIBC
+#include <features.h>
+#include "rpc_private.h"
 #include <rpc/svc.h>
 
 /*
@@ -53,7 +55,7 @@ struct svcraw_private_s
     XDR xdr_stream;
     char verf_body[MAX_AUTH_BYTES];
   };
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 #define svcraw_private ((struct svcraw_private_s *)RPC_THREAD_VARIABLE(svcraw_private_s))
 #else
 static struct svcraw_private_s *svcraw_private;

+ 3 - 3
libc/inet/rpc/svc_simple.c

@@ -44,7 +44,7 @@ static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
-#include <rpc/rpc.h>
+#include "rpc_private.h"
 #include <rpc/pmap_clnt.h>
 #include <sys/socket.h>
 #include <netdb.h>
@@ -63,7 +63,7 @@ struct proglst_
     xdrproc_t p_inproc, p_outproc;
     struct proglst_ *p_nxt;
   };
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 #define proglst ((struct proglst_ *)RPC_THREAD_VARIABLE(svcsimple_proglst_s))
 #else
 static struct proglst_ *proglst;
@@ -71,7 +71,7 @@ static struct proglst_ *proglst;
 
 
 static void universal (struct svc_req *rqstp, SVCXPRT *transp_s);
-#ifdef _RPC_THREAD_SAFE_
+#ifdef __UCLIBC_HAS_THREADS__
 #define transp ((SVCXPRT *)RPC_THREAD_VARIABLE(svcsimple_transp_s))
 #else
 static SVCXPRT *transp;