Esempio n. 1
0
File: uname.c Progetto: bminor/glibc
/* Put information about the system in NAME.  */
int
__uname (struct utsname *name)
{
  int save;

  if (name == NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

  save = errno;
  if (__gethostname (name->nodename, sizeof (name->nodename)) < 0)
    {
      if (errno == ENOSYS)
	{
	  /* Hostname is meaningless for this machine.  */
	  name->nodename[0] = '\0';
	  __set_errno (save);
	}
#ifdef	ENAMETOOLONG
      else if (errno == ENAMETOOLONG)
	/* The name was truncated.  */
	__set_errno (save);
#endif
      else
	return -1;
    }
  strncpy (name->sysname, UNAME_SYSNAME, sizeof (name->sysname));
  strncpy (name->release, UNAME_RELEASE, sizeof (name->release));
  strncpy (name->version, UNAME_VERSION, sizeof (name->version));
  strncpy (name->machine, UNAME_MACHINE, sizeof (name->machine));

  return 0;
}
Esempio n. 2
0
int
host2netname (char netname[MAXNETNAMELEN + 1], const char *host,
	      const char *domain)
{
  char *p;
  char hostname[MAXHOSTNAMELEN + 1];
  char domainname[MAXHOSTNAMELEN + 1];
  char *dot_in_host;
  size_t i;

  netname[0] = '\0';		/* make null first (no need for memset) */

  if (host == NULL)
    __gethostname (hostname, MAXHOSTNAMELEN);
  else
    {
      strncpy (hostname, host, MAXHOSTNAMELEN);
      hostname[MAXHOSTNAMELEN] = '\0';
    }

  dot_in_host = strchr (hostname, '.');
  if (domain == NULL)
    {
      p = dot_in_host;
      if (p)
	{
	  ++p;
	  strncpy (domainname, p, MAXHOSTNAMELEN);
	  domainname[MAXHOSTNAMELEN] = '\0';
	}
      else
	{
	  domainname[0] = 0;
	  getdomainname (domainname, MAXHOSTNAMELEN);
	}
    }
  else
    {
      strncpy (domainname, domain, MAXHOSTNAMELEN);
      domainname[MAXHOSTNAMELEN] = '\0';
    }

  i = strlen (domainname);
  if (i == 0)
    /* No domainname */
    return 0;
  if (domainname[i - 1] == '.')
    domainname[i - 1] = 0;

  if (dot_in_host)		/* strip off rest of name */
    *dot_in_host = '\0';

  if ((strlen (domainname) + strlen (hostname) + OPSYS_LEN + 3)
      > MAXNETNAMELEN)
    return 0;

  sprintf (netname, "%s.%s@%s", OPSYS, hostname, domainname);
  return 1;
}
Esempio n. 3
0
int
__gethostname_chk (char *buf, size_t buflen, size_t nreal)
{
  if (buflen > nreal)
    __chk_fail ();

  return __gethostname (buf, buflen);
}
int
__uname (struct utsname *uname)
{
  error_t err;

  if (err = __USEPORT (PROC, __proc_uname (port, uname)))
    return __hurd_fail (err);

  /* Fill in the hostname, which the proc server doesn't know.  */
  err = errno;
  if (__gethostname (uname->nodename, sizeof uname->nodename) < 0)
    {
      if (errno == ENAMETOOLONG)
	/* Ignore the error of the buffer being too small.
	   It is of fixed size, nothing to do about it.  */
	errno = err;
      else
	return -1;
    }

  return 0;
}
Esempio n. 5
0
/* This function has to be reachable by res_data.c but not publically. */
int
__res_vinit(res_state statp, int preinit) {
	FILE *fp;
	char *cp, **pp;
	int n;
	char buf[BUFSIZ];
	int nserv = 0;    /* number of nameservers read from file */
	int have_serv6 = 0;
	int haveenv = 0;
	int havesearch = 0;
#ifdef RESOLVSORT
	int nsort = 0;
	char *net;
#endif
#ifndef RFC1535
	int dots;
#endif
#ifdef _LIBC
	statp->_u._ext.initstamp = __res_initstamp;
#endif

	if (!preinit) {
		statp->retrans = RES_TIMEOUT;
		statp->retry = RES_DFLRETRY;
		statp->options = RES_DEFAULT;
		statp->id = res_randomid();
	}

	statp->nscount = 0;
	statp->ndots = 1;
	statp->pfcode = 0;
	statp->_vcsock = -1;
	statp->_flags = 0;
	statp->qhook = NULL;
	statp->rhook = NULL;
	statp->_u._ext.nscount = 0;
	for (n = 0; n < MAXNS; n++)
	    statp->_u._ext.nsaddrs[n] = NULL;

	/* Allow user to override the local domain definition */
	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
		(void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		haveenv++;

		/*
		 * Set search list to be blank-separated strings
		 * from rest of env value.  Permits users of LOCALDOMAIN
		 * to still have a search list, and anyone to set the
		 * one that they want to use as an individual (even more
		 * important now that the rfc1535 stuff restricts searches)
		 */
		cp = statp->defdname;
		pp = statp->dnsrch;
		*pp++ = cp;
		for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
			if (*cp == '\n')	/* silly backwards compat */
				break;
			else if (*cp == ' ' || *cp == '\t') {
				*cp = 0;
				n = 1;
			} else if (n) {
				*pp++ = cp;
				n = 0;
				havesearch = 1;
			}
		}
		/* null terminate last domain if there are excess */
		while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
			cp++;
		*cp = '\0';
		*pp++ = 0;
	}

#define	MATCH(line, name) \
	(!strncmp(line, name, sizeof(name) - 1) && \
	(line[sizeof(name) - 1] == ' ' || \
	 line[sizeof(name) - 1] == '\t'))

	if ((fp = fopen(_PATH_RESCONF, "rce")) != NULL) {
	    /* No threads use this stream.  */
	    __fsetlocking (fp, FSETLOCKING_BYCALLER);
	    /* read the config file */
	    while (__fgets_unlocked(buf, sizeof(buf), fp) != NULL) {
		/* skip comments */
		if (*buf == ';' || *buf == '#')
			continue;
		/* read default domain name */
		if (MATCH(buf, "domain")) {
		    if (haveenv)	/* skip if have from environ */
			    continue;
		    cp = buf + sizeof("domain") - 1;
		    while (*cp == ' ' || *cp == '\t')
			    cp++;
		    if ((*cp == '\0') || (*cp == '\n'))
			    continue;
		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		    if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL)
			    *cp = '\0';
		    havesearch = 0;
		    continue;
		}
		/* set search list */
		if (MATCH(buf, "search")) {
		    if (haveenv)	/* skip if have from environ */
			    continue;
		    cp = buf + sizeof("search") - 1;
		    while (*cp == ' ' || *cp == '\t')
			    cp++;
		    if ((*cp == '\0') || (*cp == '\n'))
			    continue;
		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		    if ((cp = strchr(statp->defdname, '\n')) != NULL)
			    *cp = '\0';
		    /*
		     * Set search list to be blank-separated strings
		     * on rest of line.
		     */
		    cp = statp->defdname;
		    pp = statp->dnsrch;
		    *pp++ = cp;
		    for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
			    if (*cp == ' ' || *cp == '\t') {
				    *cp = 0;
				    n = 1;
			    } else if (n) {
				    *pp++ = cp;
				    n = 0;
			    }
		    }
		    /* null terminate last domain if there are excess */
		    while (*cp != '\0' && *cp != ' ' && *cp != '\t')
			    cp++;
		    *cp = '\0';
		    *pp++ = 0;
		    havesearch = 1;
		    continue;
		}
		/* read nameservers to query */
		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
		    struct in_addr a;

		    cp = buf + sizeof("nameserver") - 1;
		    while (*cp == ' ' || *cp == '\t')
			cp++;
		    if ((*cp != '\0') && (*cp != '\n')
			&& __inet_aton(cp, &a)) {
			statp->nsaddr_list[nserv].sin_addr = a;
			statp->nsaddr_list[nserv].sin_family = AF_INET;
			statp->nsaddr_list[nserv].sin_port =
				htons(NAMESERVER_PORT);
			nserv++;
#ifdef _LIBC
		    } else {
			struct in6_addr a6;
			char *el;

			if ((el = strpbrk(cp, " \t\n")) != NULL)
			    *el = '\0';
			if ((el = strchr(cp, SCOPE_DELIMITER)) != NULL)
			    *el = '\0';
			if ((*cp != '\0') &&
			    (__inet_pton(AF_INET6, cp, &a6) > 0)) {
			    struct sockaddr_in6 *sa6;

			    sa6 = malloc(sizeof(*sa6));
			    if (sa6 != NULL) {
				sa6->sin6_family = AF_INET6;
				sa6->sin6_port = htons(NAMESERVER_PORT);
				sa6->sin6_flowinfo = 0;
				sa6->sin6_addr = a6;

				if (__glibc_likely (el == NULL))
				    sa6->sin6_scope_id = 0;
				else {
				    int try_numericscope = 1;
				    if (IN6_IS_ADDR_LINKLOCAL (&a6)
					|| IN6_IS_ADDR_MC_LINKLOCAL (&a6)) {
					sa6->sin6_scope_id
					  = __if_nametoindex (el + 1);
					if (sa6->sin6_scope_id != 0)
					    try_numericscope = 0;
				    }

				    if (try_numericscope) {
					char *end;
					sa6->sin6_scope_id
					  = (uint32_t) strtoul (el + 1, &end,
								10);
					if (*end != '\0')
					    sa6->sin6_scope_id = 0;
				    }
				}

				statp->nsaddr_list[nserv].sin_family = 0;
				statp->_u._ext.nsaddrs[nserv] = sa6;
				statp->_u._ext.nssocks[nserv] = -1;
				have_serv6 = 1;
				nserv++;
			    }
			}
#endif
		    }
		    continue;
		}
#ifdef RESOLVSORT
		if (MATCH(buf, "sortlist")) {
		    struct in_addr a;

		    cp = buf + sizeof("sortlist") - 1;
		    while (nsort < MAXRESOLVSORT) {
			while (*cp == ' ' || *cp == '\t')
			    cp++;
			if (*cp == '\0' || *cp == '\n' || *cp == ';')
			    break;
			net = cp;
			while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
			       isascii(*cp) && !isspace(*cp))
				cp++;
			n = *cp;
			*cp = 0;
			if (__inet_aton(net, &a)) {
			    statp->sort_list[nsort].addr = a;
			    if (ISSORTMASK(n)) {
				*cp++ = n;
				net = cp;
				while (*cp && *cp != ';' &&
					isascii(*cp) && !isspace(*cp))
				    cp++;
				n = *cp;
				*cp = 0;
				if (__inet_aton(net, &a)) {
				    statp->sort_list[nsort].mask = a.s_addr;
				} else {
				    statp->sort_list[nsort].mask =
					net_mask(statp->sort_list[nsort].addr);
				}
			    } else {
				statp->sort_list[nsort].mask =
				    net_mask(statp->sort_list[nsort].addr);
			    }
			    nsort++;
			}
			*cp = n;
		    }
		    continue;
		}
#endif
		if (MATCH(buf, "options")) {
		    res_setoptions(statp, buf + sizeof("options") - 1, "conf");
		    continue;
		}
	    }
	    statp->nscount = nserv;
#ifdef _LIBC
	    if (have_serv6) {
		/* We try IPv6 servers again.  */
		statp->ipv6_unavail = false;
	    }
#endif
#ifdef RESOLVSORT
	    statp->nsort = nsort;
#endif
	    (void) fclose(fp);
	}
	if (__builtin_expect(statp->nscount == 0, 0)) {
	    statp->nsaddr.sin_addr = __inet_makeaddr(IN_LOOPBACKNET, 1);
	    statp->nsaddr.sin_family = AF_INET;
	    statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
	    statp->nscount = 1;
	}
	if (statp->defdname[0] == 0 &&
	    __gethostname(buf, sizeof(statp->defdname) - 1) == 0 &&
	    (cp = strchr(buf, '.')) != NULL)
		strcpy(statp->defdname, cp + 1);

	/* find components of local domain that might be searched */
	if (havesearch == 0) {
		pp = statp->dnsrch;
		*pp++ = statp->defdname;
		*pp = NULL;

#ifndef RFC1535
		dots = 0;
		for (cp = statp->defdname; *cp; cp++)
			dots += (*cp == '.');

		cp = statp->defdname;
		while (pp < statp->dnsrch + MAXDFLSRCH) {
			if (dots < LOCALDOMAINPARTS)
				break;
			cp = __rawmemchr(cp, '.') + 1;    /* we know there is one */
			*pp++ = cp;
			dots--;
		}
		*pp = NULL;
#ifdef DEBUG
		if (statp->options & RES_DEBUG) {
			printf(";; res_init()... default dnsrch list:\n");
			for (pp = statp->dnsrch; *pp; pp++)
				printf(";;\t%s\n", *pp);
			printf(";;\t..END..\n");
		}
#endif
#endif /* !RFC1535 */
	}

	if ((cp = getenv("RES_OPTIONS")) != NULL)
		res_setoptions(statp, cp, "env");
	statp->options |= RES_INIT;
	return (0);
}
Esempio n. 6
0
int
ruserpass (const char *host, const char **aname, const char **apass)
{
	char *hdir, *buf, *tmp;
	char myname[1024], *mydomain;
	int t, usedefault = 0;
	struct stat64 stb;

	hdir = __libc_secure_getenv("HOME");
	if (hdir == NULL) {
		/* If we can't get HOME, fail instead of trying ".",
		   which is no improvement. This really should call
		   getpwuid(getuid()).  */
		/*hdir = ".";*/
		return -1;
	}

	buf = alloca (strlen (hdir) + 8);

	__stpcpy (__stpcpy (buf, hdir), "/.netrc");
	cfile = fopen(buf, "rce");
	if (cfile == NULL) {
		if (errno != ENOENT)
			warn("%s", buf);
		return (0);
	}
	/* No threads use this stream.  */
	__fsetlocking (cfile, FSETLOCKING_BYCALLER);
	if (__gethostname(myname, sizeof(myname)) < 0)
		myname[0] = '\0';
	mydomain = __strchrnul(myname, '.');
next:
	while ((t = token())) switch(t) {

	case DEFAULT:
		usedefault = 1;
		/* FALL THROUGH */

	case MACHINE:
		if (!usedefault) {
			if (token() != ID)
				continue;
			/*
			 * Allow match either for user's input host name
			 * or official hostname.  Also allow match of
			 * incompletely-specified host in local domain.
			 */
			if (__strcasecmp(host, tokval) == 0)
				goto match;
/*			if (__strcasecmp(hostname, tokval) == 0)
				goto match;
			if ((tmp = strchr(hostname, '.')) != NULL &&
			    __strcasecmp(tmp, mydomain) == 0 &&
			    __strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
			    tokval[tmp - hostname] == '\0')
				goto match; */
			if ((tmp = strchr(host, '.')) != NULL &&
			    __strcasecmp(tmp, mydomain) == 0 &&
			    __strncasecmp(host, tokval, tmp - host) == 0 &&
			    tokval[tmp - host] == '\0')
				goto match;
			continue;
		}
	match:
		while ((t = token()) && t != MACHINE && t != DEFAULT) switch(t) {

		case LOGIN:
			if (token()) {
				if (*aname == 0) {
				  char *newp;
				  newp = malloc((unsigned) strlen(tokval) + 1);
				  if (newp == NULL)
				    {
				      warnx(_("out of memory"));
				      goto bad;
				    }
				  *aname = strcpy(newp, tokval);
				} else {
					if (strcmp(*aname, tokval))
						goto next;
				}
			}
			break;
		case PASSWD:
			if (strcmp(*aname, "anonymous") &&
			    fstat64(fileno(cfile), &stb) >= 0 &&
			    (stb.st_mode & 077) != 0) {
	warnx(_("Error: .netrc file is readable by others."));
	warnx(_("Remove password or make file unreadable by others."));
				goto bad;
			}
			if (token() && *apass == 0) {
				char *newp;
				newp = malloc((unsigned) strlen(tokval) + 1);
				if (newp == NULL)
				  {
				    warnx(_("out of memory"));
				    goto bad;
				  }
				*apass = strcpy(newp, tokval);
			}
			break;
		case ACCOUNT:
			break;
		case MACDEF:
			break;
		default:
			warnx(_("Unknown .netrc keyword %s"), tokval);
			break;
		}
		goto done;
	}
done:
	(void) fclose(cfile);
	return (0);
bad:
	(void) fclose(cfile);
	return (-1);
}
Esempio n. 7
0
/* This function has to be reachable by res_data.c but not publically. */
int
__res_vinit(res_state statp, int preinit) {
	register FILE *fp;
	register char *cp, **pp;
	register int n;
	char buf[BUFSIZ];
	int nserv = 0;    /* number of nameserver records read from file */
#ifdef _LIBC
	int nservall = 0; /* number of NS records read, nserv IPv4 only */
#endif
	int haveenv = 0;
	int havesearch = 0;
#ifdef RESOLVSORT
	int nsort = 0;
	char *net;
#endif
#ifndef RFC1535
	int dots;
#endif

	if (!preinit) {
		statp->retrans = RES_TIMEOUT;
		statp->retry = RES_DFLRETRY;
		statp->options = RES_DEFAULT;
		statp->id = res_randomid();
	}

#ifdef USELOOPBACK
	statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
#else
	statp->nsaddr.sin_addr.s_addr = INADDR_ANY;
#endif
	statp->nsaddr.sin_family = AF_INET;
	statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
	statp->nscount = 1;
	statp->ndots = 1;
	statp->pfcode = 0;
	statp->_vcsock = -1;
	statp->_flags = 0;
	statp->qhook = NULL;
	statp->rhook = NULL;
	statp->_u._ext.nsinit = 0;
	statp->_u._ext.nscount = 0;
#ifdef _LIBC
	statp->_u._ext.nscount6 = 0;
	for (n = 0; n < MAXNS; n++)
	    statp->_u._ext.nsaddrs[n] = NULL;
#endif

	/* Allow user to override the local domain definition */
	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
		(void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		haveenv++;

		/*
		 * Set search list to be blank-separated strings
		 * from rest of env value.  Permits users of LOCALDOMAIN
		 * to still have a search list, and anyone to set the
		 * one that they want to use as an individual (even more
		 * important now that the rfc1535 stuff restricts searches)
		 */
		cp = statp->defdname;
		pp = statp->dnsrch;
		*pp++ = cp;
		for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
			if (*cp == '\n')	/* silly backwards compat */
				break;
			else if (*cp == ' ' || *cp == '\t') {
				*cp = 0;
				n = 1;
			} else if (n) {
				*pp++ = cp;
				n = 0;
				havesearch = 1;
			}
		}
		/* null terminate last domain if there are excess */
		while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
			cp++;
		*cp = '\0';
		*pp++ = 0;
	}

#define	MATCH(line, name) \
	(!strncmp(line, name, sizeof(name) - 1) && \
	(line[sizeof(name) - 1] == ' ' || \
	 line[sizeof(name) - 1] == '\t'))

	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
		/* No threads use this stream.  */
		__fsetlocking (fp, FSETLOCKING_BYCALLER);
	    /* read the config file */
	    while (fgets_unlocked(buf, sizeof(buf), fp) != NULL) {
		/* skip comments */
		if (*buf == ';' || *buf == '#')
			continue;
		/* read default domain name */
		if (MATCH(buf, "domain")) {
		    if (haveenv)	/* skip if have from environ */
			    continue;
		    cp = buf + sizeof("domain") - 1;
		    while (*cp == ' ' || *cp == '\t')
			    cp++;
		    if ((*cp == '\0') || (*cp == '\n'))
			    continue;
		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		    if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL)
			    *cp = '\0';
		    havesearch = 0;
		    continue;
		}
		/* set search list */
		if (MATCH(buf, "search")) {
		    if (haveenv)	/* skip if have from environ */
			    continue;
		    cp = buf + sizeof("search") - 1;
		    while (*cp == ' ' || *cp == '\t')
			    cp++;
		    if ((*cp == '\0') || (*cp == '\n'))
			    continue;
		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		    if ((cp = strchr(statp->defdname, '\n')) != NULL)
			    *cp = '\0';
		    /*
		     * Set search list to be blank-separated strings
		     * on rest of line.
		     */
		    cp = statp->defdname;
		    pp = statp->dnsrch;
		    *pp++ = cp;
		    for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
			    if (*cp == ' ' || *cp == '\t') {
				    *cp = 0;
				    n = 1;
			    } else if (n) {
				    *pp++ = cp;
				    n = 0;
			    }
		    }
		    /* null terminate last domain if there are excess */
		    while (*cp != '\0' && *cp != ' ' && *cp != '\t')
			    cp++;
		    *cp = '\0';
		    *pp++ = 0;
		    havesearch = 1;
		    continue;
		}
		/* read nameservers to query */
#ifdef _LIBC
		if (MATCH(buf, "nameserver") && nservall < MAXNS) {
#else
		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
#endif
		    struct in_addr a;

		    cp = buf + sizeof("nameserver") - 1;
		    while (*cp == ' ' || *cp == '\t')
			cp++;
		    if ((*cp != '\0') && (*cp != '\n')
			&& __inet_aton(cp, &a)) {
			statp->nsaddr_list[nserv].sin_addr = a;
			statp->nsaddr_list[nserv].sin_family = AF_INET;
			statp->nsaddr_list[nserv].sin_port =
				htons(NAMESERVER_PORT);
			nserv++;
#ifdef _LIBC
			nservall++;
                    } else {
                        struct in6_addr a6;
                        char *el;

                        if ((el = strchr(cp, '\n')) != NULL)
                            *el = '\0';
                        if ((*cp != '\0') &&
                            (inet_pton(AF_INET6, cp, &a6) > 0)) {
                            struct sockaddr_in6 *sa6;

                            sa6 = malloc(sizeof(*sa6));
                            if (sa6 != NULL) {
                                sa6->sin6_addr = a6;
                                sa6->sin6_family = AF_INET6;
                                sa6->sin6_port = htons(NAMESERVER_PORT);
				statp->_u._ext.nsaddrs[nservall] = sa6;
				statp->_u._ext.nstimes[nservall] = RES_MAXTIME;
				statp->_u._ext.nssocks[nservall] = -1;
                                nservall++;
                            }
                        }
#endif
		    }
		    continue;
		}
#ifdef RESOLVSORT
		if (MATCH(buf, "sortlist")) {
		    struct in_addr a;

		    cp = buf + sizeof("sortlist") - 1;
		    while (nsort < MAXRESOLVSORT) {
			while (*cp == ' ' || *cp == '\t')
			    cp++;
			if (*cp == '\0' || *cp == '\n' || *cp == ';')
			    break;
			net = cp;
			while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
			       isascii(*cp) && !isspace(*cp))
				cp++;
			n = *cp;
			*cp = 0;
			if (__inet_aton(net, &a)) {
			    statp->sort_list[nsort].addr = a;
			    if (ISSORTMASK(n)) {
				*cp++ = n;
				net = cp;
				while (*cp && *cp != ';' &&
					isascii(*cp) && !isspace(*cp))
				    cp++;
				n = *cp;
				*cp = 0;
				if (__inet_aton(net, &a)) {
				    statp->sort_list[nsort].mask = a.s_addr;
				} else {
				    statp->sort_list[nsort].mask =
					net_mask(statp->sort_list[nsort].addr);
				}
			    } else {
				statp->sort_list[nsort].mask =
				    net_mask(statp->sort_list[nsort].addr);
			    }
			    nsort++;
			}
			*cp = n;
		    }
		    continue;
		}
#endif
		if (MATCH(buf, "options")) {
		    res_setoptions(statp, buf + sizeof("options") - 1, "conf");
		    continue;
		}
	    }
	    if (nserv > 1)
		statp->nscount = nserv;
#ifdef _LIBC
	    if (nservall - nserv > 0)
		statp->_u._ext.nscount6 = nservall - nserv;
#endif
#ifdef RESOLVSORT
	    statp->nsort = nsort;
#endif
	    (void) fclose(fp);
	}
	if (statp->defdname[0] == 0 &&
	    __gethostname(buf, sizeof(statp->defdname) - 1) == 0 &&
	    (cp = strchr(buf, '.')) != NULL)
		strcpy(statp->defdname, cp + 1);

	/* find components of local domain that might be searched */
	if (havesearch == 0) {
		pp = statp->dnsrch;
		*pp++ = statp->defdname;
		*pp = NULL;

#ifndef RFC1535
		dots = 0;
		for (cp = statp->defdname; *cp; cp++)
			dots += (*cp == '.');

		cp = statp->defdname;
		while (pp < statp->dnsrch + MAXDFLSRCH) {
			if (dots < LOCALDOMAINPARTS)
				break;
			cp = __rawmemchr(cp, '.') + 1;    /* we know there is one */
			*pp++ = cp;
			dots--;
		}
		*pp = NULL;
#ifdef DEBUG
		if (statp->options & RES_DEBUG) {
			printf(";; res_init()... default dnsrch list:\n");
			for (pp = statp->dnsrch; *pp; pp++)
				printf(";;\t%s\n", *pp);
			printf(";;\t..END..\n");
		}
#endif
#endif /* !RFC1535 */
	}

	if ((cp = getenv("RES_OPTIONS")) != NULL)
		res_setoptions(statp, cp, "env");
	statp->options |= RES_INIT;
	return (0);
}

static void
internal_function
res_setoptions(res_state statp, const char *options, const char *source) {
	const char *cp = options;
	int i;

#ifdef DEBUG
	if (statp->options & RES_DEBUG)
		printf(";; res_setoptions(\"%s\", \"%s\")...\n",
		       options, source);
#endif
	while (*cp) {
		/* skip leading and inner runs of spaces */
		while (*cp == ' ' || *cp == '\t')
			cp++;
		/* search for and process individual options */
		if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
			i = atoi(cp + sizeof("ndots:") - 1);
			if (i <= RES_MAXNDOTS)
				statp->ndots = i;
			else
				statp->ndots = RES_MAXNDOTS;
#ifdef DEBUG
			if (statp->options & RES_DEBUG)
				printf(";;\tndots=%d\n", statp->ndots);
#endif
		} else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) {
			i = atoi(cp + sizeof("timeout:") - 1);
			if (i <= RES_MAXRETRANS)
				statp->retrans = i;
			else
				statp->retrans = RES_MAXRETRANS;
		} else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){
			i = atoi(cp + sizeof("attempts:") - 1);
			if (i <= RES_MAXRETRY)
				statp->retry = i;
			else
				statp->retry = RES_MAXRETRY;
		} else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
#ifdef DEBUG
			if (!(statp->options & RES_DEBUG)) {
				printf(";; res_setoptions(\"%s\", \"%s\")..\n",
				       options, source);
				statp->options |= RES_DEBUG;
			}
			printf(";;\tdebug\n");
#endif
		} else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
			statp->options |= RES_USE_INET6;
		} else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) {
			statp->options |= RES_ROTATE;
		} else if (!strncmp(cp, "no-check-names",
				    sizeof("no-check-names") - 1)) {
			statp->options |= RES_NOCHECKNAME;
		} else {
			/* XXX - print a warning here? */
		}
		/* skip to next run of spaces */
		while (*cp && *cp != ' ' && *cp != '\t')
			cp++;
	}
}

#ifdef RESOLVSORT
/* XXX - should really support CIDR which means explicit masks always. */
static u_int32_t
net_mask(in)		/* XXX - should really use system's version of this */
	struct in_addr in;
{
	register u_int32_t i = ntohl(in.s_addr);

	if (IN_CLASSA(i))
		return (htonl(IN_CLASSA_NET));
	else if (IN_CLASSB(i))
		return (htonl(IN_CLASSB_NET));
	return (htonl(IN_CLASSC_NET));
}
#endif

u_int
res_randomid(void) {
	struct timeval now;

	__gettimeofday(&now, NULL);
	return (0xffff & (now.tv_sec ^ now.tv_usec ^ __getpid()));
}

/*
 * This routine is for closing the socket if a virtual circuit is used and
 * the program wants to close it.  This provides support for endhostent()
 * which expects to close the socket.
 *
 * This routine is not expected to be user visible.
 */
void
res_nclose(res_state statp) {
	int ns;

	if (statp->_vcsock >= 0) {
		(void) __close(statp->_vcsock);
		statp->_vcsock = -1;
		statp->_flags &= ~(RES_F_VC | RES_F_CONN);
	}
#ifdef _LIBC
	for (ns = 0; ns < statp->_u._ext.nscount + statp->_u._ext.nscount6;
	     ns++)
#else
	for (ns = 0; ns < statp->_u._ext.nscount; ns++)
#endif
	{
		if (statp->_u._ext.nssocks[ns] != -1) {
			(void) __close(statp->_u._ext.nssocks[ns]);
			statp->_u._ext.nssocks[ns] = -1;
		}
	}
	statp->_u._ext.nsinit = 0;
}