* Copyright (c) 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of California at Berkeley. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)res_query.c 5.4 (Berkeley) 4/21/88";
#endif /* LIBC_SCCS and not lint */
#include <arpa/nameser.h>
#define MAXPACKET PACKETSZ
* Formulate a normal query, send, and await answer.
* Returned answer is placed in supplied buffer "answer".
* Perform preliminary check of answer, returning success only
* if no error is indicated and the answer count is nonzero.
* Return the size of the response on success, -1 on error.
* Error number is left in h_errno.
* Caller must parse answer and determine whether it answers the question.
res_query(name
, class, type
, answer
, anslen
)
char *name
; /* domain name */
int class, type
; /* class and type of query */
u_char
*answer
; /* buffer to put answer */
int anslen
; /* size of answer buffer */
if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1)
if (_res
.options
& RES_DEBUG
)
printf("res_query(%s, %d, %d)\n", name
, class, type
);
n
= res_mkquery(QUERY
, name
, class, type
, (char *)NULL
, 0, NULL
,
if (_res
.options
& RES_DEBUG
)
printf("res_query: mkquery failed\n");
n
= res_send(buf
, n
, answer
, anslen
);
if (_res
.options
& RES_DEBUG
)
printf("res_query: send error\n");
if (hp
->rcode
!= NOERROR
|| ntohs(hp
->ancount
) == 0) {
if (_res
.options
& RES_DEBUG
)
printf("rcode = %d, ancount=%d\n", hp
->rcode
,
h_errno
= HOST_NOT_FOUND
;
* Formulate a normal query, send, and retrieve answer in supplied buffer.
* Return the size of the response on success, -1 on error.
* If enabled, implement search rules until answer or unrecoverable failure
* is detected. Error number is left in h_errno.
* Only useful for queries in the same name hierarchy as the local host
* (not, for example, for host address-to-name lookups in domain in-addr.arpa).
res_search(name
, class, type
, answer
, anslen
)
char *name
; /* domain name */
int class, type
; /* class and type of query */
u_char
*answer
; /* buffer to put answer */
int anslen
; /* size of answer */
register char *cp
, **domain
;
int n
, ret
, got_nodata
= 0;
if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1)
h_errno
= HOST_NOT_FOUND
; /* default, if we never query */
for (cp
= name
, n
= 0; *cp
; cp
++)
if (n
== 0 && (cp
= hostalias(name
)))
return (res_query(cp
, class, type
, answer
, anslen
));
if ((n
== 0 || *--cp
!= '.') && (_res
.options
& RES_DEFNAMES
))
for (domain
= _res
.dnsrch
; *domain
; domain
++) {
ret
= res_querydomain(name
, *domain
, class, type
,
* If no server present, give up.
* If name isn't found in this domain,
* keep trying higher domains in the search list
* On a NO_DATA error, keep trying, otherwise
* a wildcard entry of another type could keep us
* from finding this entry higher in the domain.
* If we get some other error (non-authoritative negative
* answer or server failure), then stop searching up,
* but try the input name below in case it's fully-qualified.
if (errno
== ECONNREFUSED
) {
if ((h_errno
!= HOST_NOT_FOUND
&& h_errno
!= NO_DATA
) ||
(_res
.options
& RES_DNSRCH
) == 0)
* If the search/default failed, try the name as fully-qualified,
* but only if it contained at least one dot (even trailing).
return (res_querydomain(name
, (char *)NULL
, class, type
,
* Perform a call on res_query on the concatenation of name and domain,
* removing a trailing dot from name if domain is NULL.
res_querydomain(name
, domain
, class, type
, answer
, anslen
)
int class, type
; /* class and type of query */
u_char
*answer
; /* buffer to put answer */
int anslen
; /* size of answer */
if (_res
.options
& RES_DEBUG
)
printf("res_querydomain(%s, %s, %d, %d)\n",
name
, domain
, class, type
);
* Check for trailing '.';
* copy without '.' if present.
if (name
[n
] == '.' && n
< sizeof(nbuf
) - 1) {
(void)sprintf(nbuf
, "%.*s.%.*s",
MAXDNAME
, name
, MAXDNAME
, domain
);
return (res_query(longname
, class, type
, answer
, anslen
));
char *file
, *getenv(), *strcpy(), *strncpy();
static char abuf
[MAXDNAME
];
file
= getenv("HOSTALIASES");
if (file
== NULL
|| (fp
= fopen(file
, "r")) == NULL
)
buf
[sizeof(buf
) - 1] = '\0';
while (fgets(buf
, sizeof(buf
), fp
)) {
for (C1
= buf
; *C1
&& !isspace(*C1
); ++C1
);
if (!strcasecmp(buf
, name
)) {
for (C2
= C1
+ 1; *C2
&& !isspace(*C2
); ++C2
);
abuf
[sizeof(abuf
) - 1] = *C2
= '\0';
(void)strncpy(abuf
, C1
, sizeof(abuf
) - 1);