Back to index

glibc  2.9
Defines | Functions
res_init.c File Reference
#include <ctype.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <not-cancel.h>

Go to the source code of this file.

Defines

#define RESOLVSORT
#define RFC1535
#define ISSORTMASK(ch)   (strchr(sort_mask_chars, ch) != NULL)
#define isascii(c)   (!(c & 0200))
#define MATCH(line, name)

Functions

static void res_setoptions (res_state, const char *, const char *)
int __res_vinit (res_state statp, int preinit)
static u_int32_t net_mask (struct in_addr in)
u_int res_randomid (void)
void __res_iclose (res_state statp, bool free_addr)
 libc_hidden_def (__res_iclose)

Define Documentation

#define isascii (   c)    (!(c & 0200))
#define ISSORTMASK (   ch)    (strchr(sort_mask_chars, ch) != NULL)
#define MATCH (   line,
  name 
)
Value:
(!strncmp(line, name, sizeof(name) - 1) && \
       (line[sizeof(name) - 1] == ' ' || \
        line[sizeof(name) - 1] == '\t'))
#define RESOLVSORT

Definition at line 92 of file res_init.c.

#define RFC1535

Definition at line 93 of file res_init.c.


Function Documentation

void __res_iclose ( res_state  statp,
bool  free_addr 
)

Definition at line 586 of file res_init.c.

                                              {
       int ns;

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

Here is the caller graph for this function:

int __res_vinit ( res_state  statp,
int  preinit 
)

Definition at line 150 of file res_init.c.

                                          {
       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
#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();
       }

#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;
              statp->_u._ext.nsmap[n] = MAXNS;
       }
#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, "rc")) != 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 ((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 (__builtin_expect (el == NULL, 1))
                                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->_u._ext.nsaddrs[nservall] = sa6;
                            statp->_u._ext.nssocks[nservall] = -1;
                            statp->_u._ext.nsmap[nservall] = MAXNS + 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;
              /* We try IPv6 servers again.  */
              statp->ipv6_unavail = false;
           }
#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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 611 of file res_init.c.

{
  __res_iclose (statp, true);
}

Here is the call graph for this function:

static u_int32_t net_mask ( struct in_addr  in) [static]

Definition at line 556 of file res_init.c.

{
       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));
}

Here is the call graph for this function:

Here is the caller graph for this function:

u_int res_randomid ( void  )

Definition at line 570 of file res_init.c.

                   {
       return 0xffff & __getpid();
}
static void internal_function res_setoptions ( res_state  statp,
const char *  options,
const char *  source 
) [static]

Definition at line 96 of file res_init.c.

                           {
       extern int __res_vinit(res_state, int);

       return (__res_vinit(statp, 0));
}

Here is the call graph for this function:

Here is the caller graph for this function: