Browse Source

Make things more re-entrany, kill some cruft.
-Erik

Eric Andersen 22 years ago
parent
commit
3aabbb4ab1
5 changed files with 385 additions and 440 deletions
  1. 7 5
      libc/inet/addr.c
  2. 88 72
      libc/inet/getnetent.c
  3. 99 71
      libc/inet/getproto.c
  4. 143 114
      libc/inet/getservice.c
  5. 48 178
      libc/inet/resolv.c

+ 7 - 5
libc/inet/addr.c

@@ -85,12 +85,8 @@ const char *cp;
 #endif
 
 #ifdef L_inet_ntoa
-
-char *inet_ntoa(in)
-struct in_addr in;
+char *inet_ntoa_r(struct in_addr in, char buf[16])
 {
-	static char buf[16];		/* max 12 digits + 3 '.'s + 1 nul */
-
 	unsigned long addr = ntohl(in.s_addr);
 	int i;
 	char *p, *q;
@@ -108,6 +104,12 @@ struct in_addr in;
 
 	return p+1;
 }
+
+char *inet_ntoa(struct in_addr in)
+{
+	static char buf[16];		/* max 12 digits + 3 '.'s + 1 nul */
+	return(inet_ntoa_r(in, buf));
+}
 #endif
 
 #ifdef L_inet_makeaddr

+ 88 - 72
libc/inet/getnetent.c

@@ -21,98 +21,114 @@
 #include <netdb.h>
 #include <arpa/inet.h>
 
-#define	MAXALIASES	35
 
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+# define LOCK	pthread_mutex_lock(&mylock)
+# define UNLOCK	pthread_mutex_unlock(&mylock);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+
+
+#define	MAXALIASES	35
 static const char NETDB[] = _PATH_NETWORKS;
 static FILE *netf = NULL;
 static char line[BUFSIZ+1];
 static struct netent net;
 static char *net_aliases[MAXALIASES];
-static char *any(char *, char *);
 
 int _net_stayopen;
 
-void
-setnetent(f)
-	int f;
+void setnetent(int f)
 {
-	if (netf == NULL)
-		netf = fopen(NETDB, "r" );
-	else
-		rewind(netf);
-	_net_stayopen |= f;
+    LOCK;
+    if (netf == NULL)
+	netf = fopen(NETDB, "r" );
+    else
+	rewind(netf);
+    _net_stayopen |= f;
+    UNLOCK;
+    return;
 }
 
-void
-endnetent()
+void endnetent(void)
 {
-	if (netf) {
-		fclose(netf);
-		netf = NULL;
-	}
-	_net_stayopen = 0;
+    LOCK;
+    if (netf) {
+	fclose(netf);
+	netf = NULL;
+    }
+    _net_stayopen = 0;
+    UNLOCK;
 }
 
-struct netent *
-getnetent()
+static char * any(register char *cp, char *match)
 {
-	char *p;
-	register char *cp, **q;
+    register char *mp, c;
 
-	if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL)
-		return (NULL);
-again:
-	p = fgets(line, BUFSIZ, netf);
-	if (p == NULL)
-		return (NULL);
-	if (*p == '#')
-		goto again;
-	cp = any(p, "#\n");
-	if (cp == NULL)
-		goto again;
-	*cp = '\0';
-	net.n_name = p;
-	cp = any(p, " \t");
-	if (cp == NULL)
-		goto again;
-	*cp++ = '\0';
-	while (*cp == ' ' || *cp == '\t')
-		cp++;
-	p = any(cp, " \t");
-	if (p != NULL)
-		*p++ = '\0';
-	net.n_net = inet_network(cp);
-	net.n_addrtype = AF_INET;
-	q = net.n_aliases = net_aliases;
-	if (p != NULL) 
-		cp = p;
-	while (cp && *cp) {
-		if (*cp == ' ' || *cp == '\t') {
-			cp++;
-			continue;
-		}
-		if (q < &net_aliases[MAXALIASES - 1])
-			*q++ = cp;
-		cp = any(cp, " \t");
-		if (cp != NULL)
-			*cp++ = '\0';
-	}
-	*q = NULL;
-	return (&net);
+    while ((c = *cp)) {
+	for (mp = match; *mp; mp++)
+	    if (*mp == c)
+		return (cp);
+	cp++;
+    }
+    return ((char *)0);
 }
 
-static char *
-any(cp, match)
-	register char *cp;
-	char *match;
+struct netent * getnetent(void)
 {
-	register char *mp, c;
+    char *p;
+    register char *cp, **q;
 
-	while ((c = *cp)) {
-		for (mp = match; *mp; mp++)
-			if (*mp == c)
-				return (cp);
-		cp++;
+    LOCK;
+    if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL) {
+	UNLOCK;
+	return (NULL);
+    }
+again:
+    p = fgets(line, BUFSIZ, netf);
+    if (p == NULL) {
+	UNLOCK;
+	return (NULL);
+    }
+    if (*p == '#')
+	goto again;
+    cp = any(p, "#\n");
+    if (cp == NULL)
+	goto again;
+    *cp = '\0';
+    net.n_name = p;
+    cp = any(p, " \t");
+    if (cp == NULL)
+	goto again;
+    *cp++ = '\0';
+    while (*cp == ' ' || *cp == '\t')
+	cp++;
+    p = any(cp, " \t");
+    if (p != NULL)
+	*p++ = '\0';
+    net.n_net = inet_network(cp);
+    net.n_addrtype = AF_INET;
+    q = net.n_aliases = net_aliases;
+    if (p != NULL) 
+	cp = p;
+    while (cp && *cp) {
+	if (*cp == ' ' || *cp == '\t') {
+	    cp++;
+	    continue;
 	}
-	return ((char *)0);
+	if (q < &net_aliases[MAXALIASES - 1])
+	    *q++ = cp;
+	cp = any(cp, " \t");
+	if (cp != NULL)
+	    *cp++ = '\0';
+    }
+    *q = NULL;
+    UNLOCK;
+    return (&net);
 }
+

+ 99 - 71
libc/inet/getproto.c

@@ -52,6 +52,7 @@
 */
 
 #define __FORCE_GLIBC
+#define _GNU_SOURCE
 #include <features.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -60,6 +61,18 @@
 #include <stdlib.h>
 #include <string.h>
 
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+# define LOCK	pthread_mutex_lock(&mylock)
+# define UNLOCK	pthread_mutex_unlock(&mylock);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+
+
 #define	MAXALIASES	35
 
 static FILE *protof = NULL;
@@ -70,97 +83,112 @@ static int proto_stayopen;
 
 void setprotoent(int f)
 {
-	if (protof == NULL)
-		protof = fopen(_PATH_PROTOCOLS, "r" );
-	else
-		rewind(protof);
-	proto_stayopen |= f;
+    LOCK;
+    if (protof == NULL)
+	protof = fopen(_PATH_PROTOCOLS, "r" );
+    else
+	rewind(protof);
+    proto_stayopen |= f;
+    UNLOCK;
 }
 
 void endprotoent(void)
 {
-	if (protof) {
-		fclose(protof);
-		protof = NULL;
-	}
-	proto_stayopen = 0;
+    LOCK;
+    if (protof) {
+	fclose(protof);
+	protof = NULL;
+    }
+    proto_stayopen = 0;
+    UNLOCK;
 }
 
 struct protoent * getprotoent(void)
 {
-	char *p;
-	register char *cp, **q;
+    char *p;
+    register char *cp, **q;
 
-	if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
-		return (NULL);
+    LOCK;
+    if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) {
+	UNLOCK;
+	return (NULL);
+    }
 again:
-	if ((p = fgets(line, BUFSIZ, protof)) == NULL)
-		return (NULL);
-	if (*p == '#')
-		goto again;
-	cp = strpbrk(p, "#\n");
-	if (cp == NULL)
-		goto again;
-	*cp = '\0';
-	proto.p_name = p;
-	cp = strpbrk(p, " \t");
-	if (cp == NULL)
-		goto again;
-	*cp++ = '\0';
-	while (*cp == ' ' || *cp == '\t')
+    if ((p = fgets(line, BUFSIZ, protof)) == NULL) {
+	UNLOCK;
+	return (NULL);
+    }
+
+    if (*p == '#')
+	goto again;
+    cp = strpbrk(p, "#\n");
+    if (cp == NULL)
+	goto again;
+    *cp = '\0';
+    proto.p_name = p;
+    cp = strpbrk(p, " \t");
+    if (cp == NULL)
+	goto again;
+    *cp++ = '\0';
+    while (*cp == ' ' || *cp == '\t')
+	cp++;
+    p = strpbrk(cp, " \t");
+    if (p != NULL)
+	*p++ = '\0';
+    proto.p_proto = atoi(cp);
+    q = proto.p_aliases = proto_aliases;
+    if (p != NULL) {
+	cp = p;
+	while (cp && *cp) {
+	    if (*cp == ' ' || *cp == '\t') {
 		cp++;
-	p = strpbrk(cp, " \t");
-	if (p != NULL)
-		*p++ = '\0';
-	proto.p_proto = atoi(cp);
-	q = proto.p_aliases = proto_aliases;
-	if (p != NULL) {
-		cp = p;
-		while (cp && *cp) {
-			if (*cp == ' ' || *cp == '\t') {
-				cp++;
-				continue;
-			}
-			if (q < &proto_aliases[MAXALIASES - 1])
-				*q++ = cp;
-			cp = strpbrk(cp, " \t");
-			if (cp != NULL)
-				*cp++ = '\0';
-		}
+		continue;
+	    }
+	    if (q < &proto_aliases[MAXALIASES - 1])
+		*q++ = cp;
+	    cp = strpbrk(cp, " \t");
+	    if (cp != NULL)
+		*cp++ = '\0';
 	}
-	*q = NULL;
-	return (&proto);
+    }
+    *q = NULL;
+    UNLOCK;
+    return (&proto);
 }
 
 
 struct protoent * getprotobyname(const char *name)
 {
-	register struct protoent *p;
-	register char **cp;
-
-	setprotoent(proto_stayopen);
-	while ((p = getprotoent()) != NULL) {
-		if (strcmp(p->p_name, name) == 0)
-			break;
-		for (cp = p->p_aliases; *cp != 0; cp++)
-			if (strcmp(*cp, name) == 0)
-				goto found;
-	}
+    register struct protoent *p;
+    register char **cp;
+
+    LOCK;
+    setprotoent(proto_stayopen);
+    while ((p = getprotoent()) != NULL) {
+	if (strcmp(p->p_name, name) == 0)
+	    break;
+	for (cp = p->p_aliases; *cp != 0; cp++)
+	    if (strcmp(*cp, name) == 0)
+		goto found;
+    }
 found:
-	if (!proto_stayopen)
-		endprotoent();
-	return (p);
+    if (!proto_stayopen)
+	endprotoent();
+    UNLOCK;
+    return (p);
 }
 
 struct protoent * getprotobynumber(int proto)
 {
-	register struct protoent *p;
-
-	setprotoent(proto_stayopen);
-	while ((p = getprotoent()) != NULL)
-		if (p->p_proto == proto)
-			break;
-	if (!proto_stayopen)
-		endprotoent();
-	return (p);
+    register struct protoent *p;
+
+    LOCK;
+    setprotoent(proto_stayopen);
+    while ((p = getprotoent()) != NULL)
+	if (p->p_proto == proto)
+	    break;
+    if (!proto_stayopen)
+	endprotoent();
+    UNLOCK;
+    return (p);
 }

+ 143 - 114
libc/inet/getservice.c

@@ -53,6 +53,7 @@
 
 
 #define __FORCE_GLIBC
+#define _GNU_SOURCE
 #include <features.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -64,6 +65,21 @@
 #include <arpa/inet.h>
 #include <errno.h>
 
+
+
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+# define LOCK	pthread_mutex_lock(&mylock)
+# define UNLOCK	pthread_mutex_unlock(&mylock);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+
+
+
 #define	MAXALIASES	35
 
 static FILE *servf = NULL;
@@ -73,156 +89,169 @@ static int serv_stayopen;
 
 void setservent(int f)
 {
-	if (servf == NULL)
-		servf = fopen(_PATH_SERVICES, "r" );
-	else
-		rewind(servf);
-	serv_stayopen |= f;
+    LOCK;
+    if (servf == NULL)
+	servf = fopen(_PATH_SERVICES, "r" );
+    else
+	rewind(servf);
+    serv_stayopen |= f;
+    UNLOCK;
 }
 
 void endservent(void)
 {
-	if (servf) {
-		fclose(servf);
-		servf = NULL;
-	}
-	serv_stayopen = 0;
+    LOCK;
+    if (servf) {
+	fclose(servf);
+	servf = NULL;
+    }
+    serv_stayopen = 0;
+    UNLOCK;
 }
 
 struct servent * getservent(void)
 {
-	struct servent *result;
-	getservent_r(&serv, buf, sizeof(buf), &result);
-	return result;
+    struct servent *result;
+    getservent_r(&serv, buf, sizeof(buf), &result);
+    return result;
 }
 
 
 struct servent *getservbyname(const char *name, const char *proto)
 {
-	struct servent *result;
-	getservbyname_r(name, proto, &serv, buf, sizeof(buf), &result);
-	return result;
+    struct servent *result;
+    getservbyname_r(name, proto, &serv, buf, sizeof(buf), &result);
+    return result;
 }
 
 
 struct servent * getservbyport(int port, const char *proto)
 {
-	struct servent *result;
-	getservbyport_r(port, proto, &serv, buf, sizeof(buf), &result);
-	return result;
+    struct servent *result;
+    getservbyport_r(port, proto, &serv, buf, sizeof(buf), &result);
+    return result;
 }
 
 int getservent_r(struct servent * result_buf,
 		 char * buf, size_t buflen,
 		 struct servent ** result)
 {
-	char *p;
-	register char *cp, **q;
-	char **serv_aliases;
-	char *line;
+    char *p;
+    register char *cp, **q;
+    char **serv_aliases;
+    char *line;
 
-	*result=NULL;
+    *result=NULL;
 
-	if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
-		errno=ERANGE;
-		return errno;
-	}
-	serv_aliases=(char **)buf;
-	buf+=sizeof(*serv_aliases)*MAXALIASES;
-	buflen-=sizeof(*serv_aliases)*MAXALIASES;
-	
-	if (buflen < BUFSIZ+1) {
-		errno=ERANGE;
-		return errno;
-	}
-	line=buf;
-	buf+=BUFSIZ+1;
-	buflen-=BUFSIZ+1;
+    if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
+	errno=ERANGE;
+	return errno;
+    }
+    LOCK;
+    serv_aliases=(char **)buf;
+    buf+=sizeof(*serv_aliases)*MAXALIASES;
+    buflen-=sizeof(*serv_aliases)*MAXALIASES;
+
+    if (buflen < BUFSIZ+1) {
+	UNLOCK;
+	errno=ERANGE;
+	return errno;
+    }
+    line=buf;
+    buf+=BUFSIZ+1;
+    buflen-=BUFSIZ+1;
 
-	if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
-		return errno;
+    if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) {
+	UNLOCK;
+	return errno;
+    }
 again:
-	if ((p = fgets(line, BUFSIZ, servf)) == NULL)
-		return TRY_AGAIN;
-	if (*p == '#')
-		goto again;
-	cp = strpbrk(p, "#\n");
-	if (cp == NULL)
-		goto again;
-	*cp = '\0';
-	result_buf->s_name = p;
-	p = strpbrk(p, " \t");
-	if (p == NULL)
-		goto again;
-	*p++ = '\0';
-	while (*p == ' ' || *p == '\t')
-		p++;
-	cp = strpbrk(p, ",/");
-	if (cp == NULL)
-		goto again;
+    if ((p = fgets(line, BUFSIZ, servf)) == NULL) {
+	UNLOCK;
+	return TRY_AGAIN;
+    }
+    if (*p == '#')
+	goto again;
+    cp = strpbrk(p, "#\n");
+    if (cp == NULL)
+	goto again;
+    *cp = '\0';
+    result_buf->s_name = p;
+    p = strpbrk(p, " \t");
+    if (p == NULL)
+	goto again;
+    *p++ = '\0';
+    while (*p == ' ' || *p == '\t')
+	p++;
+    cp = strpbrk(p, ",/");
+    if (cp == NULL)
+	goto again;
+    *cp++ = '\0';
+    result_buf->s_port = htons((u_short)atoi(p));
+    result_buf->s_proto = cp;
+    q = result_buf->s_aliases = serv_aliases;
+    cp = strpbrk(cp, " \t");
+    if (cp != NULL)
 	*cp++ = '\0';
-	result_buf->s_port = htons((u_short)atoi(p));
-	result_buf->s_proto = cp;
-	q = result_buf->s_aliases = serv_aliases;
+    while (cp && *cp) {
+	if (*cp == ' ' || *cp == '\t') {
+	    cp++;
+	    continue;
+	}
+	if (q < &serv_aliases[MAXALIASES - 1])
+	    *q++ = cp;
 	cp = strpbrk(cp, " \t");
 	if (cp != NULL)
-		*cp++ = '\0';
-	while (cp && *cp) {
-		if (*cp == ' ' || *cp == '\t') {
-			cp++;
-			continue;
-		}
-		if (q < &serv_aliases[MAXALIASES - 1])
-			*q++ = cp;
-		cp = strpbrk(cp, " \t");
-		if (cp != NULL)
-			*cp++ = '\0';
-	}
-	*q = NULL;
-	*result=result_buf;
-	return 0;
+	    *cp++ = '\0';
+    }
+    *q = NULL;
+    *result=result_buf;
+    UNLOCK;
+    return 0;
 }
 
-int getservbyname_r(const char *name, const char *proto,
-			    struct servent * result_buf,
-			    char * buf, size_t buflen,
-			    struct servent ** result)
+int getservbyname_r(const char *name, const char *proto, 
+	struct servent * result_buf, char * buf, size_t buflen, 
+	struct servent ** result)
 {
-	register char **cp;
-	int ret;
-
-	setservent(serv_stayopen);
-	while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
-		if (strcmp(name, result_buf->s_name) == 0)
-			goto gotname;
-		for (cp = result_buf->s_aliases; *cp; cp++)
-			if (strcmp(name, *cp) == 0)
-				goto gotname;
-		continue;
+    register char **cp;
+    int ret;
+
+    LOCK;
+    setservent(serv_stayopen);
+    while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
+	if (strcmp(name, result_buf->s_name) == 0)
+	    goto gotname;
+	for (cp = result_buf->s_aliases; *cp; cp++)
+	    if (strcmp(name, *cp) == 0)
+		goto gotname;
+	continue;
 gotname:
-		if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
-			break;
-	}
-	if (!serv_stayopen)
-		endservent();
-	return *result?0:ret;
+	if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
+	    break;
+    }
+    if (!serv_stayopen)
+	endservent();
+    UNLOCK;
+    return *result?0:ret;
 }
 
-int getservbyport_r(int port, const char *proto,
-			    struct servent * result_buf,
-			    char * buf, size_t buflen,
-			    struct servent ** result)
+int getservbyport_r(int port, const char *proto, 
+	struct servent * result_buf, char * buf, 
+	size_t buflen, struct servent ** result)
 {
-	int ret;
-
-	setservent(serv_stayopen);
-	while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
-		if (result_buf->s_port != port)
-			continue;
-		if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
-			break;
-	}
-	if (!serv_stayopen)
-		endservent();
-	return *result?0:ret;
+    int ret;
+
+    LOCK;
+    setservent(serv_stayopen);
+    while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
+	if (result_buf->s_port != port)
+	    continue;
+	if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
+	    break;
+    }
+    if (!serv_stayopen)
+	endservent();
+    UNLOCK;
+    return *result?0:ret;
 }

+ 48 - 178
libc/inet/resolv.c

@@ -82,6 +82,15 @@
 #endif /* DEBUG */
 
 
+/* Global stuff... */
+extern int nameservers;
+extern char * nameserver[MAX_SERVERS];
+extern int searchdomains;
+extern char * searchdomain[MAX_SEARCH];
+
+
+
+/* Structs */
 struct resolv_header {
 	int id;
 	int qr,opcode,aa,tc,rd,ra,rcode;
@@ -113,11 +122,7 @@ enum etc_hosts_action {
     GET_HOSTS_BYADDR,
 };
 
-
-extern int nameservers;
-extern char * nameserver[MAX_SERVERS];
-extern int searchdomains;
-extern char * searchdomain[MAX_SEARCH];
+/* function prototypes */
 extern int get_hosts_byname_r(const char * name, int type,
 			      struct hostent * result_buf,
 			      char * buf, size_t buflen,
@@ -135,28 +140,24 @@ extern int read_etc_hosts_r(FILE *fp, const char * name, int type,
 			    char * buf, size_t buflen,
 			    struct hostent ** result,
 			    int * h_errnop);
-extern int resolve_address(const char * address, int nscount, 
-	char ** nsip, struct in_addr * in);
-extern int resolve_mailbox(const char * address, int nscount, 
-	char ** nsip, struct in_addr * in);
 extern int dns_lookup(const char * name, int type, int nscount, 
 	char ** nsip, unsigned char ** outpacket, struct resolv_answer * a);
 
-int encode_dotted(const char * dotted, unsigned char * dest, int maxlen);
-int decode_dotted(const unsigned char * message, int offset, 
+extern int encode_dotted(const char * dotted, unsigned char * dest, int maxlen);
+extern int decode_dotted(const unsigned char * message, int offset, 
 	char * dest, int maxlen);
-int length_dotted(const unsigned char * message, int offset);
-int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen);
-int decode_header(unsigned char * data, struct resolv_header * h);
-int encode_question(struct resolv_question * q,
+extern int length_dotted(const unsigned char * message, int offset);
+extern int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen);
+extern int decode_header(unsigned char * data, struct resolv_header * h);
+extern int encode_question(struct resolv_question * q,
 	unsigned char * dest, int maxlen);
-int decode_question(unsigned char * message, int offset,
+extern int decode_question(unsigned char * message, int offset,
 	struct resolv_question * q);
-int encode_answer(struct resolv_answer * a,
+extern int encode_answer(struct resolv_answer * a,
 	unsigned char * dest, int maxlen);
-int decode_answer(unsigned char * message, int offset,
+extern int decode_answer(unsigned char * message, int offset,
 	struct resolv_answer * a);
-int length_question(unsigned char * message, int offset);
+extern int length_question(unsigned char * message, int offset);
 extern int open_nameservers(void);
 
 
@@ -343,7 +344,7 @@ int encode_question(struct resolv_question *q,
 int decode_question(unsigned char *message, int offset,
 					struct resolv_question *q)
 {
-	char temp[256];
+	char temp[BUFSIZ];
 	int i;
 
 	i = decode_dotted(message, offset, temp, sizeof(temp));
@@ -408,7 +409,7 @@ int encode_answer(struct resolv_answer *a, unsigned char *dest, int maxlen)
 int decode_answer(unsigned char *message, int offset,
 				  struct resolv_answer *a)
 {
-	char temp[256];
+	char temp[BUFSIZ];
 	int i;
 
 	i = decode_dotted(message, offset, temp, sizeof(temp));
@@ -533,9 +534,7 @@ int form_query(int id, const char *name, int type, unsigned char *packet,
 int dns_lookup(const char *name, int type, int nscount, char **nsip,
 			   unsigned char **outpacket, struct resolv_answer *a)
 {
-	static int id = 1;
-	int i, j, len, fd, pos;
-	static int ns = 0;
+	int i, j, len, fd, pos, id, ns;
 	struct sockaddr_in sa;
 #ifdef __UCLIBC_HAS_IPV6__
 	struct sockaddr_in6 sa6;
@@ -581,7 +580,8 @@ int dns_lookup(const char *name, int type, int nscount, char **nsip,
 		memset(packet, 0, PACKETSZ);
 
 		memset(&h, 0, sizeof(h));
-		h.id = ++id;
+		id = (int) random();
+		h.id = id;
 		h.qdcount = 1;
 		h.rd = 1;
 
@@ -753,116 +753,6 @@ fail:
 }
 #endif
 
-#ifdef L_resolveaddress
-
-int resolve_address(const char *address, int nscount, 
-	char **nsip, struct in_addr *in)
-{
-	unsigned char *packet;
-	struct resolv_answer a;
-	char temp[256];
-	int i;
-	int nest = 0;
-
-	if (!address || !in)
-		return -1;
-
-	strncpy(temp, address, sizeof(temp));
-
-	for (;;) {
-
-		i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a);
-
-		if (i < 0)
-			return -1;
-
-		free(a.dotted);
-
-		if (a.atype == T_CNAME) {		/* CNAME */
-			DPRINTF("Got a CNAME in resolve_address()\n");
-			i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp));
-			free(packet);
-
-			if (i < 0)
-				return -1;
-			if (++nest > MAX_RECURSE)
-				return -1;
-			continue;
-		} else if (a.atype == T_A) {	/* ADDRESS */
-			free(packet);
-			break;
-		} else {
-			free(packet);
-			return -1;
-		}
-	}
-
-	if (in)
-	    memcpy(in, a.rdata, INADDRSZ); /* IPv4 T_A */
-
-	return 0;
-}
-#endif
-
-#ifdef L_resolvemailbox
-
-int resolve_mailbox(const char *address, int nscount, 
-	char **nsip, struct in_addr *in)
-{
-	struct resolv_answer a;
-	unsigned char *packet;
-	char temp[256];
-	int nest = 0;
-	int i;
-
-	if (!address || !in)
-		return -1;
-
-	/* look up mail exchange */
-	i = dns_lookup(address, T_MX, nscount, nsip, &packet, &a);
-
-	strncpy(temp, address, sizeof(temp));
-
-	if (i >= 0) {
-		i = decode_dotted(packet, a.rdoffset+2, temp, sizeof(temp));
-		free(packet);
-	}
-
-	for (;;) {
-
-		i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a);
-
-		if (i < 0)
-			return -1;
-
-		free(a.dotted);
-
-		if (a.atype == T_CNAME) {		/* CNAME */
-			DPRINTF("Got a CNAME in resolve_mailbox()\n");
-			i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp));
-			free(packet);
-			if (i < 0)
-				return i;
-			if (++nest > MAX_RECURSE)
-				return -1;
-			continue;
-		} else if (a.atype == T_A) {	/* ADDRESS */
-			free(packet);
-			break;
-		} else {
-			free(packet);
-			return -1;
-		}
-	}
-
-	if (in)
-		memcpy(in, a.rdata, INADDRSZ); /* IPv4 */
-
-	return 0;
-}
-#endif
-
-
 #ifdef L_opennameservers
 
 int nameservers;
@@ -948,38 +838,6 @@ void close_nameservers(void)
 }
 #endif
 
-
-#ifdef L_resolvename
-
-const char *resolve_name(const char *name, int mailbox)
-{
-	struct in_addr in;
-	int i;
-
-	/* shortcut: is it a valid IP address to begin with? */
-	if (inet_aton(name, &in))
-		return name;
-
-	open_nameservers();
-
-	DPRINTF("looking up '%s', mailbox=%d, nameservers=%d\n",
-			name, mailbox, nameservers);
-
-	if (mailbox)
-		i = resolve_mailbox(name, nameservers, nameserver, &in);
-	else
-		i = resolve_address(name, nameservers, nameserver, &in);
-
-	if (i < 0)
-		return 0;
-
-	DPRINTF("success = '%s'\n", inet_ntoa(in));
-
-	return inet_ntoa(in);
-}
-#endif
-
-
 #ifdef L_gethostbyname
 
 struct hostent *gethostbyname(const char *name)
@@ -1322,33 +1180,42 @@ int read_etc_hosts_r(FILE * fp, const char * name, int type,
 #endif
 
 
-#ifdef L_endhostent
-extern int __stay_open;
-extern FILE * __gethostent_fp;
+#ifdef L_gethostent
+
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+# define LOCK	pthread_mutex_lock(&mylock)
+# define UNLOCK	pthread_mutex_unlock(&mylock);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+static int __stay_open;
+static FILE * __gethostent_fp;
+
 void endhostent (void)
 {
+    LOCK;
     __stay_open = 0;
     if (__gethostent_fp) {
 	fclose(__gethostent_fp);
     }
+    UNLOCK;
 }
-#endif
 
-#ifdef L_sethostent
-extern int __stay_open;
 void sethostent (int stay_open)
 {
+    LOCK;
     __stay_open = stay_open;
+    UNLOCK;
 }
-#endif
 
-#ifdef L_gethostent
-int __stay_open;
-FILE * __gethostent_fp;
 
 struct hostent *gethostent (void)
 {
-    static struct hostent	h;
+    static struct hostent h;
     static char buf[
 #ifndef __UCLIBC_HAS_IPV6__
 	    sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
@@ -1358,9 +1225,11 @@ struct hostent *gethostent (void)
 	    80/*namebuffer*/ + 2/* margin */];
     struct hostent *host;
 
+    LOCK;
     if (__gethostent_fp == NULL) {
 	__open_etc_hosts(&__gethostent_fp);
 	if (__gethostent_fp == NULL) {
+	    UNLOCK;
 	    return((struct hostent *)NULL);
 	}
     }
@@ -1370,6 +1239,7 @@ struct hostent *gethostent (void)
     if (__stay_open==0) {
 	fclose(__gethostent_fp);
     }
+    UNLOCK;
     return(host);
 }
 #endif