home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / named / tools / nslookup / subr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-24  |  12.5 KB  |  510 lines

  1. /*
  2.  * Copyright (c) 1985,1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)subr.c    5.24 (Berkeley) 3/2/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  *******************************************************************************
  40.  *
  41.  *  subr.c --
  42.  *
  43.  *    Miscellaneous subroutines for the name server
  44.  *    lookup program.
  45.  *
  46.  *    Copyright (c) 1985
  47.  *    Andrew Cherenson
  48.  *    U.C. Berkeley
  49.  *    CS298-26  Fall 1985
  50.  *
  51.  *******************************************************************************
  52.  */
  53.  
  54. #include <sys/types.h>
  55. #include <sys/param.h>
  56. #include <netdb.h>
  57. #include <sys/socket.h>
  58. #include <netinet/in.h>
  59. #include <arpa/nameser.h>
  60. #include <arpa/inet.h>
  61. #include <signal.h>
  62. #include <setjmp.h>
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <string.h>
  66. #include "res.h"
  67.  
  68.  
  69.  
  70. /*
  71.  *******************************************************************************
  72.  *
  73.  *  IntrHandler --
  74.  *
  75.  *    This routine is called whenever a control-C is typed.
  76.  *    It performs three main functions:
  77.  *     - closes an open socket connection,
  78.  *     - closes an open output file (used by LookupHost, et al.),
  79.  *     - jumps back to the main read-eval loop.
  80.  *
  81.  *    If a user types a ^C in the middle of a routine that uses a socket,
  82.  *    the routine would not be able to close the socket. To prevent an
  83.  *    overflow of the process's open file table, the socket and output
  84.  *    file descriptors are closed by the interrupt handler.
  85.  *
  86.  *  Side effects:
  87.  *    Open file descriptors are closed.
  88.  *    If filePtr is valid, it is closed.
  89.  *    Flow of control returns to the main() routine.
  90.  *
  91.  *******************************************************************************
  92.  */
  93.  
  94. void
  95. IntrHandler()
  96. {
  97.     extern jmp_buf env;
  98. #if defined(BSD) && BSD >= 199006
  99.     extern FILE *yyin;        /* scanner input file */
  100.     extern void yyrestart();    /* routine to restart scanner after interrupt */
  101. #endif
  102.  
  103.     SendRequest_close();
  104.     ListHost_close();
  105.     if (filePtr != NULL && filePtr != stdout) {
  106.     fclose(filePtr);
  107.     filePtr = NULL;
  108.     }
  109.     printf("\n");
  110. #if defined(BSD) && BSD >= 199006
  111.     yyrestart(yyin);
  112. #endif
  113.     longjmp(env, 1);
  114. }
  115.  
  116.  
  117. /*
  118.  *******************************************************************************
  119.  *
  120.  *  Malloc --
  121.  *  Calloc --
  122.  *
  123.  *      Calls the malloc library routine with SIGINT blocked to prevent
  124.  *    corruption of malloc's data structures. We need to do this because
  125.  *    a control-C doesn't kill the program -- it causes a return to the
  126.  *    main command loop.
  127.  *
  128.  *    NOTE: This method doesn't prevent the pointer returned by malloc
  129.  *    from getting lost, so it is possible to get "core leaks".
  130.  *
  131.  *    If malloc fails, the program exits.
  132.  *
  133.  *  Results:
  134.  *    (address)    - address of new buffer.
  135.  *
  136.  *******************************************************************************
  137.  */
  138.  
  139. char *
  140. Malloc(size)
  141.     int size;
  142. {
  143.     char    *ptr;
  144.  
  145. #ifdef SYSV
  146. #ifdef SVR3
  147.     sighold(SIGINT);
  148.     ptr = malloc((unsigned) size);
  149.     sigrelse(SIGINT);
  150. #else
  151.     { int (*old)();
  152.       old = signal(SIGINT, SIG_IGN);
  153.       ptr = malloc((unsigned) size);
  154.       signal(SIGINT, old);
  155.     }
  156. #endif
  157. #else
  158.     { int saveMask;
  159.       saveMask = sigblock(sigmask(SIGINT));
  160.       ptr = malloc((unsigned) size);
  161.       (void) sigsetmask(saveMask);
  162.     }
  163. #endif
  164.     if (ptr == NULL) {
  165.     fflush(stdout);
  166.     fprintf(stderr, "*** Can't allocate memory\n");
  167.     fflush(stderr);
  168.     abort();
  169.     /*NOTREACHED*/
  170.     } else {
  171.     return(ptr);
  172.     }
  173. }
  174.  
  175. char *
  176. Calloc(num, size)
  177.     register int num, size;
  178. {
  179.     char *ptr = Malloc(num*size);
  180.     bzero(ptr, num*size);
  181.     return(ptr);
  182. }
  183.  
  184.  
  185. /*
  186.  *******************************************************************************
  187.  *
  188.  *  PrintHostInfo --
  189.  *
  190.  *    Prints out the HostInfo structure for a host.
  191.  *
  192.  *******************************************************************************
  193.  */
  194.  
  195. void
  196. PrintHostInfo(file, title, hp)
  197.     FILE    *file;
  198.     char    *title;
  199.     register HostInfo *hp;
  200. {
  201.     register char        **cp;
  202.     register ServerInfo    **sp;
  203.     char            comma;
  204.     int            i;
  205.  
  206.     fprintf(file, "%-7s  %s", title, hp->name);
  207.  
  208.     if (hp->addrList != NULL) {
  209.         if (hp->addrList[1] != NULL) {
  210.         fprintf(file, "\nAddresses:");
  211.         } else {
  212.         fprintf(file, "\nAddress:");
  213.         }
  214.         comma = ' ';
  215.         i = 0;
  216.         for (cp = hp->addrList; cp && *cp; cp++) {
  217.         i++;
  218.         if (i > 4) {
  219.             fprintf(file, "\n\t");
  220.             comma = ' ';
  221.             i = 0;
  222.         }
  223.         fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
  224.         comma = ',';
  225.         }
  226.     }
  227.  
  228.     if (hp->aliases != NULL) {
  229.         fprintf(file, "\nAliases:");
  230.         comma = ' ';
  231.         i = 10;
  232.         for (cp = hp->aliases; cp && *cp && **cp; cp++) {
  233.         i += strlen(*cp) + 2;
  234.         if (i > 75) {
  235.             fprintf(file, "\n\t");
  236.             comma = ' ';
  237.             i = 10;
  238.         }
  239.         fprintf(file, "%c %s", comma, *cp);
  240.         comma = ',';
  241.         }
  242.     }
  243.  
  244.     if (hp->servers != NULL) {
  245.         fprintf(file, "\nServed by:\n");
  246.         for (sp = hp->servers; *sp != NULL ; sp++) {
  247.  
  248.         fprintf(file, "- %s\n\t",  (*sp)->name);
  249.  
  250.         comma = ' ';
  251.         i = 0;
  252.         for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) {
  253.             i++;
  254.             if (i > 4) {
  255.             fprintf(file, "\n\t");
  256.             comma = ' ';
  257.             i = 0;
  258.             }
  259.             fprintf(file,
  260.             "%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
  261.             comma = ',';
  262.         }
  263.         fprintf(file, "\n\t");
  264.  
  265.         comma = ' ';
  266.         i = 10;
  267.         for (cp = (*sp)->domains; cp && *cp && **cp; cp++) {
  268.             i += strlen(*cp) + 2;
  269.             if (i > 75) {
  270.             fprintf(file, "\n\t");
  271.             comma = ' ';
  272.             i = 10;
  273.             }
  274.             fprintf(file, "%c %s", comma, *cp);
  275.             comma = ',';
  276.         }
  277.         fprintf(file, "\n");
  278.         }
  279.     }
  280.  
  281.     fprintf(file, "\n\n");
  282. }
  283.  
  284. /*
  285.  *******************************************************************************
  286.  *
  287.  *  OpenFile --
  288.  *
  289.  *    Parses a command string for a file name and opens
  290.  *    the file.
  291.  *
  292.  *  Results:
  293.  *    file pointer    - the open was successful.
  294.  *    NULL        - there was an error opening the file or
  295.  *              the input string was invalid.
  296.  *
  297.  *******************************************************************************
  298.  */
  299.  
  300. FILE *
  301. OpenFile(string, file)
  302.     char *string;
  303.     char *file;
  304. {
  305.     char    *redirect;
  306.     FILE    *tmpPtr;
  307.  
  308.     /*
  309.      *  Open an output file if we see '>' or >>'.
  310.      *  Check for overwrite (">") or concatenation (">>").
  311.      */
  312.  
  313.     redirect = strchr(string, '>');
  314.     if (redirect == NULL) {
  315.         return(NULL);
  316.     }
  317.     if (redirect[1] == '>') {
  318.         sscanf(redirect, ">> %s", file);
  319.         tmpPtr = fopen(file, "a+");
  320.     } else {
  321.         sscanf(redirect, "> %s", file);
  322.         tmpPtr = fopen(file, "w");
  323.     }
  324.  
  325.     if (tmpPtr != NULL) {
  326.         redirect[0] = '\0';
  327.     }
  328.  
  329.     return(tmpPtr);
  330. }
  331.  
  332. /*
  333.  *******************************************************************************
  334.  *
  335.  *  DecodeError --
  336.  *
  337.  *    Converts an error code into a character string.
  338.  *
  339.  *******************************************************************************
  340.  */
  341.  
  342. char *
  343. DecodeError(result)
  344.     int result;
  345. {
  346.     switch (result) {
  347.         case NOERROR:    return("Success"); break;
  348.         case FORMERR:    return("Format error"); break;
  349.         case SERVFAIL:    return("Server failed"); break;
  350.         case NXDOMAIN:    return("Non-existent domain"); break;
  351.         case NOTIMP:    return("Not implemented"); break;
  352.         case REFUSED:    return("Query refused"); break;
  353.         case NOCHANGE:    return("No change"); break;
  354.         case TIME_OUT:    return("Timed out"); break;
  355.         case NO_INFO:    return("No information"); break;
  356.         case ERROR:        return("Unspecified error"); break;
  357.         case NONAUTH:    return("Non-authoritative answer"); break;
  358.         case NO_RESPONSE:    return("No response from server"); break;
  359.         default:        break;
  360.     }
  361.     return("BAD ERROR VALUE");
  362. }
  363.  
  364.  
  365. int
  366. StringToClass(class, dflt)
  367.     char *class;
  368.     int dflt;
  369. {
  370.     if (strcasecmp(class, "IN") == 0)
  371.         return(C_IN);
  372.     if (strcasecmp(class, "HESIOD") == 0 ||
  373.         strcasecmp(class, "HS") == 0)
  374.         return(C_HS);
  375.     if (strcasecmp(class, "CHAOS") == 0)
  376.         return(C_CHAOS);
  377.     if (strcasecmp(class, "ANY") == 0)
  378.         return(C_ANY);
  379.     fprintf(stderr, "unknown query class: %s\n", class);
  380.     return(dflt);
  381. }
  382.  
  383.  
  384. /*
  385.  *******************************************************************************
  386.  *
  387.  *  StringToType --
  388.  *
  389.  *    Converts a string form of a query type name to its
  390.  *    corresponding integer value.
  391.  *
  392.  *******************************************************************************
  393.  */
  394.  
  395. int
  396. StringToType(type, dflt)
  397.     char *type;
  398.     int dflt;
  399. {
  400.     if (strcasecmp(type, "A") == 0)
  401.         return(T_A);
  402.     if (strcasecmp(type, "NS") == 0)
  403.         return(T_NS);            /* authoritative server */
  404.     if (strcasecmp(type, "MX") == 0)
  405.         return(T_MX);            /* mail exchanger */
  406.     if (strcasecmp(type, "CNAME") == 0)
  407.         return(T_CNAME);        /* canonical name */
  408.     if (strcasecmp(type, "SOA") == 0)
  409.         return(T_SOA);            /* start of authority zone */
  410.     if (strcasecmp(type, "MB") == 0)
  411.         return(T_MB);            /* mailbox domain name */
  412.     if (strcasecmp(type, "MG") == 0)
  413.         return(T_MG);            /* mail group member */
  414.     if (strcasecmp(type, "MR") == 0)
  415.         return(T_MR);            /* mail rename name */
  416.     if (strcasecmp(type, "WKS") == 0)
  417.         return(T_WKS);            /* well known service */
  418.     if (strcasecmp(type, "PTR") == 0)
  419.         return(T_PTR);            /* domain name pointer */
  420.     if (strcasecmp(type, "HINFO") == 0)
  421.         return(T_HINFO);        /* host information */
  422.     if (strcasecmp(type, "MINFO") == 0)
  423.         return(T_MINFO);        /* mailbox information */
  424.     if (strcasecmp(type, "AXFR") == 0)
  425.         return(T_AXFR);            /* zone transfer */
  426.     if (strcasecmp(type, "MAILA") == 0)
  427.         return(T_MAILA);        /* mail agent */
  428.     if (strcasecmp(type, "MAILB") == 0)
  429.         return(T_MAILB);        /* mail box */
  430.     if (strcasecmp(type, "ANY") == 0)
  431.         return(T_ANY);            /* matches any type */
  432.     if (strcasecmp(type, "UINFO") == 0)
  433.         return(T_UINFO);        /* user info */
  434.     if (strcasecmp(type, "UID") == 0)
  435.         return(T_UID);            /* user id */
  436.     if (strcasecmp(type, "GID") == 0)
  437.         return(T_GID);            /* group id */
  438.     if (strcasecmp(type, "TXT") == 0)
  439.         return(T_TXT);            /* text */
  440.     fprintf(stderr, "unknown query type: %s\n", type);
  441.     return(dflt);
  442. }
  443.  
  444. /*
  445.  *******************************************************************************
  446.  *
  447.  *  DecodeType --
  448.  *
  449.  *    Converts a query type to a descriptive name.
  450.  *    (A more verbose form of p_type.)
  451.  *
  452.  *
  453.  *******************************************************************************
  454.  */
  455.  
  456. static  char nbuf[20];
  457.  
  458. char *
  459. DecodeType(type)
  460.     int type;
  461. {
  462.     switch (type) {
  463.     case T_A:
  464.         return("address");
  465.     case T_NS:
  466.         return("name server");
  467.     case T_CNAME:
  468.         return("canonical name");
  469.     case T_SOA:
  470.         return("start of authority");
  471.     case T_MB:
  472.         return("mailbox");
  473.     case T_MG:
  474.         return("mail group member");
  475.     case T_MR:
  476.         return("mail rename");
  477.     case T_NULL:
  478.         return("null");
  479.     case T_WKS:
  480.         return("well-known service");
  481.     case T_PTR:
  482.         return("domain name pointer");
  483.     case T_HINFO:
  484.         return("host information");
  485.     case T_MINFO:
  486.         return("mailbox information");
  487.     case T_MX:
  488.         return("mail exchanger");
  489.     case T_TXT:
  490.         return("text");
  491.     case T_UINFO:
  492.         return("user information");
  493.     case T_UID:
  494.         return("user ID");
  495.     case T_GID:
  496.         return("group ID");
  497.     case T_AXFR:
  498.         return("zone transfer");
  499.     case T_MAILB:
  500.         return("mailbox-related data");
  501.     case T_MAILA:
  502.         return("mail agent");
  503.     case T_ANY:
  504.         return("\"any\"");
  505.     default:
  506.         (void) sprintf(nbuf, "%d", type);
  507.         return (nbuf);
  508.     }
  509. }
  510.