diff options
Diffstat (limited to 'arlib/arlib.c')
-rw-r--r-- | arlib/arlib.c | 1056 |
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 |