diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2012-07-10 17:30:39 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2012-07-10 17:30:39 +0000 |
commit | df4fcfae18e3a99514e10dd634f3a067ccd685f5 (patch) | |
tree | 73fc9c1f1bc5c60efd9b019cb33a7606e25cc72d /lib/libc | |
parent | 3671c8df0fcddd23dbac584e79c861ff7c4ce654 (diff) |
same code update and fix as for gethostnamadr_async
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/asr/getnetnamadr_async.c | 132 |
1 files changed, 77 insertions, 55 deletions
diff --git a/lib/libc/asr/getnetnamadr_async.c b/lib/libc/asr/getnetnamadr_async.c index 0bc8a36cfb0..70efc2962f2 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.1 2012/04/14 09:24:18 eric Exp $ */ +/* $OpenBSD: getnetnamadr_async.c,v 1.2 2012/07/10 17:30:38 eric Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> * @@ -38,8 +38,8 @@ static int getnetnamadr_async_run(struct async *, struct async_res *); static struct netent *netent_alloc(int); static int netent_set_cname(struct netent *, const char *, int); static int netent_add_alias(struct netent *, const char *, int); -static int netent_file_match(FILE *, int, const char *, char **, int); -static int netent_from_packet(struct netent *, int, char *, size_t); +static struct netent *netent_file_match(FILE *, int, const char *); +static struct netent *netent_from_packet(int, char *, size_t); struct async * getnetbyname_async(const char *name, struct asr *asr) @@ -100,10 +100,9 @@ getnetbyaddr_async(in_addr_t net, int family, struct asr *asr) static int getnetnamadr_async_run(struct async *as, struct async_res *ar) { - struct netent *e; - int i, n, r, type; - FILE *f; - char *toks[MAXTOKEN], dname[MAXDNAME], *name, *data; + int i, n, r, type; + FILE *f; + char dname[MAXDNAME], *name, *data; in_addr_t in; next: @@ -171,27 +170,21 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar) data = as->as.netnamadr.name; else data = (void*)&as->as.netnamadr.addr; - n = netent_file_match(f, as->as_type, data, toks, - MAXTOKEN); - if (n == -1) { - fclose(f); - break; - } - e = netent_alloc(as->as.netnamadr.family); - if (e == NULL) { - ar->ar_errno = errno; - ar->ar_h_errno = NETDB_INTERNAL; - async_set_state(as, ASR_STATE_HALT); + + ar->ar_netent = netent_file_match(f, as->as_type, data); + fclose(f); + + if (ar->ar_netent == NULL) { + if (errno) { + ar->ar_errno = errno; + ar->ar_h_errno = NETDB_INTERNAL; + async_set_state(as, ASR_STATE_HALT); + } + /* otherwise not found */ break; } - netent_set_cname(e, toks[0], 0); - for (i = 2; i < n; i ++) - netent_add_alias(e, toks[i], 0); - e->n_net = inet_network(toks[1]); - fclose(f); ar->ar_h_errno = NETDB_SUCCESS; - ar->ar_netent = e; async_set_state(as, ASR_STATE_HALT); break; } @@ -215,31 +208,31 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar) break; } - if ((e = netent_alloc(as->as.netnamadr.family)) == NULL) { + ar->ar_netent = netent_from_packet(as->as_type, ar->ar_data, + ar->ar_datalen); + free(ar->ar_data); + + if (ar->ar_netent == NULL) { ar->ar_errno = errno; ar->ar_h_errno = NETDB_INTERNAL; - free(ar->ar_data); async_set_state(as, ASR_STATE_HALT); break; } if (as->as_type == ASR_GETNETBYADDR) - e->n_net = as->as.netnamadr.addr; - - netent_from_packet(e, as->as_type, ar->ar_data, ar->ar_datalen); - free(ar->ar_data); + ar->ar_netent->n_net = as->as.netnamadr.addr; /* * No address found in the dns packet. The blocking version * reports this as an error. */ - if (as->as_type == ASR_GETNETBYNAME && e->n_net == 0) { + if (as->as_type == ASR_GETNETBYNAME && + ar->ar_netent->n_net == 0) { /* XXX wrong */ - freenetent(e); + freenetent(ar->ar_netent); async_set_state(as, ASR_STATE_NEXT_DB); } else { ar->ar_h_errno = NETDB_SUCCESS; - ar->ar_netent = e; async_set_state(as, ASR_STATE_HALT); } break; @@ -269,75 +262,104 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar) goto next; } -static int -netent_file_match(FILE *f, int type, const char *data, char **tokens, - int ntokens) +static struct netent * +netent_file_match(FILE *f, int reqtype, const char *data) { - int n, i; - in_addr_t net; + struct netent *e; + char *tokens[MAXTOKEN]; + int n, i; + in_addr_t net; for(;;) { n = asr_parse_namedb_line(f, tokens, MAXTOKEN); - if (n == -1) - return (-1); + if (n == -1) { + errno = 0; /* ignore errors reading the file */ + return (NULL); + } - if (type == ASR_GETNETBYADDR) { + if (reqtype == ASR_GETNETBYADDR) { net = inet_network(tokens[1]); if (memcmp(&net, data, sizeof net) == 0) - return (n); + goto found; } else { for (i = 0; i < n; i++) { if (i == 1) continue; if (strcasecmp(data, tokens[i])) continue; - return (n); + goto found; } } } + +found: + if ((e = netent_alloc(AF_INET)) == NULL) + return (NULL); + if (netent_set_cname(e, tokens[0], 0) == -1) + goto fail; + for (i = 2; i < n; i ++) + if (netent_add_alias(e, tokens[i], 0) == -1) + goto fail; + e->n_net = inet_network(tokens[1]); + return (e); +fail: + freenetent(e); + return (NULL); } -static int -netent_from_packet(struct netent *n, int action, char *pkt, size_t pktlen) +static struct netent * +netent_from_packet(int reqtype, char *pkt, size_t pktlen) { + struct netent *n; struct packed p; struct header hdr; struct query q; struct rr rr; - int r; + + if ((n = netent_alloc(AF_INET)) == NULL) + return (NULL); packed_init(&p, pkt, pktlen); unpack_header(&p, &hdr); for(; hdr.qdcount; hdr.qdcount--) unpack_query(&p, &q); - for(; hdr.ancount; hdr.ancount--) { unpack_rr(&p, &rr); if (rr.rr_class != C_IN) continue; switch (rr.rr_type) { case T_CNAME: - if (action == ASR_GETNETBYNAME) - r = netent_add_alias(n, rr.rr_dname, 1); - else - r = netent_set_cname(n, rr.rr_dname, 1); + if (reqtype == ASR_GETNETBYNAME) { + if (netent_add_alias(n, rr.rr_dname, 1) == -1) + goto fail; + } else { + if (netent_set_cname(n, rr.rr_dname, 1) == -1) + goto fail; + } break; + case T_PTR: - if (action != ASR_GETNETBYADDR) + if (reqtype != ASR_GETNETBYADDR) continue; - r = netent_set_cname(n, rr.rr.ptr.ptrname, 1); + if (netent_set_cname(n, rr.rr.ptr.ptrname, 1) == -1) + goto fail; /* XXX See if we need to have MULTI_PTRS_ARE_ALIASES */ break; + case T_A: if (n->n_addrtype != AF_INET) break; - r = netent_set_cname(n, rr.rr_dname, 1); + if (netent_set_cname(n, rr.rr_dname, 1) == -1) + goto fail; n->n_net = ntohl(rr.rr.in_a.addr.s_addr); break; } } - return (0); + return (n); +fail: + freenetent(n); + return (NULL); } static struct netent * |