# 2.11BSD#431 - /usr/src/lib/libc/net/res_query.c

##### Functions

    hostalias         X
    res_query         X
    res_querydomain   X
    res_search        X

##### Variables

    h_errno           X

##### Macros

    MAXPACKET         X

       1: /*
       2:  * Copyright (c) 1988 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that this notice is preserved and that due credit is given
       7:  * to the University of California at Berkeley. The name of the University
       8:  * may not be used to endorse or promote products derived from this
       9:  * software without specific prior written permission. This software
      10:  * is provided ``as is'' without express or implied warranty.
      11:  */
      12:
      13: #if defined(LIBC_SCCS) && !defined(lint)
      14: static char sccsid[] = "@(#)res_query.c	5.3 (Berkeley) 4/5/88";
      15: #endif /* LIBC_SCCS and not lint */
      16:
      17: #include <sys/param.h>
      18: #include <sys/socket.h>
      19: #include <netinet/in.h>
      20: #include <ctype.h>
      21: #include <netdb.h>
      22: #include <stdio.h>
      23: #include <errno.h>
      24: #include <strings.h>
      25: #include <arpa/inet.h>
      26: #include <arpa/nameser.h>
      27: #include <resolv.h>
      28:
      29: #if PACKETSZ > 1024
      30: #define MAXPACKET   PACKETSZ
      31: #else
      32: #define MAXPACKET   1024
      33: #endif
      34:
      35: extern int errno;
      36: int h_errno;
      37:
      38: /*
      39:  * Formulate a normal query, send, and await answer.
      40:  * Returned answer is placed in supplied buffer "answer".
      41:  * Perform preliminary check of answer, returning success only
      42:  * if no error is indicated and the answer count is nonzero.
      43:  * Return the size of the response on success, -1 on error.
      44:  * Error number is left in h_errno.
      45:  * Caller must parse answer and determine whether it answers the question.
      46:  */
      47: res_query(name, class, type, answer, anslen)
      48:     char *name;     /* domain name */
      49:     int class, type;    /* class and type of query */
      50:     u_char *answer;     /* buffer to put answer */
      51:     int anslen;     /* size of answer buffer */
      52: {
      53:     char buf[MAXPACKET];
      54:     HEADER *hp;
      55:     int n;
      56:
      57:     if ((_res.options & RES_INIT) == 0 && res_init() == -1)
      58:         return (-1);
      59: #ifdef DEBUG
      60:     if (_res.options & RES_DEBUG)
      61:         printf("res_query(%s, %d, %d)\n", name, class, type);
      62: #endif
      63:     n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL,
      64:         buf, sizeof(buf));
      65:
      66:     if (n <= 0) {
      67: #ifdef DEBUG
      68:         if (_res.options & RES_DEBUG)
      69:             printf("res_query: mkquery failed\n");
      70: #endif
      71:         h_errno = NO_RECOVERY;
      72:         return (n);
      73:     }
      74:     n = res_send(buf, n, answer, anslen);
      75:     if (n < 0) {
      76: #ifdef DEBUG
      77:         if (_res.options & RES_DEBUG)
      78:             printf("res_query: send error\n");
      79: #endif
      80:         h_errno = TRY_AGAIN;
      81:         return(n);
      82:     }
      83:
      84:     hp = (HEADER *) answer;
      85:     if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
      86: #ifdef DEBUG
      87:         if (_res.options & RES_DEBUG)
      88:             printf("rcode = %d, ancount=%d\n", hp->rcode,
      89:                 ntohs(hp->ancount));
      90: #endif
      91:         switch (hp->rcode) {
      92:             case NXDOMAIN:
      93:                 h_errno = HOST_NOT_FOUND;
      94:                 break;
      95:             case SERVFAIL:
      96:                 h_errno = TRY_AGAIN;
      97:                 break;
      98:             case NOERROR:
      99:                 h_errno = NO_DATA;
     100:                 break;
     101:             case FORMERR:
     102:             case NOTIMP:
     103:             case REFUSED:
     104:             default:
     105:                 h_errno = NO_RECOVERY;
     106:                 break;
     107:         }
     108:         return (-1);
     109:     }
     110:     return(n);
     111: }
     112:
     113: /*
     114:  * Formulate a normal query, send, and retrieve answer in supplied buffer.
     115:  * Return the size of the response on success, -1 on error.
     116:  * If enabled, implement search rules until answer or unrecoverable failure
     117:  * is detected.  Error number is left in h_errno.
     118:  * Only useful for queries in the same name hierarchy as the local host
     119:  * (not, for example, for host address-to-name lookups in domain in-addr.arpa).
     120:  */
     121: res_search(name, class, type, answer, anslen)
     122:     char *name;     /* domain name */
     123:     int class, type;    /* class and type of query */
     124:     u_char *answer;     /* buffer to put answer */
     125:     int anslen;     /* size of answer */
     126: {
     127:     register char *cp, **domain;
     128:     int n, ret;
     129:     char *hostalias();
     130:
     131:     if ((_res.options & RES_INIT) == 0 && res_init() == -1)
     132:         return (-1);
     133:
     134:     errno = 0;
     135:     h_errno = HOST_NOT_FOUND;       /* default, if we never query */
     136:     for (cp = name, n = 0; *cp; cp++)
     137:         if (*cp == '.')
     138:             n++;
     139:     if (n == 0 && (cp = hostalias(name)))
     140:         return (res_query(cp, class, type, answer, anslen));
     141:
     142:     if ((n == 0 || *--cp != '.') && (_res.options & RES_DEFNAMES))
     143:         for (domain = _res.dnsrch; *domain; domain++) {
     144:         h_errno = 0;
     145:         ret = res_querydomain(name, *domain, class, type,
     146:             answer, anslen);
     147:         if (ret > 0)
     148:             return (ret);
     149:         /*
     150: 		 * If no server present, give up.
     151: 		 * If name isn't found in this domain,
     152: 		 * keep trying higher domains in the search list
     153: 		 * (if that's enabled).
     154: 		 * On a NO_DATA error, keep trying, otherwise
     155: 		 * a wildcard entry of another type could keep us
     156: 		 * from finding this entry higher in the domain.
     157: 		 * If we get some other error (non-authoritative negative
     158: 		 * answer or server failure), then stop searching up,
     159: 		 * but try the input name below in case it's fully-qualified.
     160: 		 */
     161:         if (errno == ECONNREFUSED) {
     162:             h_errno = TRY_AGAIN;
     163:             return (-1);
     164:         }
     165:         if ((h_errno != HOST_NOT_FOUND && h_errno != NO_DATA) ||
     166:             (_res.options & RES_DNSRCH) == 0)
     167:             break;
     168:         }
     169:     /*
     170: 	 * If the search/default failed, try the name as fully-qualified,
     171: 	 * but only if it contained at least one dot (even trailing).
     172: 	 */
     173:     if (n)
     174:         return (res_querydomain(name, (char *)NULL, class, type,
     175:             answer, anslen));
     176:     return (-1);
     177: }
     178:
     179: /*
     180:  * Perform a call on res_query on the concatenation of name and domain,
     181:  * removing a trailing dot from name if domain is NULL.
     182:  */
     183: res_querydomain(name, domain, class, type, answer, anslen)
     184:     char *name, *domain;
     185:     int class, type;    /* class and type of query */
     186:     u_char *answer;     /* buffer to put answer */
     187:     int anslen;     /* size of answer */
     188: {
     189:     char nbuf[2*MAXDNAME+2];
     190:     char *longname = nbuf;
     191:     int n;
     192:
     193: #ifdef DEBUG
     194:     if (_res.options & RES_DEBUG)
     195:         printf("res_querydomain(%s, %s, %d, %d)\n",
     196:             name, domain, class, type);
     197: #endif
     198:     if (domain == NULL) {
     199:         /*
     200: 		 * Check for trailing '.';
     201: 		 * copy without '.' if present.
     202: 		 */
     203:         n = strlen(name) - 1;
     204:         if (name[n] == '.' && n < sizeof(nbuf) - 1) {
     205:             bcopy(name, nbuf, n);
     206:             nbuf[n] = '\0';
     207:         } else
     208:             longname = name;
     209:     } else
     210:         (void)sprintf(nbuf, "%.*s.%.*s",
     211:             MAXDNAME, name, MAXDNAME, domain);
     212:
     213:     return (res_query(longname, class, type, answer, anslen));
     214: }
     215:
     216: char *
     217: hostalias(name)
     218:     register char *name;
     219: {
     220:     register char *C1, *C2;
     221:     FILE *fp;
     222:     char *file, *getenv(), *strcpy(), *strncpy();
     223:     char buf[BUFSIZ];
     224:     static char abuf[MAXDNAME];
     225:
     226:     file = getenv("HOSTALIASES");
     227:     if (file == NULL || (fp = fopen(file, "r")) == NULL)
     228:         return (NULL);
     229:     buf[sizeof(buf) - 1] = '\0';
     230:     while (fgets(buf, sizeof(buf), fp)) {
     231:         for (C1 = buf; *C1 && !isspace(*C1); ++C1);
     232:         if (!*C1)
     233:             break;
     234:         *C1 = '\0';
     235:         if (!strcasecmp(buf, name)) {
     236:             while (isspace(*++C1));
     237:             if (!*C1)
     238:                 break;
     239:             for (C2 = C1 + 1; *C2 && !isspace(*C2); ++C2);
     240:             abuf[sizeof(abuf) - 1] = *C2 = '\0';
     241:             (void)strncpy(abuf, C1, sizeof(abuf) - 1);
     242:             fclose(fp);
     243:             return (abuf);
     244:         }
     245:     }
     246:     fclose(fp);
     247:     return (NULL);
     248: }

#### Defined functions

hostalias defined in line 216; used 4 times

- in line 129, 139
- in /usr/src/usr.sbin/named/tools/nslookup/getinfo.c line 523, 546

res_query defined in line 47; used 3 times

- in line 140, 213
- in /usr/src/lib/libc/net/named/gethnamadr.c line 262

res_querydomain defined in line 183; used 2 times

- in line 145, 174

res_search defined in line 121; used 3 times

- in /usr/src/lib/libc/net/named/gethnamadr.c line 231
- in /usr/src/usr.sbin/sendmail.MX/src/domain.c line 49, 167

#### Defined variables

h_errno defined in line 36; used 52 times

- in line 71, 80, 93-99(3), 105, 135, 144, 162-165(3)
- in /usr/src/lib/libc/net/herror.c line 43(2)
- in /usr/src/lib/libc/net/hosttable/gethnamadr.c line 119, 143, 154
- in /usr/src/lib/libc/net/named/gethnamadr.c line 93, 107-109(2), 200, 224
- in /usr/src/lib/libc/net/res_query.c line 71, 80, 93-99(3), 105, 135, 144, 162-165(3)
- in /usr/src/usr.sbin/arp/arp.c line 277, 336
- in /usr/src/usr.sbin/named/tools/nslookup/main.c line 146
- in /usr/src/usr.sbin/sendmail.MX/src/daemon.c line 310, 337
- in /usr/src/usr.sbin/sendmail.MX/src/deliver.c line 980, 1004-1008(2), 1072
- in /usr/src/usr.sbin/sendmail.MX/src/domain.c line 40, 54-56(2), 162, 172
- in /usr/src/usr.sbin/sendmail/src/daemon.c line 310, 337
- in /usr/src/usr.sbin/sendmail/src/deliver.c line 922, 946-950(2), 1017

sccsid defined in line 14; never used

#### Defined macros

MAXPACKET defined in line 32; used 1 times

- in line 53

Last modified: 1988-09-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1182 |