OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc2/] [newlib/] [libc/] [sys/] [linux/] [net/] [res_hconf.c] - Diff between revs 207 and 520

Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 520
/* Copyright (C) 1993, 1995-2003, 2004 Free Software Foundation, Inc.
/* Copyright (C) 1993, 1995-2003, 2004 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   This file is part of the GNU C Library.
   Contributed by David Mosberger (davidm@azstarnet.com).
   Contributed by David Mosberger (davidm@azstarnet.com).
 
 
   The GNU C Library is free software; you can redistribute it and/or
   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   version 2.1 of the License, or (at your option) any later version.
 
 
   The GNU C Library is distributed in the hope that it will be useful,
   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   Lesser General Public License for more details.
 
 
   You should have received a copy of the GNU Lesser General Public
   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */
   02111-1307 USA.  */
 
 
/* This file provides a Linux /etc/host.conf compatible front end to
/* This file provides a Linux /etc/host.conf compatible front end to
   the various name resolvers (/etc/hosts, named, NIS server, etc.).
   the various name resolvers (/etc/hosts, named, NIS server, etc.).
   Though mostly compatibly, the following differences exist compared
   Though mostly compatibly, the following differences exist compared
   to the original implementation:
   to the original implementation:
 
 
        - new command "spoof" takes an arguments like RESOLV_SPOOF_CHECK
        - new command "spoof" takes an arguments like RESOLV_SPOOF_CHECK
          environment variable (i.e., `off', `nowarn', or `warn').
          environment variable (i.e., `off', `nowarn', or `warn').
 
 
        - line comments can appear anywhere (not just at the beginning of
        - line comments can appear anywhere (not just at the beginning of
          a line)
          a line)
*/
*/
 
 
#include <assert.h>
#include <assert.h>
#include <errno.h>
#include <errno.h>
#include <ctype.h>
#include <ctype.h>
#include <libintl.h>
#include <libintl.h>
#include <memory.h>
#include <memory.h>
#include <stdio.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <net/if.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/in.h>
#define _IO_MTSAFE_IO
#define _IO_MTSAFE_IO
#include <bits/libc-lock.h>
#include <bits/libc-lock.h>
#include "ifreq.h"
#include "ifreq.h"
#include "res_hconf.h"
#include "res_hconf.h"
#include "local.h"
#include "local.h"
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
# include <wchar.h>
# include <wchar.h>
#endif
#endif
 
 
#define _PATH_HOSTCONF  "/etc/host.conf"
#define _PATH_HOSTCONF  "/etc/host.conf"
 
 
/* Environment vars that all user to override default behavior:  */
/* Environment vars that all user to override default behavior:  */
#define ENV_HOSTCONF    "RESOLV_HOST_CONF"
#define ENV_HOSTCONF    "RESOLV_HOST_CONF"
#define ENV_SERVORDER   "RESOLV_SERV_ORDER"
#define ENV_SERVORDER   "RESOLV_SERV_ORDER"
#define ENV_SPOOF       "RESOLV_SPOOF_CHECK"
#define ENV_SPOOF       "RESOLV_SPOOF_CHECK"
#define ENV_TRIM_OVERR  "RESOLV_OVERRIDE_TRIM_DOMAINS"
#define ENV_TRIM_OVERR  "RESOLV_OVERRIDE_TRIM_DOMAINS"
#define ENV_TRIM_ADD    "RESOLV_ADD_TRIM_DOMAINS"
#define ENV_TRIM_ADD    "RESOLV_ADD_TRIM_DOMAINS"
#define ENV_MULTI       "RESOLV_MULTI"
#define ENV_MULTI       "RESOLV_MULTI"
#define ENV_REORDER     "RESOLV_REORDER"
#define ENV_REORDER     "RESOLV_REORDER"
 
 
static const char *arg_service_list (const char *, int, const char *,
static const char *arg_service_list (const char *, int, const char *,
                                     unsigned int);
                                     unsigned int);
static const char *arg_trimdomain_list (const char *, int, const char *,
static const char *arg_trimdomain_list (const char *, int, const char *,
                                        unsigned int);
                                        unsigned int);
static const char *arg_spoof (const char *, int, const char *, unsigned int);
static const char *arg_spoof (const char *, int, const char *, unsigned int);
static const char *arg_bool (const char *, int, const char *, unsigned int);
static const char *arg_bool (const char *, int, const char *, unsigned int);
 
 
static struct cmd
static struct cmd
{
{
  const char *name;
  const char *name;
  const char *(*parse_args) (const char * filename, int line_num,
  const char *(*parse_args) (const char * filename, int line_num,
                             const char * args, unsigned int arg);
                             const char * args, unsigned int arg);
  unsigned int arg;
  unsigned int arg;
} cmd[] =
} cmd[] =
{
{
  {"order",             arg_service_list,       0},
  {"order",             arg_service_list,       0},
  {"trim",              arg_trimdomain_list,    0},
  {"trim",              arg_trimdomain_list,    0},
  {"spoof",             arg_spoof,              0},
  {"spoof",             arg_spoof,              0},
  {"multi",             arg_bool,               HCONF_FLAG_MULTI},
  {"multi",             arg_bool,               HCONF_FLAG_MULTI},
  {"nospoof",           arg_bool,               HCONF_FLAG_SPOOF},
  {"nospoof",           arg_bool,               HCONF_FLAG_SPOOF},
  {"spoofalert",        arg_bool,               HCONF_FLAG_SPOOFALERT},
  {"spoofalert",        arg_bool,               HCONF_FLAG_SPOOFALERT},
  {"reorder",           arg_bool,               HCONF_FLAG_REORDER}
  {"reorder",           arg_bool,               HCONF_FLAG_REORDER}
};
};
 
 
/* Structure containing the state.  */
/* Structure containing the state.  */
struct hconf _res_hconf;
struct hconf _res_hconf;
 
 
/* Skip white space.  */
/* Skip white space.  */
static const char *
static const char *
skip_ws (const char *str)
skip_ws (const char *str)
{
{
  while (isspace (*str)) ++str;
  while (isspace (*str)) ++str;
  return str;
  return str;
}
}
 
 
 
 
/* Skip until whitespace, comma, end of line, or comment character.  */
/* Skip until whitespace, comma, end of line, or comment character.  */
static const char *
static const char *
skip_string (const char *str)
skip_string (const char *str)
{
{
  while (*str && !isspace (*str) && *str != '#' && *str != ',')
  while (*str && !isspace (*str) && *str != '#' && *str != ',')
    ++str;
    ++str;
  return str;
  return str;
}
}
 
 
 
 
static const char *
static const char *
arg_service_list (const char *fname, int line_num, const char *args,
arg_service_list (const char *fname, int line_num, const char *args,
                  unsigned int arg)
                  unsigned int arg)
{
{
  enum Name_Service service;
  enum Name_Service service;
  const char *start;
  const char *start;
  size_t len;
  size_t len;
  size_t i;
  size_t i;
  static struct
  static struct
  {
  {
    const char * name;
    const char * name;
    enum Name_Service service;
    enum Name_Service service;
  } svcs[] =
  } svcs[] =
    {
    {
      {"bind",  SERVICE_BIND},
      {"bind",  SERVICE_BIND},
      {"hosts", SERVICE_HOSTS},
      {"hosts", SERVICE_HOSTS},
      {"nis",   SERVICE_NIS},
      {"nis",   SERVICE_NIS},
    };
    };
 
 
  do
  do
    {
    {
      start = args;
      start = args;
      args = skip_string (args);
      args = skip_string (args);
      len = args - start;
      len = args - start;
 
 
      service = SERVICE_NONE;
      service = SERVICE_NONE;
      for (i = 0; i < sizeof (svcs) / sizeof (svcs[0]); ++i)
      for (i = 0; i < sizeof (svcs) / sizeof (svcs[0]); ++i)
        {
        {
          if (strncasecmp (start, svcs[i].name, len) == 0
          if (strncasecmp (start, svcs[i].name, len) == 0
              && len == strlen (svcs[i].name))
              && len == strlen (svcs[i].name))
          {
          {
            service = svcs[i].service;
            service = svcs[i].service;
            break;
            break;
          }
          }
      }
      }
      if (service == SERVICE_NONE)
      if (service == SERVICE_NONE)
        {
        {
          char *buf;
          char *buf;
 
 
          if (asprintf (&buf,
          if (asprintf (&buf,
                          _("%s: line %d: expected service, found `%s'\n"),
                          _("%s: line %d: expected service, found `%s'\n"),
                          fname, line_num, start) < 0)
                          fname, line_num, start) < 0)
            return 0;
            return 0;
 
 
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
          if (_IO_fwide (stderr, 0) > 0)
          if (_IO_fwide (stderr, 0) > 0)
            __fwprintf (stderr, L"%s", buf);
            __fwprintf (stderr, L"%s", buf);
          else
          else
#endif
#endif
            fputs (buf, stderr);
            fputs (buf, stderr);
 
 
          free (buf);
          free (buf);
          return 0;
          return 0;
        }
        }
      if (_res_hconf.num_services >= SERVICE_MAX)
      if (_res_hconf.num_services >= SERVICE_MAX)
        {
        {
          char *buf;
          char *buf;
 
 
          if (asprintf (&buf, _("\
          if (asprintf (&buf, _("\
%s: line %d: cannot specify more than %d services"),
%s: line %d: cannot specify more than %d services"),
                          fname, line_num, SERVICE_MAX) < 0)
                          fname, line_num, SERVICE_MAX) < 0)
            return 0;
            return 0;
 
 
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
          if (_IO_fwide (stderr, 0) > 0)
          if (_IO_fwide (stderr, 0) > 0)
            __fwprintf (stderr, L"%s", buf);
            __fwprintf (stderr, L"%s", buf);
          else
          else
#endif
#endif
            fputs (buf, stderr);
            fputs (buf, stderr);
 
 
          free (buf);
          free (buf);
          return 0;
          return 0;
        }
        }
      _res_hconf.service[_res_hconf.num_services++] = service;
      _res_hconf.service[_res_hconf.num_services++] = service;
 
 
      args = skip_ws (args);
      args = skip_ws (args);
      switch (*args)
      switch (*args)
        {
        {
        case ',':
        case ',':
        case ';':
        case ';':
        case ':':
        case ':':
          args = skip_ws (++args);
          args = skip_ws (++args);
          if (!*args || *args == '#')
          if (!*args || *args == '#')
            {
            {
              char *buf;
              char *buf;
 
 
              if (asprintf (&buf, _("\
              if (asprintf (&buf, _("\
%s: line %d: list delimiter not followed by keyword"),
%s: line %d: list delimiter not followed by keyword"),
                              fname, line_num) < 0)
                              fname, line_num) < 0)
                return 0;
                return 0;
 
 
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
              if (_IO_fwide (stderr, 0) > 0)
              if (_IO_fwide (stderr, 0) > 0)
                __fwprintf (stderr, L"%s", buf);
                __fwprintf (stderr, L"%s", buf);
              else
              else
#endif
#endif
                fputs (buf, stderr);
                fputs (buf, stderr);
 
 
              free (buf);
              free (buf);
              return 0;
              return 0;
            }
            }
        default:
        default:
          break;
          break;
        }
        }
    }
    }
  while (*args && *args != '#');
  while (*args && *args != '#');
  return args;
  return args;
}
}
 
 
 
 
static const char *
static const char *
arg_trimdomain_list (const char *fname, int line_num, const char *args,
arg_trimdomain_list (const char *fname, int line_num, const char *args,
                     unsigned int flag)
                     unsigned int flag)
{
{
  const char * start;
  const char * start;
  size_t len;
  size_t len;
 
 
  do
  do
    {
    {
      start = args;
      start = args;
      args = skip_string (args);
      args = skip_string (args);
      len = args - start;
      len = args - start;
 
 
      if (_res_hconf.num_trimdomains >= TRIMDOMAINS_MAX)
      if (_res_hconf.num_trimdomains >= TRIMDOMAINS_MAX)
        {
        {
          char *buf;
          char *buf;
 
 
          if (asprintf (&buf, _("\
          if (asprintf (&buf, _("\
%s: line %d: cannot specify more than %d trim domains"),
%s: line %d: cannot specify more than %d trim domains"),
                          fname, line_num, TRIMDOMAINS_MAX) < 0)
                          fname, line_num, TRIMDOMAINS_MAX) < 0)
            return 0;
            return 0;
 
 
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
              if (_IO_fwide (stderr, 0) > 0)
              if (_IO_fwide (stderr, 0) > 0)
                __fwprintf (stderr, L"%s", buf);
                __fwprintf (stderr, L"%s", buf);
              else
              else
#endif
#endif
                fputs (buf, stderr);
                fputs (buf, stderr);
 
 
              free (buf);
              free (buf);
          return 0;
          return 0;
        }
        }
      _res_hconf.trimdomain[_res_hconf.num_trimdomains++] =
      _res_hconf.trimdomain[_res_hconf.num_trimdomains++] =
        strndup (start, len);
        strndup (start, len);
      args = skip_ws (args);
      args = skip_ws (args);
      switch (*args)
      switch (*args)
        {
        {
        case ',': case ';': case ':':
        case ',': case ';': case ':':
          args = skip_ws (++args);
          args = skip_ws (++args);
          if (!*args || *args == '#')
          if (!*args || *args == '#')
            {
            {
              char *buf;
              char *buf;
 
 
              if (asprintf (&buf, _("\
              if (asprintf (&buf, _("\
%s: line %d: list delimiter not followed by domain"),
%s: line %d: list delimiter not followed by domain"),
                              fname, line_num) < 0)
                              fname, line_num) < 0)
                return 0;
                return 0;
 
 
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
              if (_IO_fwide (stderr, 0) > 0)
              if (_IO_fwide (stderr, 0) > 0)
                __fwprintf (stderr, L"%s", buf);
                __fwprintf (stderr, L"%s", buf);
              else
              else
#endif
#endif
                fputs (buf, stderr);
                fputs (buf, stderr);
 
 
              free (buf);
              free (buf);
              return 0;
              return 0;
            }
            }
        default:
        default:
          break;
          break;
        }
        }
    }
    }
  while (*args && *args != '#');
  while (*args && *args != '#');
  return args;
  return args;
}
}
 
 
 
 
static const char *
static const char *
arg_spoof (const char *fname, int line_num, const char *args, unsigned flag)
arg_spoof (const char *fname, int line_num, const char *args, unsigned flag)
{
{
  const char *start = args;
  const char *start = args;
  size_t len;
  size_t len;
 
 
  args = skip_string (args);
  args = skip_string (args);
  len = args - start;
  len = args - start;
 
 
  if (len == 3 && strncasecmp (start, "off", len) == 0)
  if (len == 3 && strncasecmp (start, "off", len) == 0)
    _res_hconf.flags &= ~(HCONF_FLAG_SPOOF | HCONF_FLAG_SPOOFALERT);
    _res_hconf.flags &= ~(HCONF_FLAG_SPOOF | HCONF_FLAG_SPOOFALERT);
  else
  else
    {
    {
      _res_hconf.flags |= (HCONF_FLAG_SPOOF | HCONF_FLAG_SPOOFALERT);
      _res_hconf.flags |= (HCONF_FLAG_SPOOF | HCONF_FLAG_SPOOFALERT);
      if ((len == 6 && strncasecmp (start, "nowarn", len) == 0)
      if ((len == 6 && strncasecmp (start, "nowarn", len) == 0)
          || !(len == 4 && strncasecmp (start, "warn", len) == 0))
          || !(len == 4 && strncasecmp (start, "warn", len) == 0))
        _res_hconf.flags &= ~HCONF_FLAG_SPOOFALERT;
        _res_hconf.flags &= ~HCONF_FLAG_SPOOFALERT;
    }
    }
  return args;
  return args;
}
}
 
 
 
 
static const char *
static const char *
arg_bool (const char *fname, int line_num, const char *args, unsigned flag)
arg_bool (const char *fname, int line_num, const char *args, unsigned flag)
{
{
  if (strncasecmp (args, "on", 2) == 0)
  if (strncasecmp (args, "on", 2) == 0)
    {
    {
      args += 2;
      args += 2;
      _res_hconf.flags |= flag;
      _res_hconf.flags |= flag;
    }
    }
  else if (strncasecmp (args, "off", 3) == 0)
  else if (strncasecmp (args, "off", 3) == 0)
    {
    {
      args += 3;
      args += 3;
      _res_hconf.flags &= ~flag;
      _res_hconf.flags &= ~flag;
    }
    }
  else
  else
    {
    {
      char *buf;
      char *buf;
 
 
      if (asprintf (&buf,
      if (asprintf (&buf,
                      _("%s: line %d: expected `on' or `off', found `%s'\n"),
                      _("%s: line %d: expected `on' or `off', found `%s'\n"),
                      fname, line_num, args) < 0)
                      fname, line_num, args) < 0)
        return 0;
        return 0;
 
 
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
      if (_IO_fwide (stderr, 0) > 0)
        __fwprintf (stderr, L"%s", buf);
        __fwprintf (stderr, L"%s", buf);
      else
      else
#endif
#endif
        fputs (buf, stderr);
        fputs (buf, stderr);
 
 
      free (buf);
      free (buf);
      return 0;
      return 0;
    }
    }
  return args;
  return args;
}
}
 
 
 
 
static void
static void
parse_line (const char *fname, int line_num, const char *str)
parse_line (const char *fname, int line_num, const char *str)
{
{
  const char *start;
  const char *start;
  struct cmd *c = 0;
  struct cmd *c = 0;
  size_t len;
  size_t len;
  size_t i;
  size_t i;
 
 
  str = skip_ws (str);
  str = skip_ws (str);
 
 
  /* skip line comment and empty lines: */
  /* skip line comment and empty lines: */
  if (*str == '\0' || *str == '#') return;
  if (*str == '\0' || *str == '#') return;
 
 
  start = str;
  start = str;
  str = skip_string (str);
  str = skip_string (str);
  len = str - start;
  len = str - start;
 
 
  for (i = 0; i < sizeof (cmd) / sizeof (cmd[0]); ++i)
  for (i = 0; i < sizeof (cmd) / sizeof (cmd[0]); ++i)
    {
    {
      if (strncasecmp (start, cmd[i].name, len) == 0
      if (strncasecmp (start, cmd[i].name, len) == 0
          && strlen (cmd[i].name) == len)
          && strlen (cmd[i].name) == len)
        {
        {
          c = &cmd[i];
          c = &cmd[i];
          break;
          break;
        }
        }
    }
    }
  if (c == NULL)
  if (c == NULL)
    {
    {
      char *buf;
      char *buf;
 
 
      if (asprintf (&buf, _("%s: line %d: bad command `%s'\n"),
      if (asprintf (&buf, _("%s: line %d: bad command `%s'\n"),
                      fname, line_num, start) < 0)
                      fname, line_num, start) < 0)
        return;
        return;
 
 
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
      if (_IO_fwide (stderr, 0) > 0)
        __fwprintf (stderr, L"%s", buf);
        __fwprintf (stderr, L"%s", buf);
      else
      else
#endif
#endif
        fputs (buf, stderr);
        fputs (buf, stderr);
 
 
      free (buf);
      free (buf);
      return;
      return;
    }
    }
 
 
  /* process args: */
  /* process args: */
  str = skip_ws (str);
  str = skip_ws (str);
  str = (*c->parse_args) (fname, line_num, str, c->arg);
  str = (*c->parse_args) (fname, line_num, str, c->arg);
  if (!str)
  if (!str)
    return;
    return;
 
 
  /* rest of line must contain white space or comment only: */
  /* rest of line must contain white space or comment only: */
  while (*str)
  while (*str)
    {
    {
      if (!isspace (*str)) {
      if (!isspace (*str)) {
        if (*str != '#')
        if (*str != '#')
          {
          {
            char *buf;
            char *buf;
 
 
            if (asprintf (&buf,
            if (asprintf (&buf,
                            _("%s: line %d: ignoring trailing garbage `%s'\n"),
                            _("%s: line %d: ignoring trailing garbage `%s'\n"),
                            fname, line_num, str) < 0)
                            fname, line_num, str) < 0)
              break;
              break;
 
 
#ifdef USE_IN_LIBIO
#ifdef USE_IN_LIBIO
            if (_IO_fwide (stderr, 0) > 0)
            if (_IO_fwide (stderr, 0) > 0)
              __fwprintf (stderr, L"%s", buf);
              __fwprintf (stderr, L"%s", buf);
            else
            else
#endif
#endif
              fputs (buf, stderr);
              fputs (buf, stderr);
 
 
            free (buf);
            free (buf);
          }
          }
        break;
        break;
      }
      }
      ++str;
      ++str;
    }
    }
}
}
 
 
 
 
static void
static void
do_init (void)
do_init (void)
{
{
  const char *hconf_name;
  const char *hconf_name;
  int line_num = 0;
  int line_num = 0;
  char buf[256], *envval;
  char buf[256], *envval;
  FILE *fp;
  FILE *fp;
 
 
  memset (&_res_hconf, '\0', sizeof (_res_hconf));
  memset (&_res_hconf, '\0', sizeof (_res_hconf));
 
 
  hconf_name = getenv (ENV_HOSTCONF);
  hconf_name = getenv (ENV_HOSTCONF);
  if (hconf_name == NULL)
  if (hconf_name == NULL)
    hconf_name = _PATH_HOSTCONF;
    hconf_name = _PATH_HOSTCONF;
 
 
  fp = fopen (hconf_name, "rc");
  fp = fopen (hconf_name, "rc");
  if (!fp)
  if (!fp)
    /* make up something reasonable: */
    /* make up something reasonable: */
    _res_hconf.service[_res_hconf.num_services++] = SERVICE_BIND;
    _res_hconf.service[_res_hconf.num_services++] = SERVICE_BIND;
  else
  else
    {
    {
      /* No threads using this stream.  */
      /* No threads using this stream.  */
      __fsetlocking (fp, FSETLOCKING_BYCALLER);
      __fsetlocking (fp, FSETLOCKING_BYCALLER);
 
 
      while (fgets (buf, sizeof (buf), fp))
      while (fgets (buf, sizeof (buf), fp))
        {
        {
          char *tmp;
          char *tmp;
          ++line_num;
          ++line_num;
          tmp = strchr (buf, '\n');
          tmp = strchr (buf, '\n');
          if (tmp != NULL)
          if (tmp != NULL)
            *tmp = '\0';
            *tmp = '\0';
          parse_line (hconf_name, line_num, buf);
          parse_line (hconf_name, line_num, buf);
        }
        }
      fclose (fp);
      fclose (fp);
    }
    }
 
 
  envval = getenv (ENV_SERVORDER);
  envval = getenv (ENV_SERVORDER);
  if (envval)
  if (envval)
    {
    {
      _res_hconf.num_services = 0;
      _res_hconf.num_services = 0;
      arg_service_list (ENV_SERVORDER, 1, envval, 0);
      arg_service_list (ENV_SERVORDER, 1, envval, 0);
    }
    }
 
 
  envval = getenv (ENV_SPOOF);
  envval = getenv (ENV_SPOOF);
  if (envval)
  if (envval)
    arg_spoof (ENV_SPOOF, 1, envval, 0);
    arg_spoof (ENV_SPOOF, 1, envval, 0);
 
 
  envval = getenv (ENV_MULTI);
  envval = getenv (ENV_MULTI);
  if (envval)
  if (envval)
    arg_bool (ENV_MULTI, 1, envval, HCONF_FLAG_MULTI);
    arg_bool (ENV_MULTI, 1, envval, HCONF_FLAG_MULTI);
 
 
  envval = getenv (ENV_REORDER);
  envval = getenv (ENV_REORDER);
  if (envval)
  if (envval)
    arg_bool (ENV_REORDER, 1, envval, HCONF_FLAG_REORDER);
    arg_bool (ENV_REORDER, 1, envval, HCONF_FLAG_REORDER);
 
 
  envval = getenv (ENV_TRIM_ADD);
  envval = getenv (ENV_TRIM_ADD);
  if (envval)
  if (envval)
    arg_trimdomain_list (ENV_TRIM_ADD, 1, envval, 0);
    arg_trimdomain_list (ENV_TRIM_ADD, 1, envval, 0);
 
 
  envval = getenv (ENV_TRIM_OVERR);
  envval = getenv (ENV_TRIM_OVERR);
  if (envval)
  if (envval)
    {
    {
      _res_hconf.num_trimdomains = 0;
      _res_hconf.num_trimdomains = 0;
      arg_trimdomain_list (ENV_TRIM_OVERR, 1, envval, 0);
      arg_trimdomain_list (ENV_TRIM_OVERR, 1, envval, 0);
    }
    }
 
 
  _res_hconf.initialized = 1;
  _res_hconf.initialized = 1;
}
}
 
 
 
 
/* Initialize hconf datastructure by reading host.conf file and
/* Initialize hconf datastructure by reading host.conf file and
   environment variables.  */
   environment variables.  */
void
void
_res_hconf_init (void)
_res_hconf_init (void)
{
{
  __libc_once_define (static, once);
  __libc_once_define (static, once);
 
 
  __libc_once (once, do_init);
  __libc_once (once, do_init);
}
}
 
 
 
 
/* List of known interfaces.  */
/* List of known interfaces.  */
libc_freeres_ptr (
libc_freeres_ptr (
static struct netaddr
static struct netaddr
{
{
  int addrtype;
  int addrtype;
  union
  union
  {
  {
    struct
    struct
    {
    {
      u_int32_t addr;
      u_int32_t addr;
      u_int32_t mask;
      u_int32_t mask;
    } ipv4;
    } ipv4;
  } u;
  } u;
} *ifaddrs);
} *ifaddrs);
 
 
/* We need to protect the dynamic buffer handling.  */
/* We need to protect the dynamic buffer handling.  */
__libc_lock_define_initialized (static, lock);
__libc_lock_define_initialized (static, lock);
 
 
/* Reorder addresses returned in a hostent such that the first address
/* Reorder addresses returned in a hostent such that the first address
   is an address on the local subnet, if there is such an address.
   is an address on the local subnet, if there is such an address.
   Otherwise, nothing is changed.
   Otherwise, nothing is changed.
 
 
   Note that this function currently only handles IPv4 addresses.  */
   Note that this function currently only handles IPv4 addresses.  */
 
 
void
void
_res_hconf_reorder_addrs (struct hostent *hp)
_res_hconf_reorder_addrs (struct hostent *hp)
{
{
#if defined SIOCGIFCONF && defined SIOCGIFNETMASK
#if defined SIOCGIFCONF && defined SIOCGIFNETMASK
  int i, j;
  int i, j;
  /* Number of interfaces.  */
  /* Number of interfaces.  */
  static int num_ifs = -1;
  static int num_ifs = -1;
 
 
  /* Only reorder if we're supposed to.  */
  /* Only reorder if we're supposed to.  */
  if ((_res_hconf.flags & HCONF_FLAG_REORDER) == 0)
  if ((_res_hconf.flags & HCONF_FLAG_REORDER) == 0)
    return;
    return;
 
 
  /* Can't deal with anything but IPv4 for now...  */
  /* Can't deal with anything but IPv4 for now...  */
  if (hp->h_addrtype != AF_INET)
  if (hp->h_addrtype != AF_INET)
    return;
    return;
 
 
  if (num_ifs <= 0)
  if (num_ifs <= 0)
    {
    {
      struct ifreq *ifr, *cur_ifr;
      struct ifreq *ifr, *cur_ifr;
      int sd, num, i;
      int sd, num, i;
      /* Save errno.  */
      /* Save errno.  */
      int save = errno;
      int save = errno;
 
 
      /* Initialize interface table.  */
      /* Initialize interface table.  */
 
 
      num_ifs = 0;
      num_ifs = 0;
 
 
      /* The SIOCGIFNETMASK ioctl will only work on an AF_INET socket.  */
      /* The SIOCGIFNETMASK ioctl will only work on an AF_INET socket.  */
      sd = socket (AF_INET, SOCK_DGRAM, 0);
      sd = socket (AF_INET, SOCK_DGRAM, 0);
      if (sd < 0)
      if (sd < 0)
        return;
        return;
 
 
      /* Get lock.  */
      /* Get lock.  */
      __libc_lock_lock (lock);
      __libc_lock_lock (lock);
 
 
      /* Get a list of interfaces.  */
      /* Get a list of interfaces.  */
      __ifreq (&ifr, &num, sd);
      __ifreq (&ifr, &num, sd);
      if (!ifr)
      if (!ifr)
        goto cleanup;
        goto cleanup;
 
 
      ifaddrs = malloc (num * sizeof (ifaddrs[0]));
      ifaddrs = malloc (num * sizeof (ifaddrs[0]));
      if (!ifaddrs)
      if (!ifaddrs)
        goto cleanup1;
        goto cleanup1;
 
 
      /* Copy usable interfaces in ifaddrs structure.  */
      /* Copy usable interfaces in ifaddrs structure.  */
      for (cur_ifr = ifr, i = 0; i < num; cur_ifr = __if_nextreq (cur_ifr), ++i)
      for (cur_ifr = ifr, i = 0; i < num; cur_ifr = __if_nextreq (cur_ifr), ++i)
        {
        {
          if (cur_ifr->ifr_addr.sa_family != AF_INET)
          if (cur_ifr->ifr_addr.sa_family != AF_INET)
            continue;
            continue;
 
 
          ifaddrs[num_ifs].addrtype = AF_INET;
          ifaddrs[num_ifs].addrtype = AF_INET;
          ifaddrs[num_ifs].u.ipv4.addr =
          ifaddrs[num_ifs].u.ipv4.addr =
            ((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr;
            ((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr;
 
 
          if (ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0)
          if (ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0)
            continue;
            continue;
 
 
          ifaddrs[num_ifs].u.ipv4.mask =
          ifaddrs[num_ifs].u.ipv4.mask =
            ((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr;
            ((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr;
 
 
          /* Now we're committed to this entry.  */
          /* Now we're committed to this entry.  */
          ++num_ifs;
          ++num_ifs;
        }
        }
      /* Just keep enough memory to hold all the interfaces we want.  */
      /* Just keep enough memory to hold all the interfaces we want.  */
      ifaddrs = realloc (ifaddrs, num_ifs * sizeof (ifaddrs[0]));
      ifaddrs = realloc (ifaddrs, num_ifs * sizeof (ifaddrs[0]));
      assert (ifaddrs != NULL);
      assert (ifaddrs != NULL);
 
 
    cleanup1:
    cleanup1:
      __if_freereq (ifr, num);
      __if_freereq (ifr, num);
 
 
    cleanup:
    cleanup:
      /* Release lock, preserve error value, and close socket.  */
      /* Release lock, preserve error value, and close socket.  */
      save = errno;
      save = errno;
      __libc_lock_unlock (lock);
      __libc_lock_unlock (lock);
      close (sd);
      close (sd);
    }
    }
 
 
  if (num_ifs == 0)
  if (num_ifs == 0)
    return;
    return;
 
 
  /* Find an address for which we have a direct connection.  */
  /* Find an address for which we have a direct connection.  */
  for (i = 0; hp->h_addr_list[i]; ++i)
  for (i = 0; hp->h_addr_list[i]; ++i)
    {
    {
      struct in_addr *haddr = (struct in_addr *) hp->h_addr_list[i];
      struct in_addr *haddr = (struct in_addr *) hp->h_addr_list[i];
 
 
      for (j = 0; j < num_ifs; ++j)
      for (j = 0; j < num_ifs; ++j)
        {
        {
          u_int32_t if_addr    = ifaddrs[j].u.ipv4.addr;
          u_int32_t if_addr    = ifaddrs[j].u.ipv4.addr;
          u_int32_t if_netmask = ifaddrs[j].u.ipv4.mask;
          u_int32_t if_netmask = ifaddrs[j].u.ipv4.mask;
 
 
          if (((haddr->s_addr ^ if_addr) & if_netmask) == 0)
          if (((haddr->s_addr ^ if_addr) & if_netmask) == 0)
            {
            {
              void *tmp;
              void *tmp;
 
 
              tmp = hp->h_addr_list[i];
              tmp = hp->h_addr_list[i];
              hp->h_addr_list[i] = hp->h_addr_list[0];
              hp->h_addr_list[i] = hp->h_addr_list[0];
              hp->h_addr_list[0] = tmp;
              hp->h_addr_list[0] = tmp;
              return;
              return;
            }
            }
        }
        }
    }
    }
#endif /* defined(SIOCGIFCONF) && ... */
#endif /* defined(SIOCGIFCONF) && ... */
}
}
 
 
 
 
/* If HOSTNAME has a postfix matching any of the trimdomains, trim away
/* If HOSTNAME has a postfix matching any of the trimdomains, trim away
   that postfix.  Notice that HOSTNAME is modified inplace.  Also, the
   that postfix.  Notice that HOSTNAME is modified inplace.  Also, the
   original code applied all trimdomains in order, meaning that the
   original code applied all trimdomains in order, meaning that the
   same domainname could be trimmed multiple times.  I believe this
   same domainname could be trimmed multiple times.  I believe this
   was unintentional.  */
   was unintentional.  */
void
void
_res_hconf_trim_domain (char *hostname)
_res_hconf_trim_domain (char *hostname)
{
{
  size_t hostname_len, trim_len;
  size_t hostname_len, trim_len;
  int i;
  int i;
 
 
  hostname_len = strlen (hostname);
  hostname_len = strlen (hostname);
 
 
  for (i = 0; i < _res_hconf.num_trimdomains; ++i)
  for (i = 0; i < _res_hconf.num_trimdomains; ++i)
    {
    {
      const char *trim = _res_hconf.trimdomain[i];
      const char *trim = _res_hconf.trimdomain[i];
 
 
      trim_len = strlen (trim);
      trim_len = strlen (trim);
      if (hostname_len > trim_len
      if (hostname_len > trim_len
          && strcasecmp (&hostname[hostname_len - trim_len], trim) == 0)
          && strcasecmp (&hostname[hostname_len - trim_len], trim) == 0)
        {
        {
          hostname[hostname_len - trim_len] = '\0';
          hostname[hostname_len - trim_len] = '\0';
          break;
          break;
        }
        }
    }
    }
}
}
 
 
 
 
/* Trim all hostnames/aliases in HP according to the trimdomain list.
/* Trim all hostnames/aliases in HP according to the trimdomain list.
   Notice that HP is modified inplace!  */
   Notice that HP is modified inplace!  */
void
void
_res_hconf_trim_domains (struct hostent *hp)
_res_hconf_trim_domains (struct hostent *hp)
{
{
  int i;
  int i;
 
 
  if (_res_hconf.num_trimdomains == 0)
  if (_res_hconf.num_trimdomains == 0)
    return;
    return;
 
 
  _res_hconf_trim_domain (hp->h_name);
  _res_hconf_trim_domain (hp->h_name);
  for (i = 0; hp->h_aliases[i]; ++i)
  for (i = 0; hp->h_aliases[i]; ++i)
    _res_hconf_trim_domain (hp->h_aliases[i]);
    _res_hconf_trim_domain (hp->h_aliases[i]);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.