aboutsummaryrefslogtreecommitdiff
path: root/arlib/arlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'arlib/arlib.c')
-rw-r--r--arlib/arlib.c1056
1 files changed, 0 insertions, 1056 deletions
diff --git a/arlib/arlib.c b/arlib/arlib.c
deleted file mode 100644
index 3d76e5749336..000000000000
--- a/arlib/arlib.c
+++ /dev/null
@@ -1,1056 +0,0 @@
-/*
- * arlib.c (C)opyright 1993 Darren Reed. All rights reserved.
- * This file may not be distributed without the author's permission in any
- * shape or form. The author takes no responsibility for any damage or loss
- * of property which results from the use of this software.
- */
-#ifndef lint
-static char sccsid[] = "@(#)arlib.c 1.9 6/5/93 (C)opyright 1992 Darren \
-Reed. ASYNC DNS";
-#endif
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "netdb.h"
-#include "arpa/nameser.h"
-#include <resolv.h>
-#include "arlib.h"
-#include "arplib.h"
-
-extern int errno, h_errno;
-static char ar_hostbuf[65], ar_domainname[65];
-static char ar_dot[] = ".";
-static int ar_resfd = -1, ar_vc = 0;
-static struct reslist *ar_last, *ar_first;
-
-/*
- * Statistics structure.
- */
-static struct resstats {
- int re_errors;
- int re_nu_look;
- int re_na_look;
- int re_replies;
- int re_requests;
- int re_resends;
- int re_sent;
- int re_timeouts;
-} ar_reinfo;
-
-static int do_query_name(/* struct resinfo *, char *, struct reslist * */);
-static int do_query_number(/* struct resinfo *, char *, struct reslist * */);
-static int ar_resend_query(/* struct reslist * */);
-
-/*
- * ar_init
- *
- * Initializes the various ARLIB internal varilables and related DNS
- * options for res_init().
- *
- * Returns 0 or the socket opened for use with talking to name servers
- * if 0 is passed or ARES_INITSOCK is set.
- */
-int ar_init(op)
-int op;
-{
- int ret = 0;
-
- if (op & ARES_INITLIST)
- {
- bzero(&ar_reinfo, sizeof(ar_reinfo));
- ar_first = ar_last = NULL;
- }
-
- if (op & ARES_CALLINIT && !(_res.options & RES_INIT))
- {
- ret = res_init();
- (void)strcpy(ar_domainname, ar_dot);
- (void)strncat(ar_domainname, _res.defdname,
- sizeof(ar_domainname)-2);
- }
-
- if (op & ARES_INITSOCK)
- ret = ar_resfd = ar_open();
-
- if (op & ARES_INITDEBG)
- _res.options |= RES_DEBUG;
-
- if (op == 0)
- ret = ar_resfd;
-
- return ret;
-}
-
-
-/*
- * ar_open
- *
- * Open a socket to talk to a name server with.
- * Check _res.options to see if we use a TCP or UDP socket.
- */
-int ar_open()
-{
- if (ar_resfd == -1)
- {
- if (_res.options & RES_USEVC)
- {
- struct sockaddr_in *sip;
- int i;
-
- sip = _res.NS_ADDR_LIST; /* was _res.nsaddr_list */
- ar_vc = 1;
- ar_resfd = socket(AF_INET, SOCK_STREAM, 0);
-
- /*
- * Try each name server listed in sequence until we
- * succeed or run out.
- */
- while (connect(ar_resfd, (struct sockaddr *)sip++,
- sizeof(struct sockaddr)))
- {
- (void)close(ar_resfd);
- ar_resfd = -1;
- if (i >= _res.nscount)
- break;
- ar_resfd = socket(AF_INET, SOCK_STREAM, 0);
- }
- }
- else
- ar_resfd = socket(AF_INET, SOCK_DGRAM, 0);
- }
- if (ar_resfd >= 0)
- { /* Need one of these two here - and it MUST work!! */
- int flags;
-
- if ((flags = fcntl(ar_resfd, F_GETFL, 0)) != -1)
-#ifdef O_NONBLOCK
- if (fcntl(ar_resfd, F_SETFL, flags|O_NONBLOCK) == -1)
-#else
-# ifdef O_NDELAY
- if (fcntl(ar_resfd, F_SETFL, flags|O_NDELAY) == -1)
-# else
-# ifdef FNDELAY
- if (fcntl(ar_resfd, F_SETFL, flags|FNDELAY) == -1)
-# endif
-# endif
-#endif
- {
- (void)close(ar_resfd);
- ar_resfd = -1;
- }
- }
- return ar_resfd;
-}
-
-
-/*
- * ar_close
- *
- * Closes and flags the ARLIB socket as closed.
- */
-void ar_close()
-{
- (void)close(ar_resfd);
- ar_resfd = -1;
- return;
-}
-
-
-/*
- * ar_add_request
- *
- * Add a new DNS query to the end of the query list.
- */
-static int ar_add_request(new)
-struct reslist *new;
-{
- if (!new)
- return -1;
- if (!ar_first)
- ar_first = ar_last = new;
- else {
- ar_last->re_next = new;
- ar_last = new;
- }
- new->re_next = NULL;
- ar_reinfo.re_requests++;
- return 0;
-}
-
-
-/*
- * ar_remrequest
- *
- * Remove a request from the list. This must also free any memory that has
- * been allocated for temporary storage of DNS results.
- *
- * Returns -1 if there are anyy problems removing the requested structure
- * or 0 if the remove is successful.
- */
-static int ar_remrequest(old)
-struct reslist *old;
-{
- register struct reslist *rptr, *r2ptr;
- register char **s;
-
- if (!old)
- return -1;
- for (rptr = ar_first, r2ptr = NULL; rptr; rptr = rptr->re_next)
- {
- if (rptr == old)
- break;
- r2ptr = rptr;
- }
-
- if (!rptr)
- return -1;
- if (rptr == ar_first)
- ar_first = ar_first->re_next;
- else if (rptr == ar_last)
- {
- if (ar_last = r2ptr)
- ar_last->re_next = NULL;
- }
- else
- r2ptr->re_next = rptr->re_next;
-
- if (!ar_first)
- ar_last = ar_first;
-
-#ifdef ARLIB_DEBUG
- ar_dump_hostent("ar_remrequest:", rptr->re_he);
-#endif
-
- if (rptr->re_he.h_name)
- (void)free(rptr->re_he.h_name);
- if (s = rptr->re_he.h_aliases)
- for (; *s; s++)
- (void)free(*s);
- if (rptr->re_rinfo.ri_ptr)
- (void)free(rptr->re_rinfo.ri_ptr);
- (void)free(rptr);
-
- return 0;
-}
-
-
-/*
- * ar_make_request
- *
- * Create a DNS query recorded for the request being made and place it on the
- * current list awaiting replies. Initialization of the record with set
- * values should also be done.
- */
-static struct reslist *ar_make_request(resi)
-register struct resinfo *resi;
-{
- register struct reslist *rptr;
- register struct resinfo *rp;
-
- rptr = (struct reslist *)calloc(1, sizeof(struct reslist));
- rp = &rptr->re_rinfo;
-
- rptr->re_next = NULL; /* where NULL is non-zero ;) */
- rptr->re_sentat = time(NULL);
- rptr->re_retries = _res.retry;
- rptr->re_sends = 1;
- rptr->re_resend = 1;
- rptr->re_timeout = rptr->re_sentat + _res.retrans;
- rptr->re_he.h_name = NULL;
- rptr->re_he.h_addrtype = AF_INET;
- rptr->re_he.h_aliases[0] = NULL;
- rp->ri_ptr = resi->ri_ptr;
- rp->ri_size = resi->ri_size;
-
- (void)ar_add_request(rptr);
-
- return rptr;
-}
-
-
-/*
- * ar_timeout
- *
- * Remove queries from the list which have been there too long without
- * being resolved.
- */
-long ar_timeout(now, info, size)
-time_t now;
-char *info;
-int size;
-{
- register struct reslist *rptr, *r2ptr;
- register long next = 0;
-
- for (rptr = ar_first, r2ptr = NULL; rptr; rptr = r2ptr)
- {
- r2ptr = rptr->re_next;
- if (now >= rptr->re_timeout)
- {
- /*
- * If the timeout for the query has been exceeded,
- * then resend the query if we still have some
- * 'retry credit' and reset the timeout. If we have
- * used it all up, then remove the request.
- */
- if (--rptr->re_retries <= 0)
- {
- ar_reinfo.re_timeouts++;
- if (info && rptr->re_rinfo.ri_ptr)
- bcopy(rptr->re_rinfo.ri_ptr, info,
- MIN(rptr->re_rinfo.ri_size,
- size));
- (void)ar_remrequest(rptr);
- return now;
- }
- else
- {
- rptr->re_sends++;
- rptr->re_sentat = now;
- rptr->re_timeout = now + _res.retrans;
- (void)ar_resend_query(rptr);
- }
- }
- if (!next || rptr->re_timeout < next)
- next = rptr->re_timeout;
- }
- return next;
-}
-
-
-/*
- * ar_send_res_msg
- *
- * When sending queries to nameservers listed in the resolv.conf file,
- * don't send a query to every one, but increase the number sent linearly
- * to match the number of resends. This increase only occurs if there are
- * multiple nameserver entries in the resolv.conf file.
- * The return value is the number of messages successfully sent to
- * nameservers or -1 if no successful sends.
- */
-static int ar_send_res_msg(msg, len, rcount)
-char *msg;
-int len, rcount;
-{
- register int i;
- int sent = 0;
-
- if (!msg)
- return -1;
-
- rcount = (_res.nscount > rcount) ? rcount : _res.nscount;
- if (_res.options & RES_PRIMARY)
- rcount = 1;
-
- if (ar_vc)
- {
- ar_reinfo.re_sent++;
- sent++;
- if (write(ar_resfd, msg, len) == -1)
- {
- int errtmp = errno;
- (void)close(ar_resfd);
- errno = errtmp;
- ar_resfd = -1;
- }
- }
- else
- for (i = 0; i < rcount; i++)
- {
- if (sendto(ar_resfd, msg, len, 0,
- (struct sockaddr *)&(_res.NS_ADDR_LIST[i]),
- sizeof(struct sockaddr_in)) == len)
- {
- ar_reinfo.re_sent++;
- sent++;
- }
- }
- return (sent) ? sent : -1;
-}
-
-
-/*
- * ar_find_id
- *
- * find a dns query record by the id (id is determined by dn_mkquery)
- */
-static struct reslist *ar_find_id(id)
-int id;
-{
- register struct reslist *rptr;
-
- for (rptr = ar_first; rptr; rptr = rptr->re_next)
- if (rptr->re_id == id)
- return rptr;
- return NULL;
-}
-
-
-/*
- * ar_delete
- *
- * Delete a request from the waiting list if it has a data pointer which
- * matches the one passed.
- */
-int ar_delete(ptr, size)
-char *ptr;
-int size;
-{
- register struct reslist *rptr;
- register struct reslist *r2ptr;
- int removed = 0;
-
- for (rptr = ar_first; rptr; rptr = r2ptr)
- {
- r2ptr = rptr->re_next;
- if (rptr->re_rinfo.ri_ptr && ptr && size &&
- bcmp(rptr->re_rinfo.ri_ptr, ptr, size) == 0)
- {
- (void)ar_remrequest(rptr);
- removed++;
- }
- }
- return removed;
-}
-
-
-/*
- * ar_query_name
- *
- * generate a query based on class, type and name.
- */
-static int ar_query_name(name, class, type, rptr)
-char *name;
-int class, type;
-struct reslist *rptr;
-{
- static char buf[MAXPACKET];
- int r,s,a;
- HEADER *hptr;
-
- bzero(buf, sizeof(buf));
- r = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
- buf, sizeof(buf));
- if (r <= 0)
- {
- h_errno = NO_RECOVERY;
- return r;
- }
- hptr = (HEADER *)buf;
- rptr->re_id = ntohs(hptr->id);
-
- s = ar_send_res_msg(buf, r, rptr->re_sends);
-
- if (s == -1)
- {
- h_errno = TRY_AGAIN;
- return -1;
- }
- else
- rptr->re_sent += s;
- return 0;
-}
-
-
-/*
- * ar_gethostbyname
- *
- * Replacement library function call to gethostbyname(). This one, however,
- * doesn't return the record being looked up but just places the query in the
- * queue to await answers.
- */
-int ar_gethostbyname(name, info, size)
-char *name;
-char *info;
-int size;
-{
- char host[65];
- struct resinfo resi;
- register struct resinfo *rp = &resi;
-
- if (size && info)
- {
- rp->ri_ptr = (char *)malloc(size);
- bcopy(info, rp->ri_ptr, size);
- rp->ri_size = size;
- }
- else
- bzero((char *)rp, sizeof(resi));
- ar_reinfo.re_na_look++;
- (void)strncpy(host, name, 64);
- host[64] = '\0';
-
- return (do_query_name(rp, host, NULL));
-}
-
-
-static int do_query_name(resi, name, rptr)
-struct resinfo *resi;
-char *name;
-register struct reslist *rptr;
-{
- char hname[65];
- int len;
-
- len = strlen((char *)strncpy(hname, name, sizeof(hname)-1));
-
- if (rptr && (hname[len-1] != '.'))
- {
- (void)strncat(hname, ar_dot, sizeof(hname)-len-1);
- /*
- * NOTE: The logical relationship between DNSRCH and DEFNAMES
- * is implies. ie no DEFNAES, no DNSRCH.
- */
- if (_res.options & (RES_DEFNAMES|RES_DNSRCH) ==
- (RES_DEFNAMES|RES_DNSRCH))
- {
- if (_res.dnsrch[rptr->re_srch])
- (void)strncat(hname, _res.dnsrch[rptr->re_srch],
- sizeof(hname) - ++len -1);
- }
- else if (_res.options & RES_DEFNAMES)
- (void)strncat(hname, ar_domainname, sizeof(hname) - len -1);
- }
-
- /*
- * Store the name passed as the one to lookup and generate other host
- * names to pass onto the nameserver(s) for lookups.
- */
- if (!rptr)
- {
- rptr = ar_make_request(resi);
- rptr->re_type = T_A;
- (void)strncpy(rptr->re_name, name, sizeof(rptr->re_name)-1);
- }
- return (ar_query_name(hname, C_IN, T_A, rptr));
-}
-
-
-/*
- * ar_gethostbyaddr
- *
- * Generates a query for a given IP address.
- */
-int ar_gethostbyaddr(addr, info, size)
-char *addr;
-char *info;
-int size;
-{
- struct resinfo resi;
- register struct resinfo *rp = &resi;
-
- if (size && info)
- {
- rp->ri_ptr = (char *)malloc(size);
- bcopy(info, rp->ri_ptr, size);
- rp->ri_size = size;
- }
- else
- bzero((char *)rp, sizeof(resi));
- ar_reinfo.re_nu_look++;
- return (do_query_number(rp, addr, NULL));
-}
-
-
-/*
- * do_query_number
- *
- * Use this to do reverse IP# lookups.
- */
-static int do_query_number(resi, numb, rptr)
-struct resinfo *resi;
-char *numb;
-register struct reslist *rptr;
-{
- register unsigned char *cp;
- static char ipbuf[32];
-
- /*
- * Generate name in the "in-addr.arpa" domain. No addings bits to this
- * name to get more names to query!.
- */
- cp = (unsigned char *)numb;
- (void)sprintf(ipbuf,"%u.%u.%u.%u.in-addr.arpa.",
- (unsigned int)(cp[3]), (unsigned int)(cp[2]),
- (unsigned int)(cp[1]), (unsigned int)(cp[0]));
-
- if (!rptr)
- {
- rptr = ar_make_request(resi);
- rptr->re_type = T_PTR;
- rptr->re_he.h_length = sizeof(struct in_addr);
- bcopy(numb, (char *)&rptr->re_addr, rptr->re_he.h_length);
- bcopy(numb, (char *)&rptr->re_he.h_addr_list[0].s_addr,
- rptr->re_he.h_length);
- }
- return (ar_query_name(ipbuf, C_IN, T_PTR, rptr));
-}
-
-
-/*
- * ar_resent_query
- *
- * resends a query.
- */
-static int ar_resend_query(rptr)
-struct reslist *rptr;
-{
- if (!rptr->re_resend)
- return -1;
-
- switch(rptr->re_type)
- {
- case T_PTR:
- ar_reinfo.re_resends++;
- return do_query_number(NULL, &rptr->re_addr, rptr);
- case T_A:
- ar_reinfo.re_resends++;
- return do_query_name(NULL, rptr->re_name, rptr);
- default:
- break;
- }
-
- return -1;
-}
-
-
-/*
- * ar_procanswer
- *
- * process an answer received from a nameserver.
- */
-static int ar_procanswer(rptr, hptr, buf, eob)
-struct reslist *rptr;
-char *buf, *eob;
-HEADER *hptr;
-{
- char *cp, **alias, *s;
- int class, type, dlen, len, ans = 0, n, i;
- u_int32_t ttl, dr, *adr;
- struct hent *hp;
-
- cp = buf + sizeof(HEADER);
- adr = (u_int32_t *)rptr->re_he.h_addr_list;
-
- while (*adr)
- adr++;
-
- alias = rptr->re_he.h_aliases;
- while (*alias)
- alias++;
-
- hp = &rptr->re_he;
-
-
- /*
- * Skip over the original question.
- */
- while (hptr->qdcount-- > 0)
- cp += dn_skipname(cp, eob) + QFIXEDSZ;
- /*
- * proccess each answer sent to us. blech.
- */
- while (hptr->ancount-- > 0 && cp < eob) {
- n = dn_expand(buf, eob, cp, ar_hostbuf, sizeof(ar_hostbuf));
- cp += n;
- if (n <= 0)
- return ans;
-
- ans++;
- /*
- * 'skip' past the general dns crap (ttl, class, etc) to get
- * the pointer to the right spot. Some of thse are actually
- * useful so its not a good idea to skip past in one big jump.
- */
- type = (int)_getshort(cp);
- cp += sizeof(short);
- class = (int)_getshort(cp);
- cp += sizeof(short);
- ttl = (u_int32_t)_getlong(cp);
- cp += sizeof(u_int32_t);
- dlen = (int)_getshort(cp);
- cp += sizeof(short);
- rptr->re_type = type;
-
- switch(type)
- {
- case T_A :
- rptr->re_he.h_length = dlen;
- if (ans == 1)
- rptr->re_he.h_addrtype=(class == C_IN) ?
- AF_INET : AF_UNSPEC;
- if (dlen != sizeof(dr))
- {
- h_errno = TRY_AGAIN;
- continue;
- }
- bcopy(cp, &dr, dlen);
- *adr++ = dr;
- *adr = 0;
- cp += dlen;
- len = strlen(ar_hostbuf);
- if (!rptr->re_he.h_name)
- {
- rptr->re_he.h_name = (char *)malloc(len+1);
- if (!rptr->re_he.h_name)
- break;
- (void)strcpy(rptr->re_he.h_name, ar_hostbuf);
- }
- break;
- case T_PTR :
- if ((n = dn_expand(buf, eob, cp, ar_hostbuf,
- sizeof(ar_hostbuf) )) < 0)
- {
- cp += n;
- continue;
- }
- cp += n;
- len = strlen(ar_hostbuf)+1;
- /*
- * copy the returned hostname into the host name
- * or alias field if there is a known hostname
- * already.
- */
- if (!rptr->re_he.h_name)
- {
- rptr->re_he.h_name = (char *)malloc(len);
- if (!rptr->re_he.h_name)
- break;
- (void)strcpy(rptr->re_he.h_name, ar_hostbuf);
- }
- else
- {
- *alias = (char *)malloc(len);
- if (!*alias)
- return -1;
- (void)strcpy(*alias++, ar_hostbuf);
- *alias = NULL;
- }
- break;
- case T_CNAME :
- cp += dlen;
- if (alias >= &(rptr->re_he.h_aliases[MAXALIASES-1]))
- continue;
- n = strlen(ar_hostbuf)+1;
- *alias = (char *)malloc(n);
- if (!*alias)
- return -1;
- (void)strcpy(*alias++, ar_hostbuf);
- *alias = NULL;
- break;
- default :
- break;
- }
- }
-
- return ans;
-}
-
-
-/*
- * ar_answer
- *
- * Get an answer from a DNS server and process it. If a query is found to
- * which no answer has been given to yet, copy its 'info' structure back
- * to where "reip" points and return a pointer to the hostent structure.
- */
-struct hostent *ar_answer(reip, size)
-char *reip;
-int size;
-{
- static char ar_rcvbuf[sizeof(HEADER) + MAXPACKET];
- static struct hostent ar_host;
-
- register HEADER *hptr;
- register struct reslist *rptr = NULL;
- register struct hostent *hp;
- register char **s;
- unsigned long *adr;
- int rc, i, n, a;
-
- rc = recv(ar_resfd, ar_rcvbuf, sizeof(ar_rcvbuf), 0);
- if (rc <= 0)
- goto getres_err;
-
- ar_reinfo.re_replies++;
- hptr = (HEADER *)ar_rcvbuf;
- /*
- * convert things to be in the right order.
- */
- hptr->id = ntohs(hptr->id);
- hptr->ancount = ntohs(hptr->ancount);
- hptr->arcount = ntohs(hptr->arcount);
- hptr->nscount = ntohs(hptr->nscount);
- hptr->qdcount = ntohs(hptr->qdcount);
- /*
- * response for an id which we have already received an answer for
- * just ignore this response.
- */
- rptr = ar_find_id(hptr->id);
- if (!rptr)
- goto getres_err;
-
- if ((hptr->rcode != NOERROR) || (hptr->ancount == 0))
- {
- switch (hptr->rcode)
- {
- case NXDOMAIN:
- h_errno = HOST_NOT_FOUND;
- break;
- case SERVFAIL:
- h_errno = TRY_AGAIN;
- break;
- case NOERROR:
- h_errno = NO_DATA;
- break;
- case FORMERR:
- case NOTIMP:
- case REFUSED:
- default:
- h_errno = NO_RECOVERY;
- break;
- }
- ar_reinfo.re_errors++;
- /*
- ** If a bad error was returned, we stop here and dont send
- ** send any more (no retries granted).
- */
- if (h_errno != TRY_AGAIN)
- {
- rptr->re_resend = 0;
- rptr->re_retries = 0;
- }
- goto getres_err;
- }
-
- a = ar_procanswer(rptr, hptr, ar_rcvbuf, ar_rcvbuf+rc);
-
- if ((rptr->re_type == T_PTR) && (_res.options & RES_CHECKPTR))
- {
- /*
- * For reverse lookups on IP#'s, lookup the name that is given
- * for the ip# and return with that as the official result.
- * -avalon
- */
- rptr->re_type = T_A;
- /*
- * Clean out the list of addresses already set, even though
- * there should only be one :)
- */
- adr = (unsigned long *)rptr->re_he.h_addr_list;
- while (*adr)
- *adr++ = 0L;
- /*
- * Lookup the name that we were given for the ip#
- */
- ar_reinfo.re_na_look++;
- (void)strncpy(rptr->re_name, rptr->re_he.h_name,
- sizeof(rptr->re_name)-1);
- rptr->re_he.h_name = NULL;
- rptr->re_retries = _res.retry;
- rptr->re_sends = 1;
- rptr->re_resend = 1;
- rptr->re_he.h_name = NULL;
- ar_reinfo.re_na_look++;
- (void)ar_query_name(rptr->re_name, C_IN, T_A, rptr);
- return NULL;
- }
-
- if (reip && rptr->re_rinfo.ri_ptr && size)
- bcopy(rptr->re_rinfo.ri_ptr, reip,
- MIN(rptr->re_rinfo.ri_size, size));
- /*
- * Clean up structure from previous usage.
- */
- hp = &ar_host;
-#ifdef ARLIB_DEBUG
- ar_dump_hostent("ar_answer: previous usage", hp);
-#endif
-
- if (hp->h_name)
- (void)free(hp->h_name);
- if (s = hp->h_aliases)
- {
- while (*s)
- (void)free(*s++);
- (void)free(hp->h_aliases);
- }
- if (s = hp->h_addr_list)
- {
- /*
- * Only free once since we allocated space for
- * address in one big chunk.
- */
- (void)free(*s);
- (void)free(hp->h_addr_list);
- }
- bzero((char *)hp, sizeof(*hp));
-
- /*
- * Setup and copy details for the structure we return a pointer to.
- */
- hp->h_addrtype = AF_INET;
- hp->h_length = sizeof(struct in_addr);
- if(rptr->re_he.h_name)
- {
- hp->h_name = (char *)malloc(strlen(rptr->re_he.h_name)+1);
- if(!hp->h_name)
- {
-#ifdef ARLIB_DEBUG
- fprintf(stderr, "no memory for hostname\n");
-#endif
- h_errno = TRY_AGAIN;
- goto getres_err;
- }
- (void)strcpy(hp->h_name, rptr->re_he.h_name);
- }
-#ifdef ARLIB_DEBUG
- ar_dump_hostent("ar_answer: (snap) store name", hp);
-#endif
-
- /*
- * Count IP#'s.
- */
- for (i = 0, n = 0; i < MAXADDRS; i++, n++)
- if (!rptr->re_he.h_addr_list[i].s_addr)
- break;
- s = hp->h_addr_list = (char **)malloc((n + 1) * sizeof(char *));
- if (n)
- {
- *s = (char *)malloc(n * sizeof(struct in_addr));
- if(!*s)
- {
-#ifdef ARLIB_DEBUG
- fprintf(stderr, "no memory for IP#'s (%d)\n", n);
-#endif
- h_errno = TRY_AGAIN;
- goto getres_err;
- }
- bcopy((char *)&rptr->re_he.h_addr_list[0].s_addr, *s,
- sizeof(struct in_addr));
- s++;
- for (i = 1; i < n; i++, s++)
- {
- *s = hp->h_addr + i * sizeof(struct in_addr);
- bcopy((char *)&rptr->re_he.h_addr_list[i].s_addr, *s,
- sizeof(struct in_addr));
- }
- }
- *s = NULL;
-#ifdef ARLIB_DEBUG
- ar_dump_hostent("ar_answer: (snap) store IP#'s", hp);
-#endif
-
- /*
- * Count CNAMEs
- */
- for (i = 0, n = 0; i < MAXADDRS; i++, n++)
- if (!rptr->re_he.h_aliases[i])
- break;
- s = hp->h_aliases = (char **)malloc((n + 1) * sizeof(char *));
- if (!s)
- {
-#ifdef ARLIB_DEBUG
- fprintf(stderr, "no memory for aliases (%d)\n", n);
-#endif
- h_errno = TRY_AGAIN;
- goto getres_err;
- }
- for (i = 0; i < n; i++)
- {
- *s++ = rptr->re_he.h_aliases[i];
- rptr->re_he.h_aliases[i] = NULL;
- }
- *s = NULL;
-#ifdef ARLIB_DEBUG
- ar_dump_hostent("ar_answer: (snap) store CNAMEs", hp);
- ar_dump_hostent("ar_answer: new one", hp);
-#endif
-
- if (a > 0)
- (void)ar_remrequest(rptr);
- else
- if (!rptr->re_sent)
- (void)ar_remrequest(rptr);
- return hp;
-
-getres_err:
- if (rptr)
- {
- if (reip && rptr->re_rinfo.ri_ptr && size)
- bcopy(rptr->re_rinfo.ri_ptr, reip,
- MIN(rptr->re_rinfo.ri_size, size));
- if ((h_errno != TRY_AGAIN) &&
- (_res.options & (RES_DNSRCH|RES_DEFNAMES) ==
- (RES_DNSRCH|RES_DEFNAMES) ))
- if (_res.dnsrch[rptr->re_srch])
- {
- rptr->re_retries = _res.retry;
- rptr->re_sends = 1;
- rptr->re_resend = 1;
- (void)ar_resend_query(rptr);
- rptr->re_srch++;
- }
- return NULL;
- }
- return NULL;
-}
-
-
-#ifdef ARLIB_DEBUG
-void ar_dump_hostent(prefix, hp)
-char *prefix;
-struct hostent *hp;
-{
- register char **s;
-
- fflush(stdout);
-
- fprintf(stderr, "%s\n", prefix);
- fprintf(stderr, " hp %p\n", hp);
- fprintf(stderr, " h_name %p '%s'\n",
- hp->h_name, hp->h_name);
- if (s = hp->h_aliases)
- {
- fprintf(stderr, " h_aliases %p\n",
- hp->h_aliases);
- while (*s)
- {
- fprintf(stderr, " element %p\n", *s);
- s++;
- }
- }
- if (s = hp->h_addr_list)
- {
- fprintf(stderr, " h_addr_list %p\n",
- hp->h_addr_list);
- while (*s)
- {
- fprintf(stderr, " element %p\n", *s);
- s++;
- }
- }
-
- fflush(stderr);
-}
-
-
-void ar_dump_reslist(FILE* fp)
-{
- register struct reslist *rptr;
- int c;
-
- c = 0;
- for (rptr = ar_first; rptr; rptr = rptr->re_next)
- {
- fprintf(fp, "%4d [%p] %4d [%p]: %s\n", rptr->re_id, rptr,
- *(rptr->re_rinfo.ri_ptr), rptr->re_rinfo.ri_ptr,
- rptr->re_name);
- }
-}
-#endif