void __open_nameservers(void)
{
	static uint32_t resolv_conf_mtime;

	char szBuffer[MAXLEN_searchdomain];
	FILE *fp;
	int i;
	sockaddr46_t sa;

	if (!__res_sync) {
		/* Reread /etc/resolv.conf if it was modified.  */
		struct stat sb;
		if (stat(_PATH_RESCONF, &sb) != 0)
			sb.st_mtime = 0;
		if (resolv_conf_mtime != (uint32_t)sb.st_mtime) {
			resolv_conf_mtime = sb.st_mtime;
			__close_nameservers(); /* force config reread */
		}
	}

	if (__nameservers)
		goto sync;

	__resolv_timeout = RES_TIMEOUT;
	__resolv_attempts = RES_DFLRETRY;

	fp = fopen(_PATH_RESCONF, "r");
#ifdef FALLBACK_TO_CONFIG_RESOLVCONF
	if (!fp) {
		/* If we do not have a pre-populated /etc/resolv.conf then
		   try to use the one from /etc/config which exists on numerous
		   systems ranging from some uClinux to IRIX installations and
		   may be the only /etc dir that was mounted rw.  */
		fp = fopen("/etc/config/resolv.conf", "r");
	}
#endif

	if (fp) {
		while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
			void *ptr;
			char *keyword, *p;

			keyword = p = skip_and_NUL_space(szBuffer);
			/* skip keyword */
			p = skip_nospace(p);
			/* find next word */
			p = skip_and_NUL_space(p);

			if (strcmp(keyword, "nameserver") == 0) {
				/* terminate IP addr */
				*skip_nospace(p) = '\0';
				memset(&sa, 0, sizeof(sa));
				if (0) /* nothing */;
#ifdef __UCLIBC_HAS_IPV6__
				else if (inet_pton(AF_INET6, p, &sa.sa6.sin6_addr) > 0) {
					sa.sa6.sin6_family = AF_INET6;
					sa.sa6.sin6_port = htons(NAMESERVER_PORT);
				}
#endif
#ifdef __UCLIBC_HAS_IPV4__
				else if (inet_pton(AF_INET, p, &sa.sa4.sin_addr) > 0) {
					sa.sa4.sin_family = AF_INET;
					sa.sa4.sin_port = htons(NAMESERVER_PORT);
				}
#endif
				else
					continue; /* garbage on this line */
				ptr = realloc(__nameserver, (__nameservers + 1) * sizeof(__nameserver[0]));
				if (!ptr)
					continue;
				__nameserver = ptr;
				__nameserver[__nameservers++] = sa; /* struct copy */
				continue;
			}
			if (strcmp(keyword, "domain") == 0 || strcmp(keyword, "search") == 0) {
				char *p1;

				/* free old domains ("last 'domain' or 'search' wins" rule) */
				while (__searchdomains)
					free(__searchdomain[--__searchdomains]);
				/*free(__searchdomain);*/
				/*__searchdomain = NULL; - not necessary */
 next_word:
				/* terminate current word */
				p1 = skip_nospace(p);
				/* find next word (maybe) */
				p1 = skip_and_NUL_space(p1);
				/* add it */
				ptr = realloc(__searchdomain, (__searchdomains + 1) * sizeof(__searchdomain[0]));
				if (!ptr)
					continue;
				__searchdomain = ptr;
				/* NB: strlen(p) <= MAXLEN_searchdomain) because szBuffer[] is smaller */
				ptr = strdup(p);
				if (!ptr)
					continue;
				DPRINTF("adding search %s\n", (char*)ptr);
				__searchdomain[__searchdomains++] = (char*)ptr;
				p = p1;
				if (*p)
					goto next_word;
				continue;
			}
			/* if (strcmp(keyword, "sortlist") == 0)... */
			if (strcmp(keyword, "options") == 0) {
				char *p1;
				uint8_t *what;

				if (p == NULL || (p1 = strchr(p, ':')) == NULL)
					continue;
				*p1++ = '\0';
				if (strcmp(p, "timeout") == 0)
					what = &__resolv_timeout;
				else if (strcmp(p, "attempts") == 0)
					what = &__resolv_attempts;
				else
					continue;
				*what = atoi(p1);
				DPRINTF("option %s:%d\n", p, *what);
			}
		}
		fclose(fp);
	}
	if (__nameservers == 0) {
		/* Have to handle malloc failure! What a mess...
		 * And it's not only here, we need to be careful
		 * to never write into __nameserver[0] if it points
		 * to constant __local_nameserver, or free it. */
		__nameserver = malloc(sizeof(__nameserver[0]));
		if (__nameserver)
			memcpy(__nameserver, &__local_nameserver, sizeof(__local_nameserver));
		else
			__nameserver = (void*) &__local_nameserver;
		__nameservers++;
	}
	if (__searchdomains == 0) {
		char buf[256];
		char *p;
		i = gethostname(buf, sizeof(buf) - 1);
		buf[sizeof(buf) - 1] = '\0';
		if (i == 0 && (p = strchr(buf, '.')) != NULL && p[1]) {
			p = strdup(p + 1);
			if (!p)
				goto err;
			__searchdomain = malloc(sizeof(__searchdomain[0]));
			if (!__searchdomain) {
				free(p);
				goto err;
			}
			__searchdomain[0] = p;
			__searchdomains++;
 err: ;
		}
	}
	DPRINTF("nameservers = %d\n", __nameservers);

 sync:
	if (__res_sync)
		__res_sync();
}
void __open_nameservers(void)
{
	static uint32_t resolv_conf_mtime;

	char szBuffer[MAXLEN_searchdomain];
	FILE *fp;
	int i;
	sockaddr46_t sa;

	if (!__res_sync) {
		 
		struct stat sb;
		if (stat(_PATH_RESCONF, &sb) != 0)
			sb.st_mtime = 0;
		if (resolv_conf_mtime != (uint32_t)sb.st_mtime) {
			resolv_conf_mtime = sb.st_mtime;
			__close_nameservers();  
		}
	}

	if (__nameservers)
		goto sync;

	__resolv_timeout = RES_TIMEOUT;
	__resolv_attempts = RES_DFLRETRY;

	fp = fopen(_PATH_RESCONF, "r");
#ifdef FALLBACK_TO_CONFIG_RESOLVCONF
	if (!fp) {
		 
		fp = fopen("/etc/config/resolv.conf", "r");
	}
#endif

	if (fp) {
		while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
			void *ptr;
			char *keyword, *p;

			keyword = p = skip_and_NUL_space(szBuffer);
			 
			p = skip_nospace(p);
			 
			p = skip_and_NUL_space(p);

			if (strcmp(keyword, "nameserver") == 0) {
				 
				*skip_nospace(p) = '\0';
				memset(&sa, 0, sizeof(sa));
				if (0)  ;
#ifdef __UCLIBC_HAS_IPV6__
				else if (inet_pton(AF_INET6, p, &sa.sa6.sin6_addr) > 0) {
					sa.sa6.sin6_family = AF_INET6;
					sa.sa6.sin6_port = htons(NAMESERVER_PORT);
				}
#endif
#ifdef __UCLIBC_HAS_IPV4__
				else if (inet_pton(AF_INET, p, &sa.sa4.sin_addr) > 0) {
					sa.sa4.sin_family = AF_INET;
					sa.sa4.sin_port = htons(NAMESERVER_PORT);
				}
#endif
				else
					continue;  
				ptr = realloc(__nameserver, (__nameservers + 1) * sizeof(__nameserver[0]));
				if (!ptr)
					continue;
				__nameserver = ptr;
				__nameserver[__nameservers++] = sa;  
				continue;
			}
			if (strcmp(keyword, "domain") == 0 || strcmp(keyword, "search") == 0) {
				char *p1;

				 
				while (__searchdomains)
					free(__searchdomain[--__searchdomains]);
				 
				 
 next_word:
				 
				p1 = skip_nospace(p);
				 
				p1 = skip_and_NUL_space(p1);
				 
				ptr = realloc(__searchdomain, (__searchdomains + 1) * sizeof(__searchdomain[0]));
				if (!ptr)
					continue;
				__searchdomain = ptr;
				 
				ptr = strdup(p);
				if (!ptr)
					continue;
				DPRINTF("adding search %s\n", (char*)ptr);
				__searchdomain[__searchdomains++] = (char*)ptr;
				p = p1;
				if (*p)
					goto next_word;
				continue;
			}
			 
			if (strcmp(keyword, "options") == 0) {
				char *p1;
				uint8_t *what;

				if (p == NULL || (p1 = strchr(p, ':')) == NULL)
					continue;
				*p1++ = '\0';
				if (strcmp(p, "timeout") == 0)
					what = &__resolv_timeout;
				else if (strcmp(p, "attempts") == 0)
					what = &__resolv_attempts;
				else
					continue;
				*what = atoi(p1);
				DPRINTF("option %s:%d\n", p, *what);
			}
		}
		fclose(fp);
	}
	if (__nameservers == 0) {
		 
		__nameserver = malloc(sizeof(__nameserver[0]));
		if (__nameserver)
			memcpy(__nameserver, &__local_nameserver, sizeof(__local_nameserver));
		else
			__nameserver = (void*) &__local_nameserver;
		__nameservers++;
	}
	if (__searchdomains == 0) {
		char buf[256];
		char *p;
		i = gethostname(buf, sizeof(buf) - 1);
		buf[sizeof(buf) - 1] = '\0';
		if (i == 0 && (p = strchr(buf, '.')) != NULL && p[1]) {
			p = strdup(p + 1);
			if (!p)
				goto err;
			__searchdomain = malloc(sizeof(__searchdomain[0]));
			if (!__searchdomain) {
				free(p);
				goto err;
			}
			__searchdomain[0] = p;
			__searchdomains++;
 err: ;
		}
	}
	DPRINTF("nameservers = %d\n", __nameservers);

 sync:
	if (__res_sync)
		__res_sync();
}