diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2012-08-19 16:17:41 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2012-08-19 16:17:41 +0000 |
commit | fd61f36b2861343b5f5d10cd950a4e9eb9b51425 (patch) | |
tree | 8b8e24578395221b33fc7b5f9a09892f597e52ac /lib/libc/asr/getnetnamadr_async.c | |
parent | 0c0c72d3447ee021bcc2674934484c9aa1f2b59a (diff) |
When building dynamic hostent and netent, allocate a single linear buffer to
hold both the structure and the data. The freehostent() and freenetent() API
functions are not needed anymore. While there, ensure that the constructed
addr and alias lists are really NULL terminated.
Diffstat (limited to 'lib/libc/asr/getnetnamadr_async.c')
-rw-r--r-- | lib/libc/asr/getnetnamadr_async.c | 67 |
1 files changed, 32 insertions, 35 deletions
diff --git a/lib/libc/asr/getnetnamadr_async.c b/lib/libc/asr/getnetnamadr_async.c index 70efc2962f2..bc03a643166 100644 --- a/lib/libc/asr/getnetnamadr_async.c +++ b/lib/libc/asr/getnetnamadr_async.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getnetnamadr_async.c,v 1.2 2012/07/10 17:30:38 eric Exp $ */ +/* $OpenBSD: getnetnamadr_async.c,v 1.3 2012/08/19 16:17:40 eric Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> * @@ -32,6 +32,11 @@ #define MAXALIASES 16 +#define NETENT_PTR(n) ((char**)(((char*)n) + sizeof (*n))) +#define NETENT_POS(n) NETENT_PTR(n)[0] +#define NETENT_STOP(n) NETENT_PTR(n)[1] +#define NETENT_LEFT(n) (NETENT_STOP(n) - NETENT_POS(n)) + ssize_t addr_as_fqdn(const char *, int, char *, size_t); static int getnetnamadr_async_run(struct async *, struct async_res *); @@ -229,7 +234,7 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar) if (as->as_type == ASR_GETNETBYNAME && ar->ar_netent->n_net == 0) { /* XXX wrong */ - freenetent(ar->ar_netent); + free(ar->ar_netent); async_set_state(as, ASR_STATE_NEXT_DB); } else { ar->ar_h_errno = NETDB_SUCCESS; @@ -303,7 +308,7 @@ found: e->n_net = inet_network(tokens[1]); return (e); fail: - freenetent(e); + free(e); return (NULL); } @@ -358,7 +363,7 @@ netent_from_packet(int reqtype, char *pkt, size_t pktlen) return (n); fail: - freenetent(n); + free(n); return (NULL); } @@ -366,17 +371,17 @@ static struct netent * netent_alloc(int family) { struct netent *n; + size_t alloc; - n = calloc(1, sizeof *n); - if (n == NULL) + alloc = sizeof(*n) + (2 + MAXALIASES) * sizeof(char*) + 1024; + if ((n = calloc(1, alloc)) == NULL) return (NULL); - n->n_aliases = calloc(MAXALIASES, sizeof *n->n_aliases); - if (n->n_aliases == NULL) { - freenetent(n); - return (NULL); - } n->n_addrtype = family; + n->n_aliases = NETENT_PTR(n) + 2; + + NETENT_STOP(n) = (char*)(n) + alloc; + NETENT_POS(n) = (char *)(n->n_aliases + MAXALIASES); return (n); } @@ -392,12 +397,14 @@ netent_set_cname(struct netent *n, const char *name, int isdname) if (isdname) { asr_strdname(name, buf, sizeof buf); buf[strlen(buf) - 1] = '\0'; - n->n_name = strdup(buf); - } else { - n->n_name = strdup(name); + name = buf; } - if (n->n_name == NULL) - return (-1); + if (strlen(name) + 1 >= NETENT_LEFT(n)) + return (1); + + strlcpy(NETENT_POS(n), name, NETENT_LEFT(n)); + n->n_name = NETENT_POS(n); + NETENT_POS(n) += strlen(name) + 1; return (0); } @@ -408,33 +415,23 @@ netent_add_alias(struct netent *n, const char *name, int isdname) char buf[MAXDNAME]; size_t i; - for (i = 0; i < MAXALIASES; i++) + for (i = 0; i < MAXALIASES - 1; i++) if (n->n_aliases[i] == NULL) break; - if (i == MAXALIASES) + if (i == MAXALIASES - 1) return (0); if (isdname) { asr_strdname(name, buf, sizeof buf); buf[strlen(buf)-1] = '\0'; - n->n_aliases[i] = strdup(buf); - } else { - n->n_aliases[i] = strdup(name); + name = buf; } - if (n->n_aliases[i] == NULL) - return (-1); + if (strlen(name) + 1 >= NETENT_LEFT(n)) + return (1); - return (0); -} - -void -freenetent(struct netent *n) -{ - char **c; + strlcpy(NETENT_POS(n), name, NETENT_LEFT(n)); + n->n_aliases[i] = NETENT_POS(n); + NETENT_POS(n) += strlen(name) + 1; - free(n->n_name); - for (c = n->n_aliases; *c; c++) - free(*c); - free(n->n_aliases); - free(n); + return (0); } |