Home | History | Annotate | Line # | Download | only in net
hesiod.c revision 1.1.4.3
      1  1.1.4.3  lukem /*	$NetBSD: hesiod.c,v 1.1.4.3 1998/11/02 03:29:36 lukem Exp $	*/
      2  1.1.4.1  lukem 
      3  1.1.4.1  lukem /* This file is part of the Hesiod library.
      4  1.1.4.1  lukem  *
      5  1.1.4.1  lukem  *  Copyright (C) 1988, 1989 by the Massachusetts Institute of Technology
      6  1.1.4.1  lukem  *
      7  1.1.4.1  lukem  *    Export of software employing encryption from the United States of
      8  1.1.4.1  lukem  *    America is assumed to require a specific license from the United
      9  1.1.4.1  lukem  *    States Government.  It is the responsibility of any person or
     10  1.1.4.1  lukem  *    organization contemplating export to obtain such a license before
     11  1.1.4.1  lukem  *    exporting.
     12  1.1.4.1  lukem  *
     13  1.1.4.1  lukem  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
     14  1.1.4.1  lukem  * distribute this software and its documentation for any purpose and
     15  1.1.4.1  lukem  * without fee is hereby granted, provided that the above copyright
     16  1.1.4.1  lukem  * notice appear in all copies and that both that copyright notice and
     17  1.1.4.1  lukem  * this permission notice appear in supporting documentation, and that
     18  1.1.4.1  lukem  * the name of M.I.T. not be used in advertising or publicity pertaining
     19  1.1.4.1  lukem  * to distribution of the software without specific, written prior
     20  1.1.4.1  lukem  * permission.  M.I.T. makes no representations about the suitability of
     21  1.1.4.1  lukem  * this software for any purpose.  It is provided "as is" without express
     22  1.1.4.1  lukem  * or implied warranty.
     23  1.1.4.1  lukem  */
     24  1.1.4.1  lukem 
     25  1.1.4.3  lukem #include <sys/cdefs.h>
     26  1.1.4.3  lukem 
     27  1.1.4.1  lukem #ifndef lint
     28  1.1.4.3  lukem __IDSTRING(rcsid_hesiod_c, "#Header: /afs/rel-eng.athena.mit.edu/project/release/current/source/athena/athena.lib/hesiod/RCS/hesiod.c,v 1.11 93/06/15 10:26:37 mar Exp #");
     29  1.1.4.3  lukem __IDSTRING(rcsid_resolve_c, "#Header: /afs/rel-eng.athena.mit.edu/project/release/current/source/athena/athena.lib/hesiod/RCS/resolve.c,v 1.7 93/06/15 10:25:45 mar Exp #");
     30  1.1.4.1  lukem #endif
     31  1.1.4.1  lukem 
     32  1.1.4.1  lukem #include <sys/types.h>
     33  1.1.4.1  lukem #include <sys/param.h>
     34  1.1.4.1  lukem #include <netinet/in.h>
     35  1.1.4.1  lukem #include <arpa/nameser.h>
     36  1.1.4.1  lukem 
     37  1.1.4.1  lukem #include <errno.h>
     38  1.1.4.1  lukem #include <hesiod.h>
     39  1.1.4.1  lukem #include <resolv.h>
     40  1.1.4.1  lukem #include <stdio.h>
     41  1.1.4.1  lukem #include <stdlib.h>
     42  1.1.4.1  lukem #include <string.h>
     43  1.1.4.1  lukem #include <stringlist.h>
     44  1.1.4.1  lukem #include <unistd.h>
     45  1.1.4.1  lukem 
     46  1.1.4.1  lukem typedef struct rr {
     47  1.1.4.1  lukem 	u_int16_t	 type;		/* RR type */
     48  1.1.4.1  lukem 	u_int16_t	 class;		/* RR class */
     49  1.1.4.1  lukem 	int		 dlen;		/* len of data section */
     50  1.1.4.1  lukem 	u_char		*data;		/* pointer to data */
     51  1.1.4.1  lukem } rr_t, *rr_p;
     52  1.1.4.1  lukem 
     53  1.1.4.1  lukem typedef struct nsmsg {
     54  1.1.4.1  lukem 	int	 len;		/* sizeof(msg) */
     55  1.1.4.1  lukem 	int	 ns_off;	/* offset to name server RRs */
     56  1.1.4.1  lukem 	int	 ar_off;	/* offset to additional RRs */
     57  1.1.4.1  lukem 	int	 count;		/* total number of RRs */
     58  1.1.4.1  lukem 	HEADER	*hd;		/* message header */
     59  1.1.4.1  lukem 	rr_t	 rr;		/* vector of (stripped-down) RR descriptors */
     60  1.1.4.1  lukem } nsmsg_t, *nsmsg_p;
     61  1.1.4.1  lukem 
     62  1.1.4.1  lukem static int	 Hes_Errno	= HES_ER_UNINIT;
     63  1.1.4.1  lukem char		*HesConfigFile	= _PATH_HESIOD_CONF;
     64  1.1.4.1  lukem static char	 Hes_LHS[MAXDNAME + 1];
     65  1.1.4.1  lukem static char	 Hes_RHS[MAXDNAME + 1];
     66  1.1.4.1  lukem static u_char	*Hes_eoM;
     67  1.1.4.1  lukem 
     68  1.1.4.1  lukem #define DEF_RETRANS 4
     69  1.1.4.1  lukem #define DEF_RETRY 3
     70  1.1.4.1  lukem 
     71  1.1.4.3  lukem static	caddr_t	_hes_rr_scan __P((u_char *, rr_t *));
     72  1.1.4.3  lukem static	nsmsg_p	_hes_res_scan __P((u_char *));
     73  1.1.4.3  lukem static	nsmsg_p	_hes_res __P((u_char *, int, int));
     74  1.1.4.3  lukem 	int	hes_init __P((void));
     75  1.1.4.3  lukem 
     76  1.1.4.1  lukem static caddr_t
     77  1.1.4.1  lukem _hes_rr_scan(cp, rr)
     78  1.1.4.1  lukem 	u_char *cp;
     79  1.1.4.1  lukem 	rr_t *rr;
     80  1.1.4.1  lukem {
     81  1.1.4.1  lukem 	int n;
     82  1.1.4.1  lukem 
     83  1.1.4.1  lukem 	if ((n = dn_skipname(cp, Hes_eoM)) < 0) {
     84  1.1.4.1  lukem 		errno = EINVAL;
     85  1.1.4.1  lukem 		return((u_char *)NULL);
     86  1.1.4.1  lukem 	}
     87  1.1.4.1  lukem 
     88  1.1.4.1  lukem 	cp += n;
     89  1.1.4.1  lukem 	rr->type = _getshort(cp);
     90  1.1.4.1  lukem 	cp += sizeof(u_int16_t /*type*/);
     91  1.1.4.1  lukem 
     92  1.1.4.1  lukem 	rr->class = _getshort(cp);
     93  1.1.4.1  lukem 	cp += sizeof(u_int16_t /*class*/) + sizeof(u_int32_t /*ttl*/);
     94  1.1.4.1  lukem 
     95  1.1.4.1  lukem 	rr->dlen = (int)_getshort(cp);
     96  1.1.4.1  lukem 	rr->data = cp + sizeof(u_int16_t /*dlen*/);
     97  1.1.4.1  lukem 
     98  1.1.4.1  lukem 	return(rr->data + rr->dlen);
     99  1.1.4.1  lukem }
    100  1.1.4.1  lukem 
    101  1.1.4.1  lukem 
    102  1.1.4.1  lukem static nsmsg_p
    103  1.1.4.1  lukem _hes_res_scan(msg)
    104  1.1.4.1  lukem 	u_char *msg;
    105  1.1.4.1  lukem {
    106  1.1.4.1  lukem 	static u_char	 bigmess[sizeof(nsmsg_t) + sizeof(rr_t) *
    107  1.1.4.1  lukem 				((PACKETSZ-sizeof(HEADER))/RRFIXEDSZ)];
    108  1.1.4.1  lukem 	static u_char	 datmess[PACKETSZ-sizeof(HEADER)];
    109  1.1.4.1  lukem 	u_char		*cp;
    110  1.1.4.1  lukem 	rr_t		*rp;
    111  1.1.4.1  lukem 	HEADER		*hp;
    112  1.1.4.1  lukem 	u_char		*data = datmess;
    113  1.1.4.1  lukem 	int	 	 n, n_an, n_ns, n_ar, nrec;
    114  1.1.4.1  lukem 	nsmsg_t		*mess = (nsmsg_t *)bigmess;
    115  1.1.4.1  lukem 
    116  1.1.4.1  lukem 	hp = (HEADER *)msg;
    117  1.1.4.1  lukem 	cp = msg + sizeof(HEADER);
    118  1.1.4.1  lukem 	n_an = ntohs(hp->ancount);
    119  1.1.4.1  lukem 	n_ns = ntohs(hp->nscount);
    120  1.1.4.1  lukem 	n_ar = ntohs(hp->arcount);
    121  1.1.4.1  lukem 	nrec = n_an + n_ns + n_ar;
    122  1.1.4.1  lukem 
    123  1.1.4.1  lukem 	mess->len = 0;
    124  1.1.4.1  lukem 	mess->hd = hp;
    125  1.1.4.1  lukem 	mess->ns_off = n_an;
    126  1.1.4.1  lukem 	mess->ar_off = n_an + n_ns;
    127  1.1.4.1  lukem 	mess->count = nrec;
    128  1.1.4.1  lukem 	rp = &mess->rr;
    129  1.1.4.1  lukem 
    130  1.1.4.1  lukem 	/* skip over questions */
    131  1.1.4.1  lukem 	if ((n = ntohs(hp->qdcount) != 0)) {
    132  1.1.4.1  lukem 		while (--n >= 0) {
    133  1.1.4.1  lukem 			int i;
    134  1.1.4.1  lukem 			if ((i = dn_skipname(cp, Hes_eoM)) < 0)
    135  1.1.4.1  lukem 				return((nsmsg_t *)NULL);
    136  1.1.4.1  lukem 			cp += i + (sizeof(u_int16_t /*type*/)
    137  1.1.4.1  lukem 				+ sizeof(u_int16_t /*class*/));
    138  1.1.4.1  lukem 		}
    139  1.1.4.1  lukem 	}
    140  1.1.4.1  lukem 
    141  1.1.4.1  lukem 	/* scan answers */
    142  1.1.4.1  lukem 	if ((n = n_an) != 0) {
    143  1.1.4.1  lukem 		while (--n >= 0) {
    144  1.1.4.1  lukem 			if ((cp = _hes_rr_scan(cp, rp)) == NULL)
    145  1.1.4.1  lukem 				return((nsmsg_t *)NULL);
    146  1.1.4.1  lukem 			(void) strncpy(data, rp->data, rp->dlen);
    147  1.1.4.1  lukem 			rp->data = data;
    148  1.1.4.1  lukem 			data += rp->dlen;
    149  1.1.4.1  lukem 			*data++ = '\0';
    150  1.1.4.1  lukem 			rp++;
    151  1.1.4.1  lukem 		}
    152  1.1.4.1  lukem 	}
    153  1.1.4.1  lukem 
    154  1.1.4.1  lukem 	/* scan name servers */
    155  1.1.4.1  lukem 	if ((n = n_ns) != 0) {
    156  1.1.4.1  lukem 		while (--n >= 0) {
    157  1.1.4.1  lukem 			if ((cp = _hes_rr_scan(cp, rp)) == NULL)
    158  1.1.4.1  lukem 				return((nsmsg_t *)NULL);
    159  1.1.4.1  lukem 			(void) strncpy(data, rp->data, rp->dlen);
    160  1.1.4.1  lukem 			rp->data = data;
    161  1.1.4.1  lukem 			data += rp->dlen;
    162  1.1.4.1  lukem 			*data++ = '\0';
    163  1.1.4.1  lukem 			rp++;
    164  1.1.4.1  lukem 		}
    165  1.1.4.1  lukem 	}
    166  1.1.4.1  lukem 
    167  1.1.4.1  lukem 	/* scan additional records */
    168  1.1.4.1  lukem 	if ((n = n_ar) != 0) {
    169  1.1.4.1  lukem 		while (--n >= 0) {
    170  1.1.4.1  lukem 			if ((cp = _hes_rr_scan(cp, rp)) == NULL)
    171  1.1.4.1  lukem 				return((nsmsg_t *)NULL);
    172  1.1.4.1  lukem 			(void) strncpy(data, rp->data, rp->dlen);
    173  1.1.4.1  lukem 			rp->data = data;
    174  1.1.4.1  lukem 			data += rp->dlen;
    175  1.1.4.1  lukem 			*data++ = '\0';
    176  1.1.4.1  lukem 			rp++;
    177  1.1.4.1  lukem 		}
    178  1.1.4.1  lukem 	}
    179  1.1.4.1  lukem 
    180  1.1.4.1  lukem 	mess->len = (int)cp - (int)msg;
    181  1.1.4.1  lukem 
    182  1.1.4.1  lukem 	return(mess);
    183  1.1.4.1  lukem }
    184  1.1.4.1  lukem 
    185  1.1.4.1  lukem /*
    186  1.1.4.1  lukem  * Resolve name into data records
    187  1.1.4.1  lukem  */
    188  1.1.4.1  lukem 
    189  1.1.4.1  lukem static nsmsg_p
    190  1.1.4.1  lukem _hes_res(name, class, type)
    191  1.1.4.1  lukem 	u_char *name;
    192  1.1.4.1  lukem 	int class, type;
    193  1.1.4.1  lukem {
    194  1.1.4.1  lukem 	static u_char		qbuf[PACKETSZ], abuf[PACKETSZ];
    195  1.1.4.1  lukem 	int			n;
    196  1.1.4.1  lukem 	u_int32_t		res_options = _res.options;
    197  1.1.4.1  lukem 	int			res_retrans = _res.retrans;
    198  1.1.4.1  lukem 	int			res_retry = _res.retry;
    199  1.1.4.1  lukem 
    200  1.1.4.1  lukem #ifdef DEBUG
    201  1.1.4.1  lukem 	if (_res.options & RES_DEBUG)
    202  1.1.4.1  lukem 		printf("_hes_res: class = %d, type = %d\n", class, type);
    203  1.1.4.1  lukem #endif
    204  1.1.4.1  lukem 
    205  1.1.4.1  lukem 	if (class < 0 || type < 0) {
    206  1.1.4.1  lukem 		errno = EINVAL;
    207  1.1.4.1  lukem 		return((nsmsg_t *)NULL);
    208  1.1.4.1  lukem 	}
    209  1.1.4.1  lukem 
    210  1.1.4.1  lukem 	_res.options |= RES_IGNTC;
    211  1.1.4.1  lukem 
    212  1.1.4.1  lukem 	n = res_mkquery(QUERY, name, class, type, (u_char *)NULL, 0,
    213  1.1.4.1  lukem 	    NULL, qbuf, PACKETSZ);
    214  1.1.4.1  lukem 	if (n < 0) {
    215  1.1.4.1  lukem 		errno = EMSGSIZE;
    216  1.1.4.1  lukem 		return((nsmsg_t *)NULL);
    217  1.1.4.1  lukem 	}
    218  1.1.4.1  lukem 
    219  1.1.4.1  lukem 	_res.retrans = DEF_RETRANS;
    220  1.1.4.1  lukem 	_res.retry = DEF_RETRY;
    221  1.1.4.1  lukem 
    222  1.1.4.1  lukem 	n = res_send(qbuf, n, abuf, PACKETSZ);
    223  1.1.4.1  lukem 
    224  1.1.4.1  lukem 	_res.options = res_options;
    225  1.1.4.1  lukem 	_res.retrans = res_retrans;
    226  1.1.4.1  lukem 	_res.retry = res_retry;
    227  1.1.4.1  lukem 
    228  1.1.4.1  lukem 	if (n < 0) {
    229  1.1.4.1  lukem 		errno = ECONNREFUSED;
    230  1.1.4.1  lukem 		return((nsmsg_t *)NULL);
    231  1.1.4.1  lukem 	}
    232  1.1.4.1  lukem 	Hes_eoM = abuf+n;
    233  1.1.4.1  lukem 
    234  1.1.4.1  lukem 	return(_hes_res_scan(abuf));
    235  1.1.4.1  lukem }
    236  1.1.4.1  lukem 
    237  1.1.4.1  lukem int
    238  1.1.4.1  lukem hes_init()
    239  1.1.4.1  lukem {
    240  1.1.4.1  lukem 	FILE	*fp;
    241  1.1.4.1  lukem 	char	*key, *cp, *cpp;
    242  1.1.4.1  lukem 	char	 buf[MAXDNAME+7];
    243  1.1.4.1  lukem 
    244  1.1.4.1  lukem 	Hes_Errno = HES_ER_UNINIT;
    245  1.1.4.1  lukem 	Hes_LHS[0] = '\0';
    246  1.1.4.1  lukem 	Hes_RHS[0] = '\0';
    247  1.1.4.1  lukem 	if ((fp = fopen(HesConfigFile, "r")) == NULL) {
    248  1.1.4.1  lukem 		/* use defaults compiled in */
    249  1.1.4.1  lukem 		/* no file or no access uses defaults */
    250  1.1.4.1  lukem 		/* but poorly formed file returns error */
    251  1.1.4.1  lukem 		if (DEF_LHS) strncpy(Hes_LHS, DEF_LHS, MAXDNAME);
    252  1.1.4.1  lukem 		if (DEF_RHS) strncpy(Hes_RHS, DEF_RHS, MAXDNAME);
    253  1.1.4.1  lukem 
    254  1.1.4.1  lukem 		/* if DEF_RHS == "", use getdomainname() */
    255  1.1.4.1  lukem 		if (Hes_RHS[0] == '\0')
    256  1.1.4.1  lukem 			(void)getdomainname(Hes_RHS, MAXDNAME);
    257  1.1.4.1  lukem 	} else {
    258  1.1.4.1  lukem 		while(fgets(buf, MAXDNAME+7, fp) != NULL) {
    259  1.1.4.1  lukem 			cp = buf;
    260  1.1.4.1  lukem 			if (*cp == '#' || *cp == '\n')
    261  1.1.4.1  lukem 				continue;
    262  1.1.4.1  lukem 			while(*cp == ' ' || *cp == '\t')
    263  1.1.4.1  lukem 				cp++;
    264  1.1.4.1  lukem 			key = cp;
    265  1.1.4.1  lukem 			while(*cp != ' ' && *cp != '\t' && *cp != '=')
    266  1.1.4.1  lukem 				cp++;
    267  1.1.4.1  lukem 			*cp++ = '\0';
    268  1.1.4.1  lukem 			if (strcmp(key, "lhs") == 0)
    269  1.1.4.1  lukem 				cpp = Hes_LHS;
    270  1.1.4.1  lukem 			else if (strcmp(key, "rhs") == 0)
    271  1.1.4.1  lukem 				cpp = Hes_RHS;
    272  1.1.4.1  lukem 			else
    273  1.1.4.1  lukem 				continue;
    274  1.1.4.1  lukem 			while(*cp == ' ' || *cp == '\t' || *cp == '=')
    275  1.1.4.1  lukem 				cp++;
    276  1.1.4.1  lukem 			if (*cp != '.' && *cp != '\n') {
    277  1.1.4.1  lukem 				Hes_Errno = HES_ER_CONFIG;
    278  1.1.4.1  lukem 				fclose(fp);
    279  1.1.4.1  lukem 				return(Hes_Errno);
    280  1.1.4.1  lukem 			}
    281  1.1.4.1  lukem 			(void) strncpy(cpp, cp, strlen(cp)-1);
    282  1.1.4.1  lukem 		}
    283  1.1.4.1  lukem 		fclose(fp);
    284  1.1.4.1  lukem 	}
    285  1.1.4.1  lukem 	/* see if the RHS is overridden by environment variable */
    286  1.1.4.1  lukem 	if ((cp = getenv("HES_DOMAIN")) != NULL)
    287  1.1.4.1  lukem 		strncpy(Hes_RHS, cp, MAXDNAME);
    288  1.1.4.1  lukem 	/* the LHS may be null, the RHS must not be null */
    289  1.1.4.1  lukem 	if (Hes_RHS[0] == '\0')
    290  1.1.4.1  lukem 		Hes_Errno = HES_ER_CONFIG;
    291  1.1.4.1  lukem 	else
    292  1.1.4.1  lukem 		Hes_Errno = HES_ER_OK;
    293  1.1.4.1  lukem 	return(Hes_Errno);
    294  1.1.4.1  lukem }
    295  1.1.4.1  lukem 
    296  1.1.4.1  lukem char *
    297  1.1.4.1  lukem hes_to_bind(HesiodName, HesiodNameType)
    298  1.1.4.1  lukem 	char *HesiodName, *HesiodNameType;
    299  1.1.4.1  lukem {
    300  1.1.4.1  lukem 	static char	 bindname[MAXDNAME];
    301  1.1.4.1  lukem 	char		*cp, **cpp, *x;
    302  1.1.4.1  lukem 	char		*RHS;
    303  1.1.4.1  lukem 	int		 bni = 0;
    304  1.1.4.1  lukem 
    305  1.1.4.1  lukem #define STRADDBIND(y)	for (x = y; *x; x++, bni++) { \
    306  1.1.4.1  lukem 				if (bni >= MAXDNAME) \
    307  1.1.4.1  lukem 					return NULL; \
    308  1.1.4.1  lukem 				bindname[bni] = *x; \
    309  1.1.4.1  lukem 			}
    310  1.1.4.1  lukem 
    311  1.1.4.1  lukem 	if (Hes_Errno == HES_ER_UNINIT || Hes_Errno == HES_ER_CONFIG)
    312  1.1.4.1  lukem 		(void) hes_init();
    313  1.1.4.1  lukem 	if (Hes_Errno == HES_ER_CONFIG)
    314  1.1.4.1  lukem 		return(NULL);
    315  1.1.4.1  lukem 	if ((cp = strchr(HesiodName,'@')) != NULL) {
    316  1.1.4.1  lukem 		if (strchr(++cp,'.'))
    317  1.1.4.1  lukem 			RHS = cp;
    318  1.1.4.1  lukem 		else
    319  1.1.4.1  lukem 			if ((cpp = hes_resolve(cp, "rhs-extension")) != NULL)
    320  1.1.4.1  lukem 				RHS = *cpp;
    321  1.1.4.1  lukem 			else {
    322  1.1.4.1  lukem 				Hes_Errno = HES_ER_NOTFOUND;
    323  1.1.4.1  lukem 				return(NULL);
    324  1.1.4.1  lukem 			}
    325  1.1.4.1  lukem 		STRADDBIND(HesiodName);
    326  1.1.4.1  lukem 		*strchr(bindname,'@') = '\0';
    327  1.1.4.1  lukem 	} else {
    328  1.1.4.1  lukem 		RHS = Hes_RHS;
    329  1.1.4.1  lukem 		STRADDBIND(HesiodName);
    330  1.1.4.1  lukem 	}
    331  1.1.4.1  lukem 	STRADDBIND(".");
    332  1.1.4.1  lukem 	STRADDBIND(HesiodNameType);
    333  1.1.4.1  lukem 	if (Hes_LHS && Hes_LHS[0]) {
    334  1.1.4.1  lukem 		if (Hes_LHS[0] != '.')
    335  1.1.4.1  lukem 			STRADDBIND(".");
    336  1.1.4.1  lukem 		STRADDBIND(Hes_LHS);
    337  1.1.4.1  lukem 	}
    338  1.1.4.1  lukem 	if (RHS[0] != '.')
    339  1.1.4.1  lukem 		STRADDBIND(".");
    340  1.1.4.1  lukem 	STRADDBIND(RHS);
    341  1.1.4.1  lukem 	if (bni == MAXDNAME)
    342  1.1.4.1  lukem 		bni--;
    343  1.1.4.1  lukem 	bindname[bni] = '\0';
    344  1.1.4.1  lukem 	return(bindname);
    345  1.1.4.1  lukem }
    346  1.1.4.1  lukem 
    347  1.1.4.1  lukem /* XXX: convert to resolv directly */
    348  1.1.4.1  lukem char **
    349  1.1.4.1  lukem hes_resolve(HesiodName, HesiodNameType)
    350  1.1.4.1  lukem 	char *HesiodName, *HesiodNameType;
    351  1.1.4.1  lukem {
    352  1.1.4.2  lukem 	char		**retvec;
    353  1.1.4.2  lukem 	char		 *cp, *ocp, *dst;
    354  1.1.4.2  lukem 	int		  i, n;
    355  1.1.4.2  lukem 	struct nsmsg	 *ns;
    356  1.1.4.2  lukem 	rr_t		 *rp;
    357  1.1.4.2  lukem 	StringList	 *sl;
    358  1.1.4.1  lukem 
    359  1.1.4.1  lukem 	sl = sl_init();
    360  1.1.4.1  lukem 
    361  1.1.4.1  lukem 	cp = hes_to_bind(HesiodName, HesiodNameType);
    362  1.1.4.1  lukem 	if (cp == NULL)
    363  1.1.4.1  lukem 		return(NULL);
    364  1.1.4.1  lukem 	errno = 0;
    365  1.1.4.1  lukem 	ns = _hes_res(cp, C_HS, T_TXT);
    366  1.1.4.1  lukem 	if (errno == ETIMEDOUT || errno == ECONNREFUSED) {
    367  1.1.4.1  lukem 		Hes_Errno = HES_ER_NET;
    368  1.1.4.1  lukem 		return(NULL);
    369  1.1.4.1  lukem 	}
    370  1.1.4.1  lukem 	if (ns == NULL || ns->ns_off <= 0) {
    371  1.1.4.1  lukem 		Hes_Errno = HES_ER_NOTFOUND;
    372  1.1.4.1  lukem 		return(NULL);
    373  1.1.4.1  lukem 	}
    374  1.1.4.1  lukem 	for(i = 0, rp = &ns->rr; i < ns->ns_off; rp++, i++) {
    375  1.1.4.1  lukem 		if (rp->class == C_HS && rp->type == T_TXT) {
    376  1.1.4.1  lukem 			dst = calloc(rp->dlen + 1, sizeof(char));
    377  1.1.4.1  lukem 			if (dst == NULL) {
    378  1.1.4.1  lukem 				sl_free(sl, 1);
    379  1.1.4.1  lukem 				return NULL;
    380  1.1.4.1  lukem 			}
    381  1.1.4.1  lukem 			sl_add(sl, dst);
    382  1.1.4.1  lukem 			ocp = cp = rp->data;
    383  1.1.4.1  lukem 			while (cp < ocp + rp->dlen) {
    384  1.1.4.1  lukem 				n = (unsigned char) *cp++;
    385  1.1.4.1  lukem 				(void) memmove(dst, cp, n);
    386  1.1.4.1  lukem 				cp += n;
    387  1.1.4.1  lukem 				dst += n;
    388  1.1.4.1  lukem 			}
    389  1.1.4.1  lukem 			*dst = 0;
    390  1.1.4.1  lukem 		}
    391  1.1.4.1  lukem 	}
    392  1.1.4.1  lukem 	sl_add(sl, NULL);
    393  1.1.4.1  lukem 	retvec = sl->sl_str;	/* XXX: nasty, knows stringlist internals */
    394  1.1.4.1  lukem 	free(sl);
    395  1.1.4.1  lukem 	return(retvec);
    396  1.1.4.1  lukem }
    397  1.1.4.1  lukem 
    398  1.1.4.1  lukem int
    399  1.1.4.1  lukem hes_error()
    400  1.1.4.1  lukem {
    401  1.1.4.1  lukem 	return(Hes_Errno);
    402  1.1.4.1  lukem }
    403  1.1.4.1  lukem 
    404  1.1.4.1  lukem void
    405  1.1.4.1  lukem hes_free(hp)
    406  1.1.4.1  lukem 	char **hp;
    407  1.1.4.1  lukem {
    408  1.1.4.1  lukem 	int i;
    409  1.1.4.1  lukem 	if (!hp)
    410  1.1.4.1  lukem 		return;
    411  1.1.4.1  lukem 	for (i = 0; hp[i]; i++)
    412  1.1.4.1  lukem 		free(hp[i]);
    413  1.1.4.1  lukem 	free(hp);
    414  1.1.4.1  lukem }
    415