* Copyright (c) 1985, 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
[] = "@(#)gethostnamadr.c 6.30 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <arpa/nameser.h>
static char *h_addr_ptrs
[MAXADDRS
+ 1];
static struct hostent host
;
static char *host_aliases
[MAXALIASES
];
static char hostbuf
[BUFSIZ
+1];
static struct in_addr host_addr
;
static char HOSTDB
[] = "/etc/hosts";
static FILE *hostf
= NULL
;
static char line
[BUFSIZ
+1];
static char hostaddr
[MAXADDRS
];
static char *host_addrs
[2];
#define MAXPACKET PACKETSZ
getanswer(msg
, msglen
, iquery
)
int type
, class, buflen
, ancount
, qdcount
;
int haveanswer
, getclass
= C_ANY
;
n
= res_send(msg
, msglen
, (char *)&answer
, sizeof(answer
));
if (_res
.options
& RES_DEBUG
)
printf("res_send failed\n");
return ((struct hostent
*) NULL
);
eom
= (char *)&answer
+ n
;
* find first satisfactory answer
ancount
= ntohs(hp
->ancount
);
qdcount
= ntohs(hp
->qdcount
);
if (hp
->rcode
!= NOERROR
|| ancount
== 0) {
if (_res
.options
& RES_DEBUG
)
printf("rcode = %d, ancount=%d\n", hp
->rcode
, ancount
);
/* Check if it's an authoritive answer */
h_errno
= HOST_NOT_FOUND
;
return ((struct hostent
*) NULL
);
buflen
= sizeof(hostbuf
);
cp
= (char *)&answer
+ sizeof(HEADER
);
if ((n
= dn_expand((char *)&answer
, eom
,
return ((struct hostent
*) NULL
);
cp
+= dn_skipname(cp
, eom
) + QFIXEDSZ
;
cp
+= dn_skipname(cp
, eom
) + QFIXEDSZ
;
h_errno
= HOST_NOT_FOUND
;
return ((struct hostent
*) NULL
);
host
.h_aliases
= host_aliases
;
#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
host
.h_addr_list
= h_addr_ptrs
;
while (--ancount
>= 0 && cp
< eom
) {
if ((n
= dn_expand((char *)&answer
, eom
, cp
, bp
, buflen
)) < 0)
cp
+= sizeof(u_short
) + sizeof(u_long
);
if (ap
>= &host_aliases
[MAXALIASES
-1])
if ((n
= dn_expand((char *)&answer
, eom
,
if (_res
.options
& RES_DEBUG
)
printf("unexpected answer type %d, size %d\n",
if (n
!= host
.h_length
) {
host
.h_addrtype
= (class == C_IN
) ? AF_INET
: AF_UNSPEC
;
bp
+= sizeof(align
) - ((u_long
)bp
% sizeof(align
));
if (bp
+ n
>= &hostbuf
[sizeof(hostbuf
)]) {
if (_res
.options
& RES_DEBUG
)
printf("size (%d) too big\n", n
);
bcopy(cp
, *hap
++ = bp
, n
);
#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
host
.h_addr
= h_addr_ptrs
[0];
return ((struct hostent
*) NULL
);
register char *cp
, **domain
;
struct hostent
*hp
, *gethostdomain();
extern struct hostent
*_gethtbyname();
if (!(_res
.options
& RES_INIT
) && res_init() == -1)
return ((struct hostent
*) NULL
);
* disallow names consisting only of digits/dots, unless
h_errno
= HOST_NOT_FOUND
;
return ((struct hostent
*) NULL
);
if (!isdigit(*cp
) && *cp
!= '.')
for (cp
= name
, n
= 0; *cp
; cp
++)
if (n
== 0 && (cp
= hostalias(name
)))
return (gethostdomain(cp
, (char *)NULL
));
if ((n
== 0 || *--cp
!= '.') && (_res
.options
& RES_DEFNAMES
))
for (domain
= _res
.dnsrch
; *domain
; domain
++) {
hp
= gethostdomain(name
, *domain
);
* If no server present, use host table.
* If host isn't found in this domain,
* keep trying higher domains in the search list
* On a NO_ADDRESS error, keep trying, otherwise
* a wildcard MX entry could keep us from finding
* host entries 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
)
return (_gethtbyname(name
));
if ((h_errno
!= HOST_NOT_FOUND
&& h_errno
!= NO_ADDRESS
) ||
(_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 (gethostdomain(name
, (char *)NULL
));
return ((struct hostent
*) NULL
);
gethostdomain(name
, domain
)
* Check for trailing '.';
* copy without '.' if present.
if (name
[n
] == '.' && n
< sizeof(nbuf
) - 1) {
(void)sprintf(nbuf
, "%.*s.%.*s",
MAXDNAME
, name
, MAXDNAME
, domain
);
n
= res_mkquery(QUERY
, longname
, C_IN
, T_A
, (char *)NULL
, 0, NULL
,
(char *)&buf
, sizeof(buf
));
if (_res
.options
& RES_DEBUG
)
printf("res_mkquery failed\n");
return ((struct hostent
*) NULL
);
return (getanswer((char *)&buf
, n
, 0));
gethostbyaddr(addr
, len
, type
)
register struct hostent
*hp
;
extern struct hostent
*_gethtbyaddr();
return ((struct hostent
*) NULL
);
(void)sprintf(qbuf
, "%d.%d.%d.%d.in-addr.arpa",
((unsigned)addr
[3] & 0xff),
((unsigned)addr
[2] & 0xff),
((unsigned)addr
[1] & 0xff),
((unsigned)addr
[0] & 0xff));
n
= res_mkquery(QUERY
, qbuf
, C_IN
, T_PTR
, (char *)NULL
, 0, NULL
,
(char *)&buf
, sizeof(buf
));
if (_res
.options
& RES_DEBUG
)
printf("res_mkquery failed\n");
return ((struct hostent
*) NULL
);
hp
= getanswer((char *)&buf
, n
, 1);
if (hp
== NULL
&& errno
== ECONNREFUSED
)
hp
= _gethtbyaddr(addr
, len
, type
);
return ((struct hostent
*) NULL
);
h_addr_ptrs
[0] = (char *)&host_addr
;
h_addr_ptrs
[1] = (char *)0;
host_addr
= *(struct in_addr
*)addr
;
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);
hostf
= fopen(HOSTDB
, "r" );
if (hostf
&& !stayopen
) {
if (hostf
== NULL
&& (hostf
= fopen(HOSTDB
, "r" )) == NULL
)
if ((p
= fgets(line
, BUFSIZ
, hostf
)) == NULL
)
/* THIS STUFF IS INTERNET SPECIFIC */
#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
host
.h_addr_list
= host_addrs
;
*((u_long
*)host
.h_addr
) = inet_addr(p
);
host
.h_length
= sizeof (u_long
);
host
.h_addrtype
= AF_INET
;
while (*cp
== ' ' || *cp
== '\t')
q
= host
.h_aliases
= host_aliases
;
if (*cp
== ' ' || *cp
== '\t') {
if (q
< &host_aliases
[MAXALIASES
- 1])
for (mp
= match
; *mp
; mp
++)
register struct hostent
*p
;
while (p
= _gethtent()) {
if (strcasecmp(p
->h_name
, name
) == 0)
for (cp
= p
->h_aliases
; *cp
!= 0; cp
++)
if (strcasecmp(*cp
, name
) == 0)
_gethtbyaddr(addr
, len
, type
)
register struct hostent
*p
;
if (p
->h_addrtype
== type
&& !bcmp(p
->h_addr
, addr
, len
))