summaryrefslogtreecommitdiff
path: root/contrib/bind/lib/irs/lcl_nw.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/lib/irs/lcl_nw.c')
-rw-r--r--contrib/bind/lib/irs/lcl_nw.c148
1 files changed, 129 insertions, 19 deletions
diff --git a/contrib/bind/lib/irs/lcl_nw.c b/contrib/bind/lib/irs/lcl_nw.c
index 09a324cc3b7e7..0d41ec409e97c 100644
--- a/contrib/bind/lib/irs/lcl_nw.c
+++ b/contrib/bind/lib/irs/lcl_nw.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996 by Internet Software Consortium.
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_nw.c,v 1.13 1997/12/04 04:57:57 halley Exp $";
+static const char rcsid[] = "$Id: lcl_nw.c,v 1.21 1999/10/15 19:49:10 vixie Exp $";
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
#endif /* LIBC_SCCS and not lint */
@@ -59,18 +59,21 @@ static const char rcsid[] = "$Id: lcl_nw.c,v 1.13 1997/12/04 04:57:57 halley Exp
#include "port_before.h"
#include <sys/types.h>
+#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#include <sys/socket.h>
+#include <arpa/nameser.h>
#include <errno.h>
#include <fcntl.h>
+#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <irs.h>
+#include <isc/memcluster.h>
#include "port_after.h"
@@ -87,6 +90,8 @@ struct pvt {
struct nwent net;
char * aliases[MAXALIASES];
char addr[MAXADDRSIZE];
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forward */
@@ -97,6 +102,12 @@ static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
static struct nwent * nw_next(struct irs_nw *);
static void nw_rewind(struct irs_nw *);
static void nw_minimize(struct irs_nw *);
+static struct __res_state * nw_res_get(struct irs_nw *this);
+static void nw_res_set(struct irs_nw *this,
+ struct __res_state *res,
+ void (*free_res)(void *));
+
+static int init(struct irs_nw *this);
/* Portability. */
@@ -111,17 +122,17 @@ irs_lcl_nw(struct irs_acc *this) {
struct irs_nw *nw;
struct pvt *pvt;
- if (!(nw = (struct irs_nw *)malloc(sizeof *nw))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
- memset(nw, 0x5e, sizeof *nw);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(nw);
+ memset(pvt, 0, sizeof *pvt);
+ if (!(nw = memget(sizeof *nw))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
- memset(pvt, 0, sizeof *pvt);
+ memset(nw, 0x5e, sizeof *nw);
nw->private = pvt;
nw->close = nw_close;
nw->byname = nw_byname;
@@ -129,6 +140,8 @@ irs_lcl_nw(struct irs_acc *this) {
nw->next = nw_next;
nw->rewind = nw_rewind;
nw->minimize = nw_minimize;
+ nw->res_get = nw_res_get;
+ nw->res_set = nw_res_set;
return (nw);
}
@@ -138,16 +151,22 @@ static void
nw_close(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ nw_minimize(this);
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
if (pvt->fp)
(void)fclose(pvt->fp);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct nwent *
nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
struct nwent *p;
+ if (init(this) == -1)
+ return(NULL);
+
nw_rewind(this);
while ((p = nw_next(this)) != NULL)
if (p->n_addrtype == type && p->n_length == length)
@@ -161,13 +180,16 @@ nw_byname(struct irs_nw *this, const char *name, int type) {
struct nwent *p;
char **ap;
+ if (init(this) == -1)
+ return(NULL);
+
nw_rewind(this);
while ((p = nw_next(this)) != NULL) {
- if (strcasecmp(p->n_name, name) == 0 &&
+ if (ns_samename(p->n_name, name) == 1 &&
p->n_addrtype == type)
break;
for (ap = p->n_aliases; *ap; ap++)
- if ((strcasecmp(*ap, name) == 0) &&
+ if ((ns_samename(*ap, name) == 1) &&
(p->n_addrtype == type))
goto found;
}
@@ -195,24 +217,60 @@ nw_rewind(struct irs_nw *this) {
static struct nwent *
nw_next(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ struct nwent *ret = NULL;
char *p, *cp, **q;
+ char *bufp, *ndbuf, *dbuf = NULL;
+ int c, bufsiz, offset = 0;
+
+ if (init(this) == -1)
+ return(NULL);
if (pvt->fp == NULL)
nw_rewind(this);
if (pvt->fp == NULL) {
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
+ bufp = pvt->line;
+ bufsiz = sizeof(pvt->line);
+
again:
- p = fgets(pvt->line, BUFSIZ, pvt->fp);
+ p = fgets(bufp + offset, bufsiz - offset, pvt->fp);
if (p == NULL)
- return (NULL);
+ goto cleanup;
+ if (!strchr(p, '\n') && !feof(pvt->fp)) {
+#define GROWBUF 1024
+ /* allocate space for longer line */
+ if (dbuf == NULL) {
+ if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
+ strcpy(ndbuf, bufp);
+ } else
+ ndbuf = realloc(dbuf, bufsiz + GROWBUF);
+ if (ndbuf) {
+ dbuf = ndbuf;
+ bufp = dbuf;
+ bufsiz += GROWBUF;
+ offset = strlen(dbuf);
+ } else {
+ /* allocation failed; skip this long line */
+ while ((c = getc(pvt->fp)) != EOF)
+ if (c == '\n')
+ break;
+ if (c != EOF)
+ ungetc(c, pvt->fp);
+ }
+ goto again;
+ }
+
+ p -= offset;
+ offset = 0;
+
if (*p == '#')
goto again;
+
cp = strpbrk(p, "#\n");
- if (cp == NULL)
- goto again;
- *cp = '\0';
+ if (cp != NULL)
+ *cp = '\0';
pvt->net.n_name = p;
cp = strpbrk(p, " \t");
if (cp == NULL)
@@ -245,15 +303,67 @@ nw_next(struct irs_nw *this) {
}
}
*q = NULL;
- return (&pvt->net);
+ ret = &pvt->net;
+
+ cleanup:
+ if (dbuf)
+ free(dbuf);
+
+ return (ret);
}
static void
nw_minimize(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ if (pvt->res)
+ res_nclose(pvt->res);
if (pvt->fp != NULL) {
(void)fclose(pvt->fp);
pvt->fp = NULL;
}
}
+
+static struct __res_state *
+nw_res_get(struct irs_nw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (!pvt->res) {
+ struct __res_state *res;
+ res = (struct __res_state *)malloc(sizeof *res);
+ if (!res) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(res, 0, sizeof *res);
+ nw_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+nw_res_set(struct irs_nw *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (pvt->res && pvt->free_res) {
+ res_nclose(pvt->res);
+ (*pvt->free_res)(pvt->res);
+ }
+
+ pvt->res = res;
+ pvt->free_res = free_res;
+}
+
+static int
+init(struct irs_nw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (!pvt->res && !nw_res_get(this))
+ return (-1);
+ if (((pvt->res->options & RES_INIT) == 0) &&
+ res_ninit(pvt->res) == -1)
+ return (-1);
+ return (0);
+}