* Copyright (c) 1986 Eric P. Allman
* Copyright (c) 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, 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'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)domain.c 5.16 (Berkeley) %G% (with name server)";
static char sccsid
[] = "@(#)domain.c 5.16 (Berkeley) %G% (without name server)";
#include <arpa/nameser.h>
static char hostbuf
[MAXMXHOSTS
*PACKETSZ
];
getmxrr(host
, mxhosts
, localhost
, rcode
)
char *host
, **mxhosts
, *localhost
;
register u_char
*eom
, *cp
;
register int i
, j
, n
, nmx
;
int ancount
, qdcount
, buflen
, seenlocal
;
u_short pref
, localpref
, type
, prefer
[MAXMXHOSTS
];
n
= res_search(host
, C_IN
, T_MX
, (char *)&answer
, sizeof(answer
));
printf("getmxrr: res_search failed (errno=%d, h_errno=%d)\n",
/* no MX data on this host */
/* the host just doesn't exist */
/* couldn't connect to the name server */
if (!UseNameServer
&& errno
== ECONNREFUSED
)
/* it might come up later; better queue it up */
/* irreconcilable differences */
/* find first satisfactory answer */
cp
= (u_char
*)&answer
+ sizeof(HEADER
);
eom
= (u_char
*)&answer
+ n
;
for (qdcount
= ntohs(hp
->qdcount
); qdcount
--; cp
+= n
+ QFIXEDSZ
)
if ((n
= dn_skipname(cp
, eom
)) < 0)
buflen
= sizeof(hostbuf
);
ancount
= ntohs(hp
->ancount
);
while (--ancount
>= 0 && cp
< eom
&& nmx
< MAXMXHOSTS
) {
if ((n
= dn_expand((char *)&answer
, eom
, cp
, bp
, buflen
)) < 0)
cp
+= sizeof(u_short
) + sizeof(u_long
);
if (tTd(8, 1) || _res
.options
& RES_DEBUG
)
printf("unexpected answer type %d, size %d\n",
if ((n
= dn_expand((char *)&answer
, eom
, cp
, bp
, buflen
)) < 0)
if (!strcasecmp(bp
, localhost
)) {
if (seenlocal
== 0 || pref
< localpref
)
punt
: mxhosts
[0] = strcpy(hostbuf
, host
);
for (i
= 0; i
< nmx
; i
++) {
for (j
= i
+ 1; j
< nmx
; j
++) {
if (prefer
[i
] > prefer
[j
]) {
if (seenlocal
&& prefer
[i
] >= localpref
) {
* truncate higher pref part of list; if we're
* the best choice left, we should have realized
* awhile ago that this was a local delivery.
getcanonname(host
, hbsize
)
register u_char
*eom
, *cp
;
int first
, ancount
, qdcount
, loopcnt
;
n
= res_search(host
, C_IN
, T_CNAME
, (char *)&answer
, sizeof(answer
));
printf("getcanonname: res_search failed (errno=%d, h_errno=%d)\n",
/* find first satisfactory answer */
ancount
= ntohs(hp
->ancount
);
/* we don't care about errors here, only if we got an answer */
printf("rcode = %d, ancount=%d\n", hp
->rcode
, ancount
);
cp
= (u_char
*)&answer
+ sizeof(HEADER
);
eom
= (u_char
*)&answer
+ n
;
for (qdcount
= ntohs(hp
->qdcount
); qdcount
--; cp
+= n
+ QFIXEDSZ
)
if ((n
= dn_skipname(cp
, eom
)) < 0)
* just in case someone puts a CNAME record after another record,
* check all records for CNAME; otherwise, just take the first
for (first
= 1; --ancount
>= 0 && cp
< eom
; cp
+= n
) {
if ((n
= dn_expand((char *)&answer
, eom
, cp
, nbuf
,
(void)strncpy(host
, nbuf
, hbsize
);
cp
+= sizeof(u_short
) + sizeof(u_long
);
* assume that only one cname will be found. More
* than one is undefined. Copy so that if dn_expand
* fails, `host' is still okay.
if ((n
= dn_expand((char *)&answer
, eom
, cp
, nbuf
,
(void)strncpy(host
, nbuf
, hbsize
); /* XXX */
if (++loopcnt
> 8) /* never be more than 1 */