resolv: Use getline for configuration file reading in res_vinit_1

This commit is contained in:
Florian Weimer 2017-06-16 20:54:43 +02:00
parent ea4924ce5b
commit 89f187a40f
2 changed files with 49 additions and 24 deletions

View File

@ -1,3 +1,9 @@
2017-06-16 Florian Weimer <fweimer@redhat.com>
* resolv/res_init.c (res_vinit_1): Use getline to read from the
configuration file.
(__res_vinit): Adjust.
2017-06-19 Florian Weimer <fweimer@redhat.com> 2017-06-19 Florian Weimer <fweimer@redhat.com>
* resolv/res_init.c (res_vinit_1): New function. * resolv/res_init.c (res_vinit_1): New function.

View File

@ -126,10 +126,10 @@ is_sort_mask (char ch)
deallocation and error handling. Return true on success, false on deallocation and error handling. Return true on success, false on
failure. */ failure. */
static bool static bool
res_vinit_1 (res_state statp, bool preinit, FILE *fp) res_vinit_1 (res_state statp, bool preinit, FILE *fp, char **buffer)
{ {
char *cp, **pp; char *cp, **pp;
char buf[BUFSIZ]; size_t buffer_size = 0;
int nserv = 0; /* Number of nameservers read from file. */ int nserv = 0; /* Number of nameservers read from file. */
bool have_serv6 = false; bool have_serv6 = false;
bool haveenv = false; bool haveenv = false;
@ -197,27 +197,38 @@ res_vinit_1 (res_state statp, bool preinit, FILE *fp)
} }
#define MATCH(line, name) \ #define MATCH(line, name) \
(!strncmp (line, name, sizeof (name) - 1) \ (!strncmp ((line), name, sizeof (name) - 1) \
&& (line[sizeof (name) - 1] == ' ' \ && ((line)[sizeof (name) - 1] == ' ' \
|| line[sizeof (name) - 1] == '\t')) || (line)[sizeof (name) - 1] == '\t'))
if (fp != NULL) if (fp != NULL)
{ {
/* No threads use this stream. */ /* No threads use this stream. */
__fsetlocking (fp, FSETLOCKING_BYCALLER); __fsetlocking (fp, FSETLOCKING_BYCALLER);
/* Read the config file. */ /* Read the config file. */
while (__fgets_unlocked (buf, sizeof (buf), fp) != NULL) while (true)
{ {
{
ssize_t ret = __getline (buffer, &buffer_size, fp);
if (ret <= 0)
{
if (_IO_ferror_unlocked (fp))
return false;
else
break;
}
}
/* Skip comments. */ /* Skip comments. */
if (*buf == ';' || *buf == '#') if (**buffer == ';' || **buffer == '#')
continue; continue;
/* Read default domain name. */ /* Read default domain name. */
if (MATCH (buf, "domain")) if (MATCH (*buffer, "domain"))
{ {
if (haveenv) if (haveenv)
/* LOCALDOMAIN overrides the configuration file. */ /* LOCALDOMAIN overrides the configuration file. */
continue; continue;
cp = buf + sizeof ("domain") - 1; cp = *buffer + sizeof ("domain") - 1;
while (*cp == ' ' || *cp == '\t') while (*cp == ' ' || *cp == '\t')
cp++; cp++;
if ((*cp == '\0') || (*cp == '\n')) if ((*cp == '\0') || (*cp == '\n'))
@ -230,12 +241,12 @@ res_vinit_1 (res_state statp, bool preinit, FILE *fp)
continue; continue;
} }
/* Set search list. */ /* Set search list. */
if (MATCH (buf, "search")) if (MATCH (*buffer, "search"))
{ {
if (haveenv) if (haveenv)
/* LOCALDOMAIN overrides the configuration file. */ /* LOCALDOMAIN overrides the configuration file. */
continue; continue;
cp = buf + sizeof ("search") - 1; cp = *buffer + sizeof ("search") - 1;
while (*cp == ' ' || *cp == '\t') while (*cp == ' ' || *cp == '\t')
cp++; cp++;
if ((*cp == '\0') || (*cp == '\n')) if ((*cp == '\0') || (*cp == '\n'))
@ -271,11 +282,11 @@ res_vinit_1 (res_state statp, bool preinit, FILE *fp)
continue; continue;
} }
/* Read nameservers to query. */ /* Read nameservers to query. */
if (MATCH (buf, "nameserver") && nserv < MAXNS) if (MATCH (*buffer, "nameserver") && nserv < MAXNS)
{ {
struct in_addr a; struct in_addr a;
cp = buf + sizeof ("nameserver") - 1; cp = *buffer + sizeof ("nameserver") - 1;
while (*cp == ' ' || *cp == '\t') while (*cp == ' ' || *cp == '\t')
cp++; cp++;
if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a)) if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a))
@ -300,7 +311,7 @@ res_vinit_1 (res_state statp, bool preinit, FILE *fp)
sa6 = malloc (sizeof (*sa6)); sa6 = malloc (sizeof (*sa6));
if (sa6 == NULL) if (sa6 == NULL)
return -1; return false;
sa6->sin6_family = AF_INET6; sa6->sin6_family = AF_INET6;
sa6->sin6_port = htons (NAMESERVER_PORT); sa6->sin6_port = htons (NAMESERVER_PORT);
@ -323,11 +334,11 @@ res_vinit_1 (res_state statp, bool preinit, FILE *fp)
} }
continue; continue;
} }
if (MATCH (buf, "sortlist")) if (MATCH (*buffer, "sortlist"))
{ {
struct in_addr a; struct in_addr a;
cp = buf + sizeof ("sortlist") - 1; cp = *buffer + sizeof ("sortlist") - 1;
while (nsort < MAXRESOLVSORT) while (nsort < MAXRESOLVSORT)
{ {
while (*cp == ' ' || *cp == '\t') while (*cp == ' ' || *cp == '\t')
@ -367,9 +378,9 @@ res_vinit_1 (res_state statp, bool preinit, FILE *fp)
} }
continue; continue;
} }
if (MATCH (buf, "options")) if (MATCH (*buffer, "options"))
{ {
res_setoptions (statp, buf + sizeof ("options") - 1, "conf"); res_setoptions (statp, *buffer + sizeof ("options") - 1, "conf");
continue; continue;
} }
} }
@ -387,10 +398,13 @@ res_vinit_1 (res_state statp, bool preinit, FILE *fp)
statp->nsaddr.sin_port = htons (NAMESERVER_PORT); statp->nsaddr.sin_port = htons (NAMESERVER_PORT);
statp->nscount = 1; statp->nscount = 1;
} }
if (statp->defdname[0] == 0 if (statp->defdname[0] == 0)
&& __gethostname (buf, sizeof (statp->defdname) - 1) == 0 {
&& (cp = strchr (buf, '.')) != NULL) char buf[sizeof (statp->defdname)];
strcpy (statp->defdname, cp + 1); if (__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. */ /* Find components of local domain that might be searched. */
if (!havesearch) if (!havesearch)
@ -404,7 +418,7 @@ res_vinit_1 (res_state statp, bool preinit, FILE *fp)
if ((cp = getenv ("RES_OPTIONS")) != NULL) if ((cp = getenv ("RES_OPTIONS")) != NULL)
res_setoptions (statp, cp, "env"); res_setoptions (statp, cp, "env");
statp->options |= RES_INIT; statp->options |= RES_INIT;
return 0; return true;
} }
/* Set up default settings. If the /etc/resolv.conf configuration /* Set up default settings. If the /etc/resolv.conf configuration
@ -434,7 +448,12 @@ __res_vinit (res_state statp, int preinit)
need to be handled by the application. */ need to be handled by the application. */
return -1; return -1;
} }
if (!res_vinit_1 (statp, preinit, fp))
char *buffer = NULL;
bool ok = res_vinit_1 (statp, preinit, fp, &buffer);
free (buffer);
if (!ok)
{ {
/* Deallocate the name server addresses which have been /* Deallocate the name server addresses which have been
allocated. */ allocated. */