]> Git Repo - uclibc-ng.git/blobdiff - libc/inet/resolv.c
patch #3: make resolv.c use __uc_malloc
[uclibc-ng.git] / libc / inet / resolv.c
index 0b479ee203964cd9e7c059a8a3b4fc8eb87e9b79..5d3e2d871e694957d342153004cac8f482eb3b72 100644 (file)
@@ -7,7 +7,7 @@
  * 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.
-*/
+ */
 
 /*
  * Portions Copyright (c) 1985, 1993
 #define __FORCE_GLIBC
 #include <features.h>
 #include <string.h>
+#include <strings.h>
 #include <stdio.h>
 #include <signal.h>
 #include <errno.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
+#include <malloc.h>
 #include <unistd.h>
 #include <resolv.h>
 #include <netdb.h>
 #include <ctype.h>
+#include <stdbool.h>
 #include <arpa/nameser.h>
 #include <sys/utsname.h>
 #include <sys/un.h>
+#include <bits/uClibc_mutex.h>
+
+__UCLIBC_MUTEX_EXTERN(__resolv_lock);
 
 libc_hidden_proto(memcpy)
 libc_hidden_proto(memset)
@@ -202,10 +208,12 @@ libc_hidden_proto(fprintf)
 libc_hidden_proto(__h_errno_location)
 #ifdef __UCLIBC_HAS_XLOCALE__
 libc_hidden_proto(__ctype_b_loc)
-#else
+#elif __UCLIBC_HAS_CTYPE_TABLES__
 libc_hidden_proto(__ctype_b)
 #endif
 
+
+
 #define MAX_RECURSE 5
 #define REPLY_TIMEOUT 10
 #define MAX_RETRIES 3
@@ -215,7 +223,7 @@ libc_hidden_proto(__ctype_b)
 #define MAX_ALIASES    5
 
 /* 1:ip + 1:full + MAX_ALIASES:aliases + 1:NULL */
-#define        ALIAS_DIM               (2 + MAX_ALIASES + 1)
+#define ALIAS_DIM              (2 + MAX_ALIASES + 1)
 
 #undef DEBUG
 /* #define DEBUG */
@@ -234,12 +242,6 @@ extern int __searchdomains attribute_hidden;
 extern char * __searchdomain[MAX_SEARCH] attribute_hidden;
 
 
-#ifdef __UCLIBC_HAS_THREADS__
-# include <pthread.h>
-extern pthread_mutex_t __resolv_lock;
-#endif
-#define BIGLOCK        __pthread_mutex_lock(&__resolv_lock)
-#define BIGUNLOCK      __pthread_mutex_unlock(&__resolv_lock)
 
 
 
@@ -265,7 +267,7 @@ struct resolv_answer {
        int aclass;
        int ttl;
        int rdlength;
-       unsigned char * rdata;
+       const unsigned char * rdata;
        int rdoffset;
        char* buf;
        size_t buflen;
@@ -300,21 +302,21 @@ extern int __dns_lookup(const char * name, int type, int nscount,
        char ** nsip, unsigned char ** outpacket, struct resolv_answer * a) attribute_hidden;
 
 extern int __encode_dotted(const char * dotted, unsigned char * dest, int maxlen) attribute_hidden;
-extern int __decode_dotted(const unsigned char * message, int offset,
+extern int __decode_dotted(const unsigned char * const message, int offset,
        char * dest, int maxlen) attribute_hidden;
-extern int __length_dotted(const unsigned char * message, int offset) attribute_hidden;
+extern int __length_dotted(const unsigned char * const message, int offset) attribute_hidden;
 extern int __encode_header(struct resolv_header * h, unsigned char * dest, int maxlen) attribute_hidden;
 extern int __decode_header(unsigned char * data, struct resolv_header * h) attribute_hidden;
-extern int __encode_question(struct resolv_question * q,
+extern int __encode_question(const struct resolv_question * const q,
        unsigned char * dest, int maxlen) attribute_hidden;
-extern int __decode_question(unsigned char * message, int offset,
+extern int __decode_question(const unsigned char * const message, int offset,
        struct resolv_question * q) attribute_hidden;
 extern int __encode_answer(struct resolv_answer * a,
        unsigned char * dest, int maxlen) attribute_hidden;
-extern int __decode_answer(unsigned char * message, int offset,
+extern int __decode_answer(const unsigned char * message, int offset,
        struct resolv_answer * a) attribute_hidden;
-extern int __length_question(unsigned char * message, int offset) attribute_hidden;
-extern int __open_nameservers(void) attribute_hidden;
+extern int __length_question(const unsigned char * const message, int offset) attribute_hidden;
+extern void __open_nameservers(void) attribute_hidden;
 extern void __close_nameservers(void) attribute_hidden;
 extern int __dn_expand(const u_char *, const u_char *, const u_char *,
        char *, int);
@@ -373,7 +375,7 @@ int attribute_hidden __decode_header(unsigned char *data, struct resolv_header *
 
 int attribute_hidden __encode_dotted(const char *dotted, unsigned char *dest, int maxlen)
 {
-       int used = 0;
+       unsigned used = 0;
 
        while (dotted && *dotted) {
                char *c = strchr(dotted, '.');
@@ -405,13 +407,13 @@ int attribute_hidden __encode_dotted(const char *dotted, unsigned char *dest, in
 /* Decode a dotted string from nameserver transport-level encoding.
    This routine understands compressed data. */
 
-int attribute_hidden __decode_dotted(const unsigned char *data, int offset,
+int attribute_hidden __decode_dotted(const unsigned char * const data, int offset,
                                  char *dest, int maxlen)
 {
        int l;
-       int measure = 1;
-       int total = 0;
-       int used = 0;
+       bool measure = 1;
+       unsigned total = 0;
+       unsigned used = 0;
 
        if (!data)
                return -1;
@@ -455,7 +457,7 @@ int attribute_hidden __decode_dotted(const unsigned char *data, int offset,
 #endif
 
 #ifdef L_lengthd
-int attribute_hidden __length_dotted(const unsigned char *data, int offset)
+int attribute_hidden __length_dotted(const unsigned char * const data, int offset)
 {
        int orig_offset = offset;
        int l;
@@ -478,7 +480,7 @@ int attribute_hidden __length_dotted(const unsigned char *data, int offset)
 #endif
 
 #ifdef L_encodeq
-int attribute_hidden __encode_question(struct resolv_question *q,
+int attribute_hidden __encode_question(const struct resolv_question * const q,
                                        unsigned char *dest, int maxlen)
 {
        int i;
@@ -503,7 +505,7 @@ int attribute_hidden __encode_question(struct resolv_question *q,
 #endif
 
 #ifdef L_decodeq
-int attribute_hidden __decode_question(unsigned char *message, int offset,
+int attribute_hidden __decode_question(const unsigned char * const message, int offset,
                                        struct resolv_question *q)
 {
        char temp[256];
@@ -524,7 +526,7 @@ int attribute_hidden __decode_question(unsigned char *message, int offset,
 #endif
 
 #ifdef L_lengthq
-int attribute_hidden __length_question(unsigned char *message, int offset)
+int attribute_hidden __length_question(const unsigned char * const message, int offset)
 {
        int i;
 
@@ -568,7 +570,7 @@ int attribute_hidden __encode_answer(struct resolv_answer *a, unsigned char *des
 #endif
 
 #ifdef L_decodea
-int attribute_hidden __decode_answer(unsigned char *message, int offset,
+int attribute_hidden __decode_answer(const unsigned char *message, int offset,
                                  struct resolv_answer *a)
 {
        char temp[256];
@@ -600,15 +602,21 @@ int attribute_hidden __decode_answer(unsigned char *message, int offset,
 #endif
 
 #ifdef L_encodep
-int attribute_hidden __encode_packet(struct resolv_header *h,
+int __encode_packet(struct resolv_header *h,
        struct resolv_question **q,
        struct resolv_answer **an,
        struct resolv_answer **ns,
        struct resolv_answer **ar,
-       unsigned char *dest, int maxlen)
+       unsigned char *dest, int maxlen) attribute_hidden;
+int __encode_packet(struct resolv_header *h,
+                                       struct resolv_question **q,
+                                       struct resolv_answer **an,
+                                       struct resolv_answer **ns,
+                                       struct resolv_answer **ar,
+                                       unsigned char *dest, int maxlen)
 {
        int i, total = 0;
-       int j;
+       unsigned j;
 
        i = __encode_header(h, dest, maxlen);
        if (i < 0)
@@ -657,15 +665,17 @@ int attribute_hidden __encode_packet(struct resolv_header *h,
 #endif
 
 #ifdef L_decodep
-int attribute_hidden __decode_packet(unsigned char *data, struct resolv_header *h)
+int __decode_packet(unsigned char *data, struct resolv_header *h) attribute_hidden;
+int __decode_packet(unsigned char *data, struct resolv_header *h)
 {
        return __decode_header(data, h);
 }
 #endif
 
 #ifdef L_formquery
+int __form_query(int id, const char *name, int type, unsigned char *packet, int maxlen);
 int __form_query(int id, const char *name, int type, unsigned char *packet,
-                          int maxlen)
+                                int maxlen)
 {
        struct resolv_header h;
        struct resolv_question q;
@@ -691,16 +701,8 @@ int __form_query(int id, const char *name, int type, unsigned char *packet,
 }
 #endif
 
-#if defined(L_dnslookup) || defined(L_gethostent)
-#ifdef __UCLIBC_HAS_THREADS__
-# include <pthread.h>
-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
-#endif
-#define LOCK   __pthread_mutex_lock(&mylock)
-#define UNLOCK __pthread_mutex_unlock(&mylock)
-#endif
-
 #ifdef L_dnslookup
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
 
 /* Just for the record, having to lock __dns_lookup() just for these two globals
  * is pretty lame.  I think these two variables can probably be de-global-ized,
@@ -717,15 +719,15 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char
        struct resolv_header h;
        struct resolv_question q;
        struct resolv_answer ma;
-       int first_answer = 1;
-       int retries = 0;
+       bool first_answer = 1;
+       unsigned retries = 0;
        unsigned char * packet = malloc(PACKETSZ);
        char *dns, *lookup = malloc(MAXDNAME);
        int variant = -1;
        struct sockaddr_in sa;
        int local_ns = -1, local_id = -1;
 #ifdef __UCLIBC_HAS_IPV6__
-       int v6;
+       bool v6;
        struct sockaddr_in6 sa6;
 #endif
 
@@ -737,10 +739,10 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char
        DPRINTF("Looking up type %d answer for '%s'\n", type, name);
 
        /* Mess with globals while under lock */
-       LOCK;
+       __UCLIBC_MUTEX_LOCK(mylock);
        local_ns = ns % nscount;
        local_id = id;
-       UNLOCK;
+       __UCLIBC_MUTEX_UNLOCK(mylock);
 
        while (retries < MAX_RETRIES) {
                if (fd != -1)
@@ -753,7 +755,11 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char
                ++local_id;
                local_id &= 0xffff;
                h.id = local_id;
+               __UCLIBC_MUTEX_LOCK(__resolv_lock);
+               /* this is really __nameserver[] which is a global that
+                  needs to hold __resolv_lock before access!! */
                dns = nsip[local_ns];
+               __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
 
                h.qdcount = 1;
                h.rd = 1;
@@ -766,13 +772,13 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char
 
                strncpy(lookup,name,MAXDNAME);
                if (variant >= 0) {
-                        BIGLOCK;
-                        if (variant < __searchdomains) {
-                                strncat(lookup,".", MAXDNAME);
-                                strncat(lookup,__searchdomain[variant], MAXDNAME);
-                        }
-                        BIGUNLOCK;
-                }
+                       __UCLIBC_MUTEX_LOCK(__resolv_lock);
+                       if (variant < __searchdomains) {
+                               strncat(lookup,".", MAXDNAME);
+                               strncat(lookup,__searchdomain[variant], MAXDNAME);
+                       }
+                       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+               }
                DPRINTF("lookup name: %s\n", lookup);
                q.dotted = (char *)lookup;
                q.qtype = type;
@@ -788,13 +794,17 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char
                                retries+1, NAMESERVER_PORT, dns);
 
 #ifdef __UCLIBC_HAS_IPV6__
+               __UCLIBC_MUTEX_LOCK(__resolv_lock);
+               /* 'dns' is really __nameserver[] which is a global that
+                  needs to hold __resolv_lock before access!! */
                v6 = inet_pton(AF_INET6, dns, &sa6.sin6_addr) > 0;
+               __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
                fd = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 #else
                fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 #endif
                if (fd < 0) {
-                    retries++;
+                       retries++;
                    continue;
                }
 
@@ -809,18 +819,22 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char
 #endif
                    sa.sin_family = AF_INET;
                    sa.sin_port = htons(NAMESERVER_PORT);
+                   __UCLIBC_MUTEX_LOCK(__resolv_lock);
+                   /* 'dns' is really __nameserver[] which is a global that
+                      needs to hold __resolv_lock before access!! */
                    sa.sin_addr.s_addr = inet_addr(dns);
+                   __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
                    rc = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
 #ifdef __UCLIBC_HAS_IPV6__
                }
 #endif
                if (rc < 0) {
                    if (errno == ENETUNREACH) {
-                       /* routing error, presume not transient */
-                       goto tryall;
+                               /* routing error, presume not transient */
+                               goto tryall;
                    } else
-                       /* retry */
-                        retries++;
+                               /* retry */
+                               retries++;
                        continue;
                }
 
@@ -882,55 +896,55 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char
 
                first_answer = 1;
                for (j=0;j<h.ancount;j++,pos += i)
-               {
-                   i = __decode_answer(packet, pos, &ma);
+                       {
+                               i = __decode_answer(packet, pos, &ma);
 
-                   if (i<0) {
-                       DPRINTF("failed decode %d\n", i);
-                       goto again;
-                   }
+                               if (i<0) {
+                                       DPRINTF("failed decode %d\n", i);
+                                       goto again;
+                               }
 
-                   if ( first_answer )
-                   {
-                       ma.buf = a->buf;
-                       ma.buflen = a->buflen;
-                       ma.add_count = a->add_count;
-                       memcpy(a, &ma, sizeof(ma));
-                       if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA)))
-                       {
-                           break;
-                       }
-                       if (a->atype != type)
-                       {
-                           free(a->dotted);
-                           continue;
-                       }
-                       a->add_count = h.ancount - j - 1;
-                       if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
-                       {
-                           break;
-                       }
-                       a->add_count = 0;
-                       first_answer = 0;
-                   }
-                   else
-                   {
-                       free(ma.dotted);
-                       if (ma.atype != type)
-                       {
-                           continue;
-                       }
-                       if (a->rdlength != ma.rdlength)
-                       {
-                           free(a->dotted);
-                           DPRINTF("Answer address len(%u) differs from original(%u)\n",
-                                   ma.rdlength, a->rdlength);
-                           goto again;
+                               if ( first_answer )
+                                       {
+                                               ma.buf = a->buf;
+                                               ma.buflen = a->buflen;
+                                               ma.add_count = a->add_count;
+                                               memcpy(a, &ma, sizeof(ma));
+                                               if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA)))
+                                                       {
+                                                               break;
+                                                       }
+                                               if (a->atype != type)
+                                                       {
+                                                               free(a->dotted);
+                                                               continue;
+                                                       }
+                                               a->add_count = h.ancount - j - 1;
+                                               if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
+                                                       {
+                                                               break;
+                                                       }
+                                               a->add_count = 0;
+                                               first_answer = 0;
+                                       }
+                               else
+                                       {
+                                               free(ma.dotted);
+                                               if (ma.atype != type)
+                                                       {
+                                                               continue;
+                                                       }
+                                               if (a->rdlength != ma.rdlength)
+                                                       {
+                                                               free(a->dotted);
+                                                               DPRINTF("Answer address len(%u) differs from original(%u)\n",
+                                                                               ma.rdlength, a->rdlength);
+                                                               goto again;
+                                                       }
+                                               memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
+                                               ++a->add_count;
+                                       }
                        }
-                       memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
-                       ++a->add_count;
-                   }
-               }
 
                DPRINTF("Answer name = |%s|\n", a->dotted);
                DPRINTF("Answer type = |%d|\n", a->atype);
@@ -944,48 +958,48 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char
                free(lookup);
 
                /* Mess with globals while under lock */
-               LOCK;
+               __UCLIBC_MUTEX_LOCK(mylock);
                ns = local_ns;
                id = local_id;
-               UNLOCK;
+               __UCLIBC_MUTEX_UNLOCK(mylock);
 
                return (len);                           /* success! */
 
-         tryall:
+       tryall:
                /* if there are other nameservers, give them a go,
                   otherwise return with error */
                {
                    variant = -1;
-                    local_ns = (local_ns + 1) % nscount;
-                    if (local_ns == 0)
-                      retries++;
+                       local_ns = (local_ns + 1) % nscount;
+                       if (local_ns == 0)
+                               retries++;
 
-                    continue;
+                       continue;
                }
 
-         again:
+       again:
                /* if there are searchdomains, try them or fallback as passed */
                {
                    int sdomains;
-                   BIGLOCK;
+                   __UCLIBC_MUTEX_LOCK(__resolv_lock);
                    sdomains=__searchdomains;
-                   BIGUNLOCK;
+                   __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
 
                    if (variant < sdomains - 1) {
-                       /* next search */
-                       variant++;
+                               /* next search */
+                               variant++;
                    } else {
-                       /* next server, first search */
-                       local_ns = (local_ns + 1) % nscount;
-                        if (local_ns == 0)
-                          retries++;
+                               /* next server, first search */
+                               local_ns = (local_ns + 1) % nscount;
+                               if (local_ns == 0)
+                                       retries++;
 
-                       variant = -1;
+                               variant = -1;
                    }
                }
        }
 
-fail:
+ fail:
        if (fd != -1)
            close(fd);
        if (lookup)
@@ -995,10 +1009,10 @@ fail:
        h_errno = NETDB_INTERNAL;
        /* Mess with globals while under lock */
        if (local_ns != -1) {
-           LOCK;
+           __UCLIBC_MUTEX_LOCK(mylock);
            ns = local_ns;
            id = local_id;
-           UNLOCK;
+           __UCLIBC_MUTEX_UNLOCK(mylock);
        }
        return -1;
 }
@@ -1006,81 +1020,84 @@ fail:
 
 #ifdef L_opennameservers
 
+/* We use __resolv_lock to guard access to the
+ * '__nameservers' and __searchdomains globals */
 int __nameservers;
 char * __nameserver[MAX_SERVERS];
 int __searchdomains;
 char * __searchdomain[MAX_SEARCH];
-#ifdef __UCLIBC_HAS_THREADS__
-# include <pthread.h>
-pthread_mutex_t __resolv_lock = PTHREAD_MUTEX_INITIALIZER;
-#endif
+
+__UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
 
 /*
  *     we currently read formats not quite the same as that on normal
  *     unix systems, we can have a list of nameservers after the keyword.
  */
 
-int attribute_hidden __open_nameservers()
+void attribute_hidden __open_nameservers()
 {
        FILE *fp;
        int i;
 #define RESOLV_ARGS 5
        char szBuffer[128], *p, *argv[RESOLV_ARGS];
        int argc;
+       /* int rv = 0; */
 
-       BIGLOCK;
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);
        if (__nameservers > 0) {
-           BIGUNLOCK;
-           return 0;
+               goto DONE;
        }
 
        if ((fp = fopen("/etc/resolv.conf", "r")) ||
-                       (fp = fopen("/etc/config/resolv.conf", "r")))
-       {
-
-               while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
-
-                       for (p = szBuffer; *p && isspace(*p); p++)
-                               /* skip white space */;
-                       if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */
-                               continue;
-                       argc = 0;
-                       while (*p && argc < RESOLV_ARGS) {
-                               argv[argc++] = p;
-                               while (*p && !isspace(*p) && *p != '\n')
-                                       p++;
-                               while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */
-                                       *p++ = '\0';
-                       }
+               (fp = fopen("/etc/config/resolv.conf", "r")))
+               {
 
-                       if (strcmp(argv[0], "nameserver") == 0) {
-                               for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) {
-                                       __nameserver[__nameservers++] = strdup(argv[i]);
-                                       DPRINTF("adding nameserver %s\n", argv[i]);
+                       while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
+
+                               for (p = szBuffer; *p && isspace(*p); p++)
+                                       /* skip white space */;
+                               if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */
+                                       continue;
+                               argc = 0;
+                               while (*p && argc < RESOLV_ARGS) {
+                                       argv[argc++] = p;
+                                       while (*p && !isspace(*p) && *p != '\n')
+                                               p++;
+                                       while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */
+                                               *p++ = '\0';
                                }
-                       }
 
-                       /* domain and search are mutually exclusive, the last one wins */
-                       if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) {
-                               while (__searchdomains > 0) {
-                                       free(__searchdomain[--__searchdomains]);
-                                       __searchdomain[__searchdomains] = NULL;
+                               if (strcmp(argv[0], "nameserver") == 0) {
+                                       for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) {
+                                               __nameserver[__nameservers++] = strdup(argv[i]);
+                                               DPRINTF("adding nameserver %s\n", argv[i]);
+                                       }
                                }
-                               for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) {
-                                       __searchdomain[__searchdomains++] = strdup(argv[i]);
-                                       DPRINTF("adding search %s\n", argv[i]);
+
+                               /* domain and search are mutually exclusive, the last one wins */
+                               if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) {
+                                       while (__searchdomains > 0) {
+                                               free(__searchdomain[--__searchdomains]);
+                                               __searchdomain[__searchdomains] = NULL;
+                                       }
+                                       for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) {
+                                               __searchdomain[__searchdomains++] = strdup(argv[i]);
+                                               DPRINTF("adding search %s\n", argv[i]);
+                                       }
                                }
                        }
+                       fclose(fp);
+                       DPRINTF("nameservers = %d\n", __nameservers);
+                       goto DONE;
                }
-               fclose(fp);
-               DPRINTF("nameservers = %d\n", __nameservers);
-               BIGUNLOCK;
-               return 0;
-       }
        DPRINTF("failed to open %s\n", "resolv.conf");
        h_errno = NO_RECOVERY;
-       BIGUNLOCK;
-       return -1;
+
+       /* rv = -1; */
+
+ DONE:
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+       /* return rv; */
 }
 #endif
 
@@ -1089,7 +1106,7 @@ int attribute_hidden __open_nameservers()
 
 void attribute_hidden __close_nameservers(void)
 {
-       BIGLOCK;
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);
        while (__nameservers > 0) {
                free(__nameserver[--__nameservers]);
                __nameserver[__nameservers] = NULL;
@@ -1098,7 +1115,7 @@ void attribute_hidden __close_nameservers(void)
                free(__searchdomain[--__searchdomains]);
                __searchdomain[__searchdomains] = NULL;
        }
-       BIGUNLOCK;
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
 }
 #endif
 
@@ -1106,13 +1123,17 @@ void attribute_hidden __close_nameservers(void)
 
 struct hostent *gethostbyname(const char *name)
 {
-       static struct hostent h;
-       static char buf[sizeof(struct in_addr) +
-                       sizeof(struct in_addr *)*2 +
-                       sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+       static struct {
+               struct hostent h;
+               char buf[sizeof(struct in_addr) +
+                                       sizeof(struct in_addr *)*2 +
+                                       sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+       } *sp;
        struct hostent *hp;
 
-       gethostbyname_r(name, &h, buf, sizeof(buf), &hp, &h_errno);
+       free(sp);
+       sp = __uc_malloc(sizeof(*sp));
+       gethostbyname_r(name, &sp->h, sp->buf, sizeof(sp->buf), &hp, &h_errno);
 
        return hp;
 }
@@ -1126,13 +1147,17 @@ struct hostent *gethostbyname2(const char *name, int family)
 #ifndef __UCLIBC_HAS_IPV6__
        return family == AF_INET ? gethostbyname(name) : (struct hostent*)0;
 #else /* __UCLIBC_HAS_IPV6__ */
-       static struct hostent h;
-       static char buf[sizeof(struct in6_addr) +
-                       sizeof(struct in6_addr *)*2 +
-                       sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+       static struct {
+               struct hostent h;
+               char buf[sizeof(struct in6_addr) +
+                                       sizeof(struct in6_addr *)*2 +
+                                       sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+       } *sp;
        struct hostent *hp;
 
-       gethostbyname2_r(name, family, &h, buf, sizeof(buf), &hp, &h_errno);
+       free(sp);
+       sp = __uc_malloc(sizeof(*sp));
+       gethostbyname2_r(name, family, &sp->h, sp->buf, sizeof(sp->buf), &hp, &h_errno);
 
        return hp;
 #endif /* __UCLIBC_HAS_IPV6__ */
@@ -1142,12 +1167,14 @@ struct hostent *gethostbyname2(const char *name, int family)
 
 
 #ifdef L_res_init
+/* We use __resolv_lock to guard access to global '_res' */
 struct __res_state _res;
 
 int res_init(void)
 {
        struct __res_state *rp = &(_res);
 
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);     /* must be a recursive lock! */
        __close_nameservers();
        __open_nameservers();
        rp->retrans = RES_TIMEOUT;
@@ -1165,7 +1192,6 @@ int res_init(void)
        /** rp->rhook = NULL; **/
        /** rp->_u._ext.nsinit = 0; **/
 
-       BIGLOCK;
        if(__searchdomains) {
                int i;
                for(i=0; i<__searchdomains; i++) {
@@ -1185,16 +1211,19 @@ int res_init(void)
                }
        }
        rp->nscount = __nameservers;
-       BIGUNLOCK;
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
 
        return(0);
 }
 libc_hidden_def(res_init)
 
+#ifdef __UCLIBC_HAS_BSD_RES_CLOSE__
 void res_close( void )
 {
-       return;
+       __close_nameservers();
+       memset(&_res, 0, sizeof(_res));
 }
+#endif
 
 #endif
 
@@ -1222,10 +1251,10 @@ int res_query(const char *dname, int class, int type,
 
        memset((char *) &a, '\0', sizeof(a));
 
-       BIGLOCK;
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);
        __nameserversXX=__nameservers;
        __nameserverXX=__nameserver;
-       BIGUNLOCK;
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
        i = __dns_lookup(dname, type, __nameserversXX, __nameserverXX, &packet, &a);
 
        if (i < 0) {
@@ -1254,19 +1283,29 @@ libc_hidden_def(res_query)
  * If enabled, implement search rules until answer or unrecoverable failure
  * is detected.  Error code, if any, is left in h_errno.
  */
+#define __TRAILING_DOT (1<<0)
+#define __GOT_NODATA   (1<<1)
+#define __GOT_SERVFAIL (1<<2)
+#define __TRIED_AS_IS  (1<<3)
 int res_search(name, class, type, answer, anslen)
-       const char *name;       /* domain name */
-       int class, type;        /* class and type of query */
-       u_char *answer;         /* buffer to put answer */
-       int anslen;             /* size of answer */
+        const char *name;      /* domain name */
+        int class, type;       /* class and type of query */
+        u_char *answer;                /* buffer to put answer */
+        int anslen;            /* size of answer */
 {
        const char *cp, * const *domain;
        HEADER *hp = (HEADER *)(void *)answer;
        u_int dots;
-       int trailing_dot, ret, saved_herrno;
-       int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
-
-       if ((!name || !answer) || ((_res.options & RES_INIT) == 0 && res_init() == -1)) {
+       unsigned _state = 0;
+       int ret, saved_herrno;
+       u_long _res_options;
+       unsigned _res_ndots;
+       char **_res_dnsrch;
+
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       _res_options = _res.options;
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+       if ((!name || !answer) || ((_res_options & RES_INIT) == 0 && res_init() == -1)) {
                h_errno = NETDB_INTERNAL;
                return (-1);
        }
@@ -1276,21 +1315,24 @@ int res_search(name, class, type, answer, anslen)
        dots = 0;
        for (cp = name; *cp; cp++)
                dots += (*cp == '.');
-       trailing_dot = 0;
+
        if (cp > name && *--cp == '.')
-               trailing_dot++;
+               _state |= __TRAILING_DOT;
 
        /*
         * If there are dots in the name already, let's just give it a try
         * 'as is'.  The threshold can be set with the "ndots" option.
         */
        saved_herrno = -1;
-       if (dots >= _res.ndots) {
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       _res_ndots = _res.ndots;
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+       if (dots >= _res_ndots) {
                ret = res_querydomain(name, NULL, class, type, answer, anslen);
                if (ret > 0)
                        return (ret);
                saved_herrno = h_errno;
-               tried_as_is++;
+               _state |= __TRIED_AS_IS;
        }
 
        /*
@@ -1299,16 +1341,20 @@ int res_search(name, class, type, answer, anslen)
         *      - there is at least one dot, there is no trailing dot,
         *        and RES_DNSRCH is set.
         */
-       if ((!dots && (_res.options & RES_DEFNAMES)) ||
-           (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
-               int done = 0;
-
-               for (domain = (const char * const *)_res.dnsrch;
-                  *domain && !done;
-                  domain++) {
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       _res_options = _res.options;
+       _res_dnsrch = _res.dnsrch;
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+       if ((!dots && (_res_options & RES_DEFNAMES)) ||
+           (dots && !(_state & __TRAILING_DOT) && (_res_options & RES_DNSRCH))) {
+               bool done = 0;
+
+               for (domain = (const char * const *)_res_dnsrch;
+                        *domain && !done;
+                        domain++) {
 
                        ret = res_querydomain(name, *domain, class, type,
-                           answer, anslen);
+                                                                 answer, anslen);
                        if (ret > 0)
                                return (ret);
 
@@ -1331,29 +1377,32 @@ int res_search(name, class, type, answer, anslen)
                        }
 
                        switch (h_errno) {
-                       case NO_DATA:
-                               got_nodata++;
-                               /* FALLTHROUGH */
-                       case HOST_NOT_FOUND:
-                               /* keep trying */
-                               break;
-                       case TRY_AGAIN:
-                               if (hp->rcode == SERVFAIL) {
-                                       /* try next search element, if any */
-                                       got_servfail++;
+                               case NO_DATA:
+                                       _state |= __GOT_NODATA;
+                                       /* FALLTHROUGH */
+                               case HOST_NOT_FOUND:
+                                       /* keep trying */
                                        break;
-                               }
-                               /* FALLTHROUGH */
-                       default:
-                               /* anything else implies that we're done */
-                               done++;
+                               case TRY_AGAIN:
+                                       if (hp->rcode == SERVFAIL) {
+                                               /* try next search element, if any */
+                                               _state |= __GOT_SERVFAIL;
+                                               break;
+                                       }
+                                       /* FALLTHROUGH */
+                               default:
+                                       /* anything else implies that we're done */
+                                       done = 1;
                        }
                        /*
                         * if we got here for some reason other than DNSRCH,
                         * we only wanted one iteration of the loop, so stop.
                         */
-                       if (!(_res.options & RES_DNSRCH))
-                               done++;
+                       __UCLIBC_MUTEX_LOCK(__resolv_lock);
+                       _res_options = _res.options;
+                       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+                       if (!(_res_options & RES_DNSRCH))
+                               done = 1;
                }
        }
 
@@ -1362,7 +1411,7 @@ int res_search(name, class, type, answer, anslen)
         * note that we do this regardless of how many dots were in the
         * name or whether it ends with a dot.
         */
-       if (!tried_as_is) {
+       if (!(_state & __TRIED_AS_IS)) {
                ret = res_querydomain(name, NULL, class, type, answer, anslen);
                if (ret > 0)
                        return (ret);
@@ -1378,36 +1427,46 @@ int res_search(name, class, type, answer, anslen)
         */
        if (saved_herrno != -1)
                h_errno = saved_herrno;
-       else if (got_nodata)
+       else if (_state & __GOT_NODATA)
                h_errno = NO_DATA;
-       else if (got_servfail)
+       else if (_state & __GOT_SERVFAIL)
                h_errno = TRY_AGAIN;
        return (-1);
 }
-
+#undef __TRAILING_DOT
+#undef __GOT_NODATA
+#undef __GOT_SERVFAIL
+#undef __TRIED_AS_IS
 /*
  * Perform a call on res_query on the concatenation of name and domain,
  * removing a trailing dot from name if domain is NULL.
  */
 int res_querydomain(name, domain, class, type, answer, anslen)
-       const char *name, *domain;
-       int class, type;        /* class and type of query */
-       u_char *answer;         /* buffer to put answer */
-       int anslen;             /* size of answer */
+        const char *name, *domain;
+        int class, type;       /* class and type of query */
+        u_char *answer;                /* buffer to put answer */
+        int anslen;            /* size of answer */
 {
        char nbuf[MAXDNAME];
        const char *longname = nbuf;
        size_t n, d;
+       u_long _res_options;
 
-       if ((!name || !answer) || ((_res.options & RES_INIT) == 0 && res_init() == -1)) {
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       _res_options = _res.options;
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+       if ((!name || !answer) || ((_res_options & RES_INIT) == 0 && res_init() == -1)) {
                h_errno = NETDB_INTERNAL;
                return (-1);
        }
 
 #ifdef DEBUG
-       if (_res.options & RES_DEBUG)
+       __UCLIBC_MUTEX_LOCK(__resolv_lock);
+       _res_options = _res.options;
+       __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
+       if (_res_options & RES_DEBUG)
                printf(";; res_querydomain(%s, %s, %d, %d)\n",
-                       name, domain?domain:"<Nil>", class, type);
+                          name, domain?domain:"<Nil>", class, type);
 #endif
        if (domain == NULL) {
                /*
@@ -1446,17 +1505,21 @@ libc_hidden_def(res_querydomain)
 #ifdef L_gethostbyaddr
 struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type)
 {
-       static struct hostent h;
-       static char buf[
+       static struct {
+               struct hostent h;
+               char buf[
 #ifndef __UCLIBC_HAS_IPV6__
-               sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
+                                       sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
 #else
-               sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
+                                       sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
 #endif /* __UCLIBC_HAS_IPV6__ */
-               sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+                                       sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */];
+       } *sp;
        struct hostent *hp;
 
-       gethostbyaddr_r(addr, len, type, &h, buf, sizeof(buf), &hp, &h_errno);
+       free(sp);
+       sp = __uc_malloc(sizeof(*sp));
+       gethostbyaddr_r(addr, len, type, &sp->h, sp->buf, sizeof(sp->buf), &hp, &h_errno);
 
        return hp;
 }
@@ -1625,25 +1688,26 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type,
 
 
 #ifdef L_gethostent
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
 
 static int __stay_open;
 static FILE * __gethostent_fp;
 
 void endhostent (void)
 {
-    LOCK;
+    __UCLIBC_MUTEX_LOCK(mylock);
     __stay_open = 0;
     if (__gethostent_fp) {
        fclose(__gethostent_fp);
     }
-    UNLOCK;
+    __UCLIBC_MUTEX_UNLOCK(mylock);
 }
 
 void sethostent (int stay_open)
 {
-    LOCK;
+    __UCLIBC_MUTEX_LOCK(mylock);
     __stay_open = stay_open;
-    UNLOCK;
+    __UCLIBC_MUTEX_UNLOCK(mylock);
 }
 
 int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen,
@@ -1651,42 +1715,47 @@ int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen,
 {
     int ret;
 
-    LOCK;
+    __UCLIBC_MUTEX_LOCK(mylock);
     if (__gethostent_fp == NULL) {
        __open_etc_hosts(&__gethostent_fp);
        if (__gethostent_fp == NULL) {
-           UNLOCK;
-           *result=NULL;
-           return 0;
+           *result = NULL;
+           ret = TRY_AGAIN;
+           goto DONE;
        }
     }
 
     ret = __read_etc_hosts_r(__gethostent_fp, NULL, AF_INET, GETHOSTENT,
                   result_buf, buf, buflen, result, h_errnop);
-    if (__stay_open==0) {
+    if (__stay_open == 0) {
        fclose(__gethostent_fp);
     }
-    UNLOCK;
+DONE:
+    __UCLIBC_MUTEX_UNLOCK(mylock);
     return(ret);
 }
 libc_hidden_def(gethostent_r)
 
 struct hostent *gethostent (void)
 {
-    static struct hostent h;
-    static char buf[
+    static struct {
+       struct hostent h;
+       char buf[
 #ifndef __UCLIBC_HAS_IPV6__
-           sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
+                                       sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
 #else
-           sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
+                                       sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
 #endif /* __UCLIBC_HAS_IPV6__ */
-               sizeof(char *)*(ALIAS_DIM) +
-           80/*namebuffer*/ + 2/* margin */];
+                                       sizeof(char *)*(ALIAS_DIM) +
+                                       80/*namebuffer*/ + 2/* margin */];
+    } *sp;
     struct hostent *host;
 
-    LOCK;
-    gethostent_r(&h, buf, sizeof(buf), &host, &h_errno);
-    UNLOCK;
+    free(sp);
+    sp = __uc_malloc(sizeof(*sp));
+    __UCLIBC_MUTEX_LOCK(mylock);
+    gethostent_r(&sp->h, sp->buf, sizeof(sp->buf), &host, &h_errno);
+    __UCLIBC_MUTEX_UNLOCK(mylock);
     return(host);
 }
 #endif
@@ -1719,24 +1788,24 @@ int attribute_hidden __get_hosts_byaddr_r(const char * addr, int len, int type,
 #endif /* __UCLIBC_HAS_IPV6__ */
 
     switch (type) {
-       case AF_INET:
-               if (len != sizeof(struct in_addr))
-                       return 0;
-               break;
+               case AF_INET:
+                       if (len != sizeof(struct in_addr))
+                               return 0;
+                       break;
 #ifdef __UCLIBC_HAS_IPV6__
-       case AF_INET6:
-               if (len != sizeof(struct in6_addr))
-                       return 0;
-               break;
+               case AF_INET6:
+                       if (len != sizeof(struct in6_addr))
+                               return 0;
+                       break;
 #endif /* __UCLIBC_HAS_IPV6__ */
-       default:
-               return 0;
+               default:
+                       return 0;
        }
 
        inet_ntop(type, addr, ipaddr, sizeof(ipaddr));
 
        return(__read_etc_hosts_r(NULL, ipaddr, type, GET_HOSTS_BYADDR,
-                   result_buf, buf, buflen, result, h_errnop));
+                                                         result_buf, buf, buflen, result, h_errnop));
 }
 #endif
 
@@ -1748,11 +1817,11 @@ int attribute_hidden __get_hosts_byaddr_r(const char * addr, int len, int type,
 
 libc_hidden_proto(getnameinfo)
 int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
-            socklen_t hostlen, char *serv, socklen_t servlen,
-            unsigned int flags)
+                                socklen_t hostlen, char *serv, socklen_t servlen,
+                                unsigned int flags)
 {
        int serrno = errno;
-       int ok = 0;
+       unsigned ok;
        struct hostent *h = NULL;
        char domain[256];
 
@@ -1760,25 +1829,23 @@ int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
                return EAI_BADFLAGS;
 
        if (sa == NULL || addrlen < sizeof (sa_family_t))
-               return EAI_FAMILY;
+               goto BAD_FAM;
 
-       switch (sa->sa_family) {
-       case AF_LOCAL:
-               break;
-       case AF_INET:
+       ok = sa->sa_family;
+       if (ok == AF_LOCAL) /* valid */;
+       else if (ok == AF_INET) {
                if (addrlen < sizeof (struct sockaddr_in))
-                       return EAI_FAMILY;
-               break;
+                       goto BAD_FAM;
 #ifdef __UCLIBC_HAS_IPV6__
-       case AF_INET6:
+       } else if (ok == AF_INET6) {
                if (addrlen < sizeof (struct sockaddr_in6))
-                       return EAI_FAMILY;
-               break;
+                       goto BAD_FAM;
 #endif /* __UCLIBC_HAS_IPV6__ */
-       default:
+       } else
+BAD_FAM:
                return EAI_FAMILY;
-       }
 
+       ok = 0;
        if (host != NULL && hostlen > 0)
                switch (sa->sa_family) {
                case AF_INET:
@@ -1898,34 +1965,29 @@ int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
                        strncpy (host, "localhost", hostlen);
                        break;
 
-               default:
+/*Already checked above                default:
                        return EAI_FAMILY;
+*/
        }
 
        if (serv && (servlen > 0)) {
-               switch (sa->sa_family) {
-               case AF_INET:
-#ifdef __UCLIBC_HAS_IPV6__
-               case AF_INET6:
-#endif /* __UCLIBC_HAS_IPV6__ */
+               if (sa->sa_family == AF_LOCAL) {
+                       strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
+               } else { /* AF_INET || AF_INET6 */
                        if (!(flags & NI_NUMERICSERV)) {
                                struct servent *s;
                                s = getservbyport (((const struct sockaddr_in *) sa)->sin_port,
                                      ((flags & NI_DGRAM) ? "udp" : "tcp"));
                                if (s) {
                                        strncpy (serv, s->s_name, servlen);
-                                       break;
+                                       goto DONE;
                                }
                        }
                        snprintf (serv, servlen, "%d",
                                ntohs (((const struct sockaddr_in *) sa)->sin_port));
-                       break;
-
-               case AF_LOCAL:
-                       strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
-                       break;
                }
        }
+DONE:
        if (host && (hostlen > 0))
                host[hostlen-1] = 0;
        if (serv && (servlen > 0))
@@ -1940,10 +2002,10 @@ libc_hidden_def(getnameinfo)
 #ifdef L_gethostbyname_r
 
 int gethostbyname_r(const char * name,
-                           struct hostent * result_buf,
-                           char * buf, size_t buflen,
-                           struct hostent ** result,
-                           int * h_errnop)
+                                       struct hostent * result_buf,
+                                       char * buf, size_t buflen,
+                                       struct hostent ** result,
+                                       int * h_errnop)
 {
        struct in_addr *in;
        struct in_addr **addr_list;
@@ -1965,7 +2027,7 @@ int gethostbyname_r(const char * name,
                __set_errno(0);                 /* to check for missing /etc/hosts. */
 
                if ((i=__get_hosts_byname_r(name, AF_INET, result_buf,
-                               buf, buflen, result, h_errnop))==0)
+                                                                       buf, buflen, result, h_errnop))==0)
                        return i;
                switch (*h_errnop) {
                        case HOST_NOT_FOUND:
@@ -2027,60 +2089,60 @@ int gethostbyname_r(const char * name,
 
        for (;;) {
 
-           BIGLOCK;
+           __UCLIBC_MUTEX_LOCK(__resolv_lock);
            __nameserversXX=__nameservers;
            __nameserverXX=__nameserver;
-           BIGUNLOCK;
+           __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
            a.buf = buf;
            a.buflen = buflen;
            a.add_count = 0;
            i = __dns_lookup(name, T_A, __nameserversXX, __nameserverXX, &packet, &a);
 
            if (i < 0) {
-               *h_errnop = HOST_NOT_FOUND;
-               DPRINTF("__dns_lookup\n");
-               return TRY_AGAIN;
+                       *h_errnop = HOST_NOT_FOUND;
+                       DPRINTF("__dns_lookup\n");
+                       return TRY_AGAIN;
            }
 
            if ((a.rdlength + sizeof(struct in_addr*)) * a.add_count + 256 > buflen)
-           {
-               free(a.dotted);
-               free(packet);
-               *h_errnop = NETDB_INTERNAL;
-               DPRINTF("buffer too small for all addresses\n");
-               return ERANGE;
-           }
+                       {
+                               free(a.dotted);
+                               free(packet);
+                               *h_errnop = NETDB_INTERNAL;
+                               DPRINTF("buffer too small for all addresses\n");
+                               return ERANGE;
+                       }
            else if(a.add_count > 0)
-           {
-               memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength);
-               addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength);
-               addr_list[0] = in;
-               for (i = a.add_count-1; i>=0; --i)
-                   addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i);
-               addr_list[a.add_count + 1] = 0;
-               buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf);
-               buf = (char*)&addr_list[a.add_count + 2];
-           }
+                       {
+                               memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength);
+                               addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength);
+                               addr_list[0] = in;
+                               for (i = a.add_count-1; i>=0; --i)
+                                       addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i);
+                               addr_list[a.add_count + 1] = 0;
+                               buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf);
+                               buf = (char*)&addr_list[a.add_count + 2];
+                       }
 
            strncpy(buf, a.dotted, buflen);
            free(a.dotted);
 
            if (a.atype == T_A) { /* ADDRESS */
-               memcpy(in, a.rdata, sizeof(*in));
-               result_buf->h_name = buf;
-               result_buf->h_addrtype = AF_INET;
-               result_buf->h_length = sizeof(*in);
-               result_buf->h_addr_list = (char **) addr_list;
+                       memcpy(in, a.rdata, sizeof(*in));
+                       result_buf->h_name = buf;
+                       result_buf->h_addrtype = AF_INET;
+                       result_buf->h_length = sizeof(*in);
+                       result_buf->h_addr_list = (char **) addr_list;
 #ifdef __UCLIBC_MJN3_ONLY__
 #warning TODO -- generate the full list
 #endif
-               result_buf->h_aliases = alias; /* TODO: generate the full list */
-               free(packet);
-               break;
+                       result_buf->h_aliases = alias; /* TODO: generate the full list */
+                       free(packet);
+                       break;
            } else {
-               free(packet);
-               *h_errnop=HOST_NOT_FOUND;
-               return TRY_AGAIN;
+                       free(packet);
+                       *h_errnop=HOST_NOT_FOUND;
+                       return TRY_AGAIN;
            }
        }
 
@@ -2094,14 +2156,14 @@ libc_hidden_def(gethostbyname_r)
 #ifdef L_gethostbyname2_r
 
 int gethostbyname2_r(const char *name, int family,
-                           struct hostent * result_buf,
-                           char * buf, size_t buflen,
-                           struct hostent ** result,
-                           int * h_errnop)
+                                        struct hostent * result_buf,
+                                        char * buf, size_t buflen,
+                                        struct hostent ** result,
+                                        int * h_errnop)
 {
 #ifndef __UCLIBC_HAS_IPV6__
        return family == (AF_INET)? gethostbyname_r(name, result_buf,
-               buf, buflen, result, h_errnop) : HOST_NOT_FOUND;
+                                                                                               buf, buflen, result, h_errnop) : HOST_NOT_FOUND;
 #else /* __UCLIBC_HAS_IPV6__ */
        struct in6_addr *in;
        struct in6_addr **addr_list;
@@ -2128,8 +2190,8 @@ int gethostbyname2_r(const char *name, int family,
                int old_errno = errno;  /* Save the old errno and reset errno */
                __set_errno(0);                 /* to check for missing /etc/hosts. */
 
-               if ((i=__get_hosts_byname_r(name, AF_INET, result_buf,
-                               buf, buflen, result, h_errnop))==0)
+               if ((i=__get_hosts_byname_r(name, family, result_buf,
+                                                                       buf, buflen, result, h_errnop))==0)
                        return i;
                switch (*h_errnop) {
                        case HOST_NOT_FOUND:
@@ -2182,10 +2244,10 @@ int gethostbyname2_r(const char *name, int family,
        memset((char *) &a, '\0', sizeof(a));
 
        for (;;) {
-       BIGLOCK;
-       __nameserversXX=__nameservers;
-       __nameserverXX=__nameserver;
-       BIGUNLOCK;
+               __UCLIBC_MUTEX_LOCK(__resolv_lock);
+               __nameserversXX=__nameservers;
+               __nameserverXX=__nameserver;
+               __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
 
                i = __dns_lookup(buf, T_AAAA, __nameserversXX, __nameserverXX, &packet, &a);
 
@@ -2236,10 +2298,10 @@ libc_hidden_def(gethostbyname2_r)
 
 #ifdef L_gethostbyaddr_r
 int gethostbyaddr_r (const void *addr, socklen_t len, int type,
-                           struct hostent * result_buf,
-                           char * buf, size_t buflen,
-                           struct hostent ** result,
-                           int * h_errnop)
+                                        struct hostent * result_buf,
+                                        char * buf, size_t buflen,
+                                        struct hostent ** result,
+                                        int * h_errnop)
 
 {
        struct in_addr *in;
@@ -2250,6 +2312,7 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
        struct in6_addr *in6;
        struct in6_addr **addr_list6;
 #endif /* __UCLIBC_HAS_IPV6__ */
+       char **alias;
        unsigned char *packet;
        struct resolv_answer a;
        int i;
@@ -2280,7 +2343,7 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
 
        /* do /etc/hosts first */
        if ((i=__get_hosts_byaddr_r(addr, len, type, result_buf,
-                                 buf, buflen, result, h_errnop))==0)
+                                                               buf, buflen, result, h_errnop))==0)
                return i;
        switch (*h_errnop) {
                case HOST_NOT_FOUND:
@@ -2310,6 +2373,12 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
        buf+=sizeof(*addr_list)*2;
        buflen-=sizeof(*addr_list)*2;
 
+       if (buflen < sizeof(char *)*(ALIAS_DIM))
+               return ERANGE;
+       alias=(char **)buf;
+       buf+=sizeof(*alias)*(ALIAS_DIM);
+       buflen-=sizeof(*alias)*(ALIAS_DIM);
+
 #ifdef __UCLIBC_HAS_IPV6__
        if (plen < sizeof(*in6))
                return ERANGE;
@@ -2340,7 +2409,7 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
                addr_list[0] = in;
 
                sprintf(buf, "%u.%u.%u.%u.in-addr.arpa",
-                       tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);
+                               tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);
 #ifdef __UCLIBC_HAS_IPV6__
        } else {
                memcpy(in6->s6_addr, addr, len);
@@ -2350,20 +2419,23 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
 
                for (i = len - 1; i >= 0; i--) {
                        qp += sprintf(qp, "%x.%x.", in6->s6_addr[i] & 0xf,
-                               (in6->s6_addr[i] >> 4) & 0xf);
-       }
-       strcpy(qp, "ip6.int");
+                                                 (in6->s6_addr[i] >> 4) & 0xf);
+               }
+               strcpy(qp, "ip6.int");
 #endif /* __UCLIBC_HAS_IPV6__ */
        }
 
        addr_list[1] = 0;
 
+       alias[0] = buf;
+       alias[1] = 0;
+
        for (;;) {
 
-       BIGLOCK;
-       __nameserversXX=__nameservers;
-       __nameserverXX=__nameserver;
-       BIGUNLOCK;
+               __UCLIBC_MUTEX_LOCK(__resolv_lock);
+               __nameserversXX=__nameservers;
+               __nameserverXX=__nameserver;
+               __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
                i = __dns_lookup(buf, T_PTR, __nameserversXX, __nameserverXX, &packet, &a);
 
                if (i < 0) {
@@ -2401,9 +2473,10 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
                        } else {
                                result_buf->h_length = sizeof(*in6);
 #endif /* __UCLIBC_HAS_IPV6__ */
-               }
+                       }
 
                        result_buf->h_addr_list = (char **) addr_list;
+                       result_buf->h_aliases = alias;
                        break;
                } else {
                        free(packet);
@@ -2428,7 +2501,7 @@ libc_hidden_def(gethostbyaddr_r)
  * Return size of compressed name or -1 if there was an error.
  */
 int __dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
-          char *dst, int dstsiz)
+                               char *dst, int dstsiz)
 {
        int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
 
@@ -2448,7 +2521,7 @@ int __dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
  */
 static int printable(int ch)
 {
-        return (ch > 0x20 && ch < 0x7f);
+       return (ch > 0x20 && ch < 0x7f);
 }
 
 /*
@@ -2460,18 +2533,18 @@ static int printable(int ch)
  */
 static int special(int ch)
 {
-        switch (ch) {
+       switch (ch) {
         case 0x22: /* '"' */
         case 0x2E: /* '.' */
         case 0x3B: /* ';' */
         case 0x5C: /* '\\' */
-        /* Special modifiers in zone files. */
+                       /* Special modifiers in zone files. */
         case 0x40: /* '@' */
         case 0x24: /* '$' */
-                return (1);
+                       return (1);
         default:
-                return (0);
-        }
+                       return (0);
+       }
 }
 
 /*
@@ -2573,7 +2646,7 @@ int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
                return (-1);
        }
        *dn++ = '\0';
-        return (dn - dst);
+       return (dn - dst);
 }
 libc_hidden_def(ns_name_ntop)
 
@@ -2603,46 +2676,46 @@ int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
        while ((n = *srcp++) != 0) {
                /* Check for indirection. */
                switch (n & NS_CMPRSFLGS) {
-               case 0:
-                       /* Limit checks. */
-                       if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
-                               __set_errno (EMSGSIZE);
-                               return (-1);
-                       }
-                       checked += n + 1;
-                       *dstp++ = n;
-                       memcpy(dstp, srcp, n);
-                       dstp += n;
-                       srcp += n;
-                       break;
+                       case 0:
+                               /* Limit checks. */
+                               if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
+                                       __set_errno (EMSGSIZE);
+                                       return (-1);
+                               }
+                               checked += n + 1;
+                               *dstp++ = n;
+                               memcpy(dstp, srcp, n);
+                               dstp += n;
+                               srcp += n;
+                               break;
 
-               case NS_CMPRSFLGS:
-                       if (srcp >= eom) {
-                               __set_errno (EMSGSIZE);
-                               return (-1);
-                       }
-                       if (len < 0)
-                               len = srcp - src + 1;
-                       srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
-                       if (srcp < msg || srcp >= eom) {  /* Out of range. */
-                               __set_errno (EMSGSIZE);
-                               return (-1);
-                       }
-                       checked += 2;
-                       /*
-                        * Check for loops in the compressed name;
-                        * if we've looked at the whole message,
-                        * there must be a loop.
-                        */
-                       if (checked >= eom - msg) {
-                               __set_errno (EMSGSIZE);
-                               return (-1);
-                       }
-                       break;
+                       case NS_CMPRSFLGS:
+                               if (srcp >= eom) {
+                                       __set_errno (EMSGSIZE);
+                                       return (-1);
+                               }
+                               if (len < 0)
+                                       len = srcp - src + 1;
+                               srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+                               if (srcp < msg || srcp >= eom) {  /* Out of range. */
+                                       __set_errno (EMSGSIZE);
+                                       return (-1);
+                               }
+                               checked += 2;
+                               /*
+                                * Check for loops in the compressed name;
+                                * if we've looked at the whole message,
+                                * there must be a loop.
+                                */
+                               if (checked >= eom - msg) {
+                                       __set_errno (EMSGSIZE);
+                                       return (-1);
+                               }
+                               break;
 
-               default:
-                       __set_errno (EMSGSIZE);
-                       return (-1);                    /* flag error */
+                       default:
+                               __set_errno (EMSGSIZE);
+                               return (-1);                    /* flag error */
                }
        }
        *dstp = '\0';
This page took 0.123955 seconds and 4 git commands to generate.