home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / comm / amitcp-3.0ß2.lha / AmiTCP / src / amitcp / api / res_query.c < prev    next >
C/C++ Source or Header  |  1994-04-02  |  11KB  |  378 lines

  1. /*
  2.  * $Id: res_query.c,v 3.4 1994/04/02 11:06:28 jraja Exp $
  3.  *
  4.  * Author: Tomi Ollila <too@cs.hut.fi>
  5.  *
  6.  *     Copyright (c) 1993 
  7.  *         All rights reserved
  8.  *
  9.  * Created: Sun May 16 21:08:43 1993 too
  10.  * Last modified: Thu Jan 20 02:23:00 1994 jraja
  11.  *
  12.  *
  13.  * HISTORY
  14.  * $Log: res_query.c,v $
  15.  * Revision 3.4  1994/04/02  11:06:28  jraja
  16.  * Moved global resolver variables to SocketBase, removed res_lock.
  17.  *
  18.  * Revision 3.3  1994/01/20  02:31:37  jraja
  19.  * Added include <conf.h> as the first include, changed <errno.h> to
  20.  * <sys/errno.h>, removed errno definition and changed to use
  21.  * writeErrnoValue() and readErrnoValue() instead.
  22.  *
  23.  * Revision 3.2  1994/01/18  19:20:37  jraja
  24.  * Changed errno macro to use baseErrno() macro.
  25.  *
  26.  * Revision 3.1  1994/01/04  14:05:21  too
  27.  * Removed "global" unused variable h_errno. Now it is defined to
  28.  * libPtr->hErrno in resolv.h
  29.  *
  30.  * Revision 1.3  1993/12/21  22:03:24  jraja
  31.  * Added one 'const'.
  32.  *
  33.  * Revision 1.2  1993/06/02  19:26:17  too
  34.  * Moved resolver stuff here from kern/ -directory
  35.  *
  36.  * Revision 1.1  1993/06/01  16:30:33  too
  37.  * Initial revision
  38.  *
  39.  */
  40. /*
  41.  * Copyright (c) 1988 Regents of the University of California.
  42.  * All rights reserved.
  43.  *
  44.  * Redistribution and use in source and binary forms, with or without
  45.  * modification, are permitted provided that the following conditions
  46.  * are met:
  47.  * 1. Redistributions of source code must retain the above copyright
  48.  *    notice, this list of conditions and the following disclaimer.
  49.  * 2. Redistributions in binary form must reproduce the above copyright
  50.  *    notice, this list of conditions and the following disclaimer in the
  51.  *    documentation and/or other materials provided with the distribution.
  52.  * 3. All advertising materials mentioning features or use of this software
  53.  *    must display the following acknowledgement:
  54.  *    This product includes software developed by the University of
  55.  *    California, Berkeley and its contributors.
  56.  * 4. Neither the name of the University nor the names of its contributors
  57.  *    may be used to endorse or promote products derived from this software
  58.  *    without specific prior written permission.
  59.  *
  60.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  61.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  62.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  63.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  64.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  65.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  66.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  67.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  68.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  69.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  70.  * SUCH DAMAGE.
  71.  */
  72.  
  73. #if defined(LIBC_SCCS) && !defined(lint)
  74. static char sccsid[] = "@(#)res_query.c    5.11 (Berkeley) 3/6/91";
  75. #endif /* LIBC_SCCS and not lint */
  76.  
  77. #include <conf.h>
  78.  
  79. #include <sys/param.h>
  80. #include <sys/malloc.h>
  81. #include <netinet/in.h>
  82. /* #include <arpa/inet.h> */
  83. #include <api/arpa_nameser.h>
  84. #include <api/resolv.h> /* resolv.h now inside AmiTCP */
  85. #include <netdb.h>
  86. #ifndef AMITCP
  87. #include <ctype.h>
  88. #endif     
  89. #include <sys/errno.h>
  90.  
  91. #include <kern/amiga_includes.h>
  92. #include <kern/amiga_subr.h>     
  93. #include <api/amiga_api.h>
  94. #include <kern/amiga_netdb.h>
  95.      
  96. #if PACKETSZ > 1024
  97. #define MAXPACKET    PACKETSZ
  98. #else
  99. #define MAXPACKET    1024
  100. #endif
  101.     
  102. /*
  103.  * Formulate a normal query, send, and await answer.
  104.  * Returned answer is placed in supplied buffer "answer".
  105.  * Perform preliminary check of answer, returning success only
  106.  * if no error is indicated and the answer count is nonzero.
  107.  * Return the size of the response on success, -1 on error.
  108.  * Caller must parse answer and determine whether it answers the question.
  109.  */
  110. int
  111. res_query(struct SocketBase *    libPtr,
  112.       const char *        name,        /* domain name */
  113.       int             class,
  114.       int            type,        /* class and type of query */
  115.       u_char *        answer,        /* buffer to put answer */
  116.       int             anslen)        /* size of answer buffer */
  117. {
  118.     char *buf;
  119.     HEADER *hp;
  120.     int n;
  121.  
  122.     /* an idea to remove reduntant bsd_mallocs and bsd_frees. let's make
  123.        a new structure in gethostby(name|addr) and put libPrt->buffer
  124.        point to it (first item in new structure is old value of that
  125.        buffer). that structure holds pointers to all needed character
  126.        buffers and is initialized to NULL. at end gethostby... bsd_frees
  127.        all buffers that are pointed there */
  128.     
  129.     if ((buf = bsd_malloc(MAXPACKET, M_TEMP, M_WAITOK)) == NULL) {
  130.       writeErrnoValue(libPtr, ENOMEM);
  131.       return -1;
  132.     }
  133. #ifdef RES_DEBUG
  134.         printf("res_query(%s, %d, %d)\n", name, class, type);
  135. #endif
  136.     n = res_mkquery(libPtr, QUERY, name, class, type, (char *)NULL, 0, NULL,
  137.             buf, MAXPACKET);
  138.  
  139.     if (n <= 0) {
  140. #ifdef RES_DEBUG
  141.             printf("res_query: mkquery failed\n");
  142. #endif
  143.             h_errno = NO_RECOVERY;
  144.             goto Return;
  145.     }
  146.     n = res_send(libPtr, buf, n, (char *)answer, anslen);
  147.     if (n < 0) {
  148. #ifdef RES_DEBUG
  149.             printf("res_query: send error\n");
  150. #endif
  151.             h_errno = TRY_AGAIN;
  152.             goto Return;
  153.     }
  154.  
  155.     hp = (HEADER *) answer;
  156.     if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
  157. #ifdef RES_DEBUG
  158.             printf("rcode = %d, ancount=%d\n", hp->rcode,
  159.                 ntohs(hp->ancount));
  160. #endif
  161.         switch (hp->rcode) {
  162.             case NXDOMAIN:
  163.                 h_errno = HOST_NOT_FOUND;
  164.                 break;
  165.             case SERVFAIL:
  166.                 h_errno = TRY_AGAIN;
  167.                 break;
  168.             case NOERROR:
  169.                 h_errno = NO_DATA;
  170.                 break;
  171.             case FORMERR:
  172.             case NOTIMP:
  173.             case REFUSED:
  174.             default:
  175.                 h_errno = NO_RECOVERY;
  176.                 break;
  177.         }
  178.         n = -1;
  179.         goto Return;
  180.     }
  181.       Return:
  182.     bsd_free(buf, M_TEMP);
  183.     return(n);
  184. }
  185.  
  186. /*
  187.  * Formulate a normal query, send, and retrieve answer in supplied buffer.
  188.  * Return the size of the response on success, -1 on error.
  189.  * If enabled, implement search rules until answer or unrecoverable failure
  190.  * is detected.  Error number is left in h_errno.
  191.  * Only useful for queries in the same name hierarchy as the local host
  192.  * (not, for example, for host address-to-name lookups in domain in-addr.arpa).
  193.  */
  194. int
  195. res_search(struct SocketBase *    libPtr,
  196.        const char *        name,        /* domain name */
  197.        int            class,
  198.        int            type,        /* class and type of query */
  199.        u_char *        answer,        /* buffer to put answer */
  200.        int             anslen)        /* size of answer */
  201. {
  202.     register const char *cp;
  203.     struct DomainentNode * domain;
  204.     
  205.     int n, ret, got_nodata = 0;
  206. #ifndef AMICTP
  207.     char *__hostalias();
  208. #endif /* ! AMITCP */    
  209.  
  210. #ifndef AMITCP
  211.     if ((_res.options & RES_INIT) == 0 && res_init() == -1)
  212.         return (-1);
  213. #endif /* !AMITCP */
  214.     writeErrnoValue(libPtr, 0);
  215.     h_errno = HOST_NOT_FOUND;           /* default, if we never query */
  216.     for (cp = name, n = 0; *cp; cp++)
  217.         if (*cp == '.')
  218.             n++;
  219. #ifndef AMITCP
  220.     if (n == 0 && (cp = __hostalias(name)))
  221.         return (res_query(cp, class, type, answer, anslen));
  222. #endif /* !AMITCP */
  223.  
  224.     /*
  225.      * We do at least one level of search if
  226.      *    - there is no dot and RES_DEFNAME is set, or
  227.      *    - there is at least one dot, there is no trailing dot,
  228.      *      and RES_DNSRCH is set.
  229.      */
  230.     if ((n == 0 && _res.options & RES_DEFNAMES) ||
  231.        (n != 0 && *--cp != '.' && _res.options & RES_DNSRCH))
  232.  
  233.       for (domain = (struct DomainentNode *)NDB->ndb_Domains.mlh_Head;
  234.            domain->dn_Node.mln_Succ;
  235.            domain = (struct DomainentNode *)domain->dn_Node.mln_Succ) {
  236.         ret = res_querydomain(libPtr, name, domain->dn_Ent.d_name,
  237.                   class, type, answer, anslen);
  238.         if (ret > 0)
  239.             return (ret);
  240.         /*
  241.          * If no server present, give up.
  242.          * If name isn't found in this domain,
  243.          * keep trying higher domains in the search list
  244.          * (if that's enabled).
  245.          * On a NO_DATA error, keep trying, otherwise
  246.          * a wildcard entry of another type could keep us
  247.          * from finding this entry higher in the domain.
  248.          * If we get some other error (negative answer or
  249.          * server failure), then stop searching up,
  250.          * but try the input name below in case it's fully-qualified.
  251.          */
  252.         if (readErrnoValue(libPtr) == ECONNREFUSED) {
  253.             h_errno = TRY_AGAIN;
  254.             return (-1);
  255.         }
  256.         if (h_errno == NO_DATA)
  257.             got_nod