diff options
Diffstat (limited to 'lib/libc/net/res_query.c')
-rw-r--r-- | lib/libc/net/res_query.c | 73 |
1 files changed, 52 insertions, 21 deletions
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c index 7649462e563..81c4d3194d3 100644 --- a/lib/libc/net/res_query.c +++ b/lib/libc/net/res_query.c @@ -1,4 +1,4 @@ -/* $NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $ */ +/* $NetBSD: res_query.c,v 1.10 1996/02/02 15:22:34 mrg Exp $ */ /*- * Copyright (c) 1988, 1993 @@ -56,9 +56,9 @@ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_query.c,v 1.1 1993/06/01 09:42:14 vixie Exp vixie "; +static char rcsid[] = "$Id: res_query.c,v 8.6 1995/06/29 09:26:28 vixie Exp "; #else -static char rcsid[] = "$NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $"; +static char rcsid[] = "$NetBSD: res_query.c,v 1.10 1996/02/02 15:22:34 mrg Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -90,27 +90,33 @@ int h_errno; * 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. */ +int res_query(name, class, type, answer, anslen) - char *name; /* domain name */ + const 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 */ { - char buf[MAXPACKET]; - HEADER *hp; + u_char buf[MAXPACKET]; + register HEADER *hp = (HEADER *) answer; int n; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) + hp->rcode = NOERROR; /* default */ + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; return (-1); + } #ifdef DEBUG if (_res.options & RES_DEBUG) printf(";; res_query(%s, %d, %d)\n", name, class, type); #endif - n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL, - buf, sizeof(buf)); + n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, + buf, sizeof(buf)); if (n <= 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) @@ -119,7 +125,7 @@ res_query(name, class, type, answer, anslen) h_errno = NO_RECOVERY; return (n); } - n = res_send(buf, n, (char *)answer, anslen); + n = res_send(buf, n, answer, anslen); if (n < 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) @@ -174,10 +180,15 @@ res_search(name, class, type, answer, anslen) int anslen; /* size of answer */ { register char *cp, **domain; - int dots, trailing_dot, ret, got_nodata, saved_herrno, tried_as_is; + HEADER *hp = (HEADER *) answer; + u_int dots; + int trailing_dot, ret, saved_herrno; + int got_nodata = 0, got_servfail = 0, tried_as_is = 0; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; return (-1); + } got_nodata = 0; errno = 0; @@ -188,13 +199,13 @@ res_search(name, class, type, answer, anslen) dots++; } trailing_dot = 0; - if ((cp > name) && (*--cp == '.')) + if (cp > name && *--cp == '.') trailing_dot++; /* * if there aren't any dots, it could be a user-level alias */ - if (!dots && (cp = __hostalias(name))) + if (!dots && (cp = __hostalias(name)) != NULL) return (res_query(cp, class, type, answer, anslen)); /* @@ -251,6 +262,13 @@ res_search(name, class, type, answer, anslen) case HOST_NOT_FOUND: /* keep trying */ break; + case TRY_AGAIN: + if (hp->rcode == SERVFAIL) { + /* try next search element, if any */ + got_servfail++; + break; + } + /* FALLTHROUGH */ default: /* anything else implies that we're done */ done++; @@ -291,6 +309,8 @@ res_search(name, class, type, answer, anslen) h_errno = saved_herrno; else if (got_nodata) h_errno = NO_DATA; + else if (got_servfail) + h_errno = TRY_AGAIN; return (-1); } @@ -298,20 +318,25 @@ res_search(name, class, type, answer, anslen) * Perform a call on res_query on the concatenation of name and domain, * removing a trailing dot from name if domain is NULL. */ +int res_querydomain(name, domain, class, type, answer, anslen) - char *name, *domain; + const char *name, *domain; int class, type; /* class and type of query */ u_char *answer; /* buffer to put answer */ int anslen; /* size of answer */ { char nbuf[2*MAXDNAME+2]; - char *longname = nbuf; + const char *longname = nbuf; int n; + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (-1); + } #ifdef DEBUG if (_res.options & RES_DEBUG) printf(";; res_querydomain(%s, %s, %d, %d)\n", - name, domain, class, type); + name, domain?domain:"<Nil>", class, type); #endif if (domain == NULL) { /* @@ -337,24 +362,30 @@ __hostalias(name) { register char *cp1, *cp2; FILE *fp; - char *file, *getenv(), *strcpy(), *strncpy(); + char *file; char buf[BUFSIZ]; static char abuf[MAXDNAME]; + if (_res.options & RES_NOALIASES) + return (NULL); file = getenv("HOSTALIASES"); if (file == NULL || (fp = fopen(file, "r")) == NULL) return (NULL); + setbuf(fp, NULL); buf[sizeof(buf) - 1] = '\0'; while (fgets(buf, sizeof(buf), fp)) { - for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1); + for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1) + ; if (!*cp1) break; *cp1 = '\0'; if (!strcasecmp(buf, name)) { - while (isspace(*++cp1)); + while (isspace(*++cp1)) + ; if (!*cp1) break; - for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2); + for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) + ; abuf[sizeof(abuf) - 1] = *cp2 = '\0'; (void)strncpy(abuf, cp1, sizeof(abuf) - 1); fclose(fp); |