Annotation of 43BSDReno/usr.sbin/named/tools/nslookup/main.c, revision 1.1

1.1     ! root        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 are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: char copyright[] =
        !            22: "@(#) Copyright (c) 1985,1989 Regents of the University of California.\n\
        !            23:  All rights reserved.\n";
        !            24: #endif /* not lint */
        !            25: 
        !            26: #ifndef lint
        !            27: static char sccsid[] = "@(#)main.c     5.39 (Berkeley) 6/24/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: /*
        !            31:  *******************************************************************************
        !            32:  *  
        !            33:  *   main.c --
        !            34:  *  
        !            35:  *     Main routine and some action routines for the name server
        !            36:  *     lookup program.
        !            37:  *
        !            38:  *     Andrew Cherenson
        !            39:  *     U.C. Berkeley Computer Science Div.
        !            40:  *     CS298-26, Fall 1985
        !            41:  *  
        !            42:  *******************************************************************************
        !            43:  */
        !            44: 
        !            45: #include <sys/param.h>
        !            46: #include <netdb.h>
        !            47: #include <sys/socket.h>
        !            48: #include <netinet/in.h>
        !            49: #include <arpa/nameser.h>
        !            50: #include <arpa/inet.h>
        !            51: #include <resolv.h>
        !            52: #include <signal.h>
        !            53: #include <setjmp.h>
        !            54: #include <ctype.h>
        !            55: #include <stdio.h>
        !            56: #include <stdlib.h>
        !            57: #include <string.h>
        !            58: #include "res.h"
        !            59: #include "pathnames.h"
        !            60: 
        !            61: /*
        !            62:  *  Default Internet address of the current host.
        !            63:  */
        !            64: 
        !            65: #if BSD < 43
        !            66: #define LOCALHOST "127.0.0.1"
        !            67: #endif
        !            68: 
        !            69: 
        !            70: /*
        !            71:  * Name of a top-level name server. Can be changed with 
        !            72:  * the "set root" command.
        !            73:  */
        !            74: 
        !            75: #ifndef ROOT_SERVER
        !            76: #define                ROOT_SERVER "ns.nic.ddn.mil."
        !            77: #endif
        !            78: char           rootServerName[NAME_LEN] = ROOT_SERVER;
        !            79: 
        !            80: 
        !            81: /*
        !            82:  *  Import the state information from the resolver library.
        !            83:  */
        !            84: 
        !            85: extern struct state _res;
        !            86: 
        !            87: 
        !            88: /*
        !            89:  *  Info about the most recently queried host.
        !            90:  */
        !            91: 
        !            92: HostInfo       curHostInfo;
        !            93: int            curHostValid = FALSE;
        !            94: 
        !            95: 
        !            96: /*
        !            97:  *  Info about the default name server.
        !            98:  */
        !            99: 
        !           100: HostInfo       *defaultPtr = NULL;
        !           101: char           defaultServer[NAME_LEN];
        !           102: struct in_addr defaultAddr;
        !           103: 
        !           104: 
        !           105: /*
        !           106:  *  Initial name server query type is Address.
        !           107:  */
        !           108: 
        !           109: int            queryType = T_A;
        !           110: int            queryClass = C_IN;
        !           111: 
        !           112: /*
        !           113:  * Stuff for Interrupt (control-C) signal handler.
        !           114:  */
        !           115: 
        !           116: #ifdef SVR3
        !           117: extern void    IntrHandler();
        !           118: #else
        !           119: extern int     IntrHandler();
        !           120: #endif
        !           121: FILE           *filePtr;
        !           122: jmp_buf                env;
        !           123: 
        !           124: static void CvtAddrToPtr();
        !           125: static void ReadRC();
        !           126: 
        !           127: 
        !           128: /*
        !           129:  *******************************************************************************
        !           130:  *
        !           131:  *  main --
        !           132:  *
        !           133:  *     Initializes the resolver library and determines the address
        !           134:  *     of the initial name server. The yylex routine is used to
        !           135:  *     read and perform commands.
        !           136:  *
        !           137:  *******************************************************************************
        !           138:  */
        !           139: 
        !           140: main(argc, argv)
        !           141:     int                argc;
        !           142:     char       **argv;
        !           143: {
        !           144:     char       *wantedHost = NULL;
        !           145:     Boolean    useLocalServer;
        !           146:     int                result;
        !           147:     int                i;
        !           148:     struct hostent     *hp;
        !           149:     extern int h_errno;
        !           150: 
        !           151:     /*
        !           152:      *  Initialize the resolver library routines.
        !           153:      */
        !           154: 
        !           155:     if (res_init() == -1) {
        !           156:        fprintf(stderr,"*** Can't initialize resolver.\n");
        !           157:        exit(1);
        !           158:     }
        !           159: 
        !           160:     /*
        !           161:      *  Allocate space for the default server's host info and
        !           162:      *  find the server's address and name. If the resolver library
        !           163:      *  already has some addresses for a potential name server,
        !           164:      *  then use them. Otherwise, see if the current host has a server.
        !           165:      *  Command line arguments may override the choice of initial server. 
        !           166:      */
        !           167: 
        !           168:     defaultPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
        !           169: 
        !           170:     /*
        !           171:      * Parse the arguments:
        !           172:      *  no args =  go into interactive mode, use default host as server
        !           173:      * 1 arg   =  use as host name to be looked up, default host will be server
        !           174:      *            non-interactive mode
        !           175:      *  2 args =  1st arg: 
        !           176:      *              if it is '-', then 
        !           177:      *                 ignore but go into interactive mode
        !           178:      *              else 
        !           179:      *                  use as host name to be looked up, 
        !           180:      *                  go into non-interactive mode
        !           181:      *         2nd arg: name or inet address of server
        !           182:      *
        !           183:      * "Set" options are specified with a leading - and must come before
        !           184:      * any arguments. For example, to find the well-known services for
        !           185:      *  a host, type "nslookup -query=wks host"
        !           186:      */
        !           187: 
        !           188:     ReadRC();                  /* look for options file */
        !           189: 
        !           190:     ++argv; --argc;            /* skip prog name */
        !           191: 
        !           192:     while (argc && *argv[0] == '-' && argv[0][1]) {
        !           193:        (void) SetOption (&(argv[0][1]));
        !           194:        ++argv; --argc;
        !           195:     }
        !           196:     if (argc > 2) {
        !           197:        Usage();
        !           198:     } 
        !           199:     if (argc && *argv[0] != '-') {
        !           200:        wantedHost = *argv;     /* name of host to be looked up */
        !           201:     }
        !           202: 
        !           203:     useLocalServer = FALSE;
        !           204:     if (argc == 2) {
        !           205:        struct in_addr addr;
        !           206: 
        !           207:        /*
        !           208:         * Use an explicit name server. If the hostname lookup fails,
        !           209:         * default to the server(s) in resolv.conf.
        !           210:         */ 
        !           211: 
        !           212:        addr.s_addr = inet_addr(*++argv);
        !           213:        if (addr.s_addr != (unsigned long)-1) {
        !           214:            _res.nscount = 1;
        !           215:            _res.nsaddr.sin_addr = addr;
        !           216:        } else {
        !           217:            hp = gethostbyname(*argv);
        !           218:            if (hp == NULL) {
        !           219:                fprintf(stderr, "*** Can't find server address for '%s': ", 
        !           220:                        *argv);
        !           221:                herror((char *)NULL);
        !           222:                fputc('\n', stderr);
        !           223:            } else {
        !           224: #if BSD < 43
        !           225:                bcopy(hp->h_addr, (char *)&_res.nsaddr.sin_addr, hp->h_length);
        !           226:                _res.nscount = 1;
        !           227: #else
        !           228:                for (i = 0; i < MAXNS && hp->h_addr_list[i] != NULL; i++) {
        !           229:                    bcopy(hp->h_addr_list[i], 
        !           230:                            (char *)&_res.nsaddr_list[i].sin_addr, 
        !           231:                            hp->h_length);
        !           232:                }
        !           233:                _res.nscount = i;
        !           234: #endif
        !           235:            } 
        !           236:        }
        !           237:     }
        !           238: 
        !           239: 
        !           240:     if (_res.nscount == 0 || useLocalServer) {
        !           241:        LocalServer(defaultPtr);
        !           242:     } else {
        !           243:        for (i = 0; i < _res.nscount; i++) {
        !           244:            if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) {
        !           245:                LocalServer(defaultPtr);
        !           246:                break;
        !           247:            } else {
        !           248:                result = GetHostInfoByAddr(&(_res.nsaddr_list[i].sin_addr), 
        !           249:                                    &(_res.nsaddr_list[i].sin_addr), 
        !           250:                                    defaultPtr);
        !           251:                if (result != SUCCESS) {
        !           252:                    fprintf(stderr,
        !           253:                    "*** Can't find server name for address %s: %s\n", 
        !           254:                       inet_ntoa(_res.nsaddr_list[i].sin_addr), 
        !           255:                       DecodeError(result));
        !           256:                } else {
        !           257:                    defaultAddr = _res.nsaddr_list[i].sin_addr;
        !           258:                    break;
        !           259:                }
        !           260:            }
        !           261:        }
        !           262: 
        !           263:        /*
        !           264:         *  If we have exhausted the list, tell the user about the
        !           265:         *  command line argument to specify an address.
        !           266:         */
        !           267: 
        !           268:        if (i == _res.nscount) {
        !           269:            fprintf(stderr, "*** Default servers are not available\n");
        !           270:            exit(1);
        !           271:        }
        !           272: 
        !           273:     }
        !           274:     strcpy(defaultServer, defaultPtr->name);
        !           275: 
        !           276: 
        !           277: #ifdef DEBUG
        !           278: #ifdef DEBUG2
        !           279:     _res.options |= RES_DEBUG2;
        !           280: #endif
        !           281:     _res.options |= RES_DEBUG;
        !           282:     _res.retry    = 2;
        !           283: #endif DEBUG
        !           284: 
        !           285:     /*
        !           286:      * If we're in non-interactive mode, look up the wanted host and quit.
        !           287:      * Otherwise, print the initial server's name and continue with
        !           288:      * the initialization.
        !           289:      */
        !           290: 
        !           291:     if (wantedHost != (char *) NULL) {
        !           292:        LookupHost(wantedHost, 0);
        !           293:     } else {
        !           294:        PrintHostInfo(stdout, "Default Server:", defaultPtr);
        !           295: 
        !           296:        /*
        !           297:         * Setup the environment to allow the interrupt handler to return here.
        !           298:         */
        !           299: 
        !           300:        (void) setjmp(env);
        !           301: 
        !           302:        /* 
        !           303:         * Return here after a longjmp.
        !           304:         */
        !           305: 
        !           306:        signal(SIGINT, IntrHandler);
        !           307:        signal(SIGPIPE, SIG_IGN);
        !           308: 
        !           309:        /*
        !           310:         * Read and evaluate commands. The commands are described in commands.l
        !           311:         * Yylex returns 0 when ^D or 'exit' is typed. 
        !           312:         */
        !           313: 
        !           314:        printf("> ");
        !           315:        fflush(stdout);
        !           316:        while(yylex()) {
        !           317:            printf("> ");
        !           318:            fflush(stdout);
        !           319:        }
        !           320:     }
        !           321:     exit(0);
        !           322: }
        !           323: 
        !           324: 
        !           325: LocalServer(defaultPtr)
        !           326:     HostInfo *defaultPtr;
        !           327: {
        !           328:     char       hostName[NAME_LEN];
        !           329: #if BSD < 43
        !           330:     int                result;
        !           331: #endif
        !           332: 
        !           333:     gethostname(hostName, sizeof(hostName));
        !           334: 
        !           335: #if BSD < 43
        !           336:     defaultAddr.s_addr = inet_addr(LOCALHOST);
        !           337:     result = GetHostInfoByName(&defaultAddr, C_IN, T_A, 
        !           338:                hostName, defaultPtr, 1);
        !           339:     if (result != SUCCESS) {
        !           340:        fprintf(stderr,
        !           341:        "*** Can't find initialize address for server %s: %s\n",
        !           342:                        defaultServer, DecodeError(result));
        !           343:        exit(1);
        !           344:     }
        !           345: #else
        !           346:     defaultAddr.s_addr = htonl(INADDR_ANY);
        !           347:     (void) GetHostInfoByName(&defaultAddr, C_IN, T_A, "0.0.0.0", defaultPtr, 1);
        !           348:     free(defaultPtr->name);
        !           349:     defaultPtr->name = Calloc(1, sizeof(hostName)+1);
        !           350:     strcpy(defaultPtr->name, hostName);
        !           351: #endif
        !           352: }
        !           353: 
        !           354: 
        !           355: /*
        !           356:  *******************************************************************************
        !           357:  *
        !           358:  *  Usage --
        !           359:  *
        !           360:  *     Lists the proper methods to run the program and exits.
        !           361:  *
        !           362:  *******************************************************************************
        !           363:  */
        !           364: 
        !           365: Usage()
        !           366: {
        !           367:     fprintf(stderr, "Usage:\n");
        !           368:     fprintf(stderr,
        !           369: "   nslookup [-opt ...]             # interactive mode using default server\n");
        !           370:     fprintf(stderr,
        !           371: "   nslookup [-opt ...] - server    # interactive mode using 'server'\n");
        !           372:     fprintf(stderr,
        !           373: "   nslookup [-opt ...] host        # just look up 'host' using default server\n");
        !           374:     fprintf(stderr,
        !           375: "   nslookup [-opt ...] host server # just look up 'host' using 'server'\n");
        !           376:     exit(1);
        !           377: }
        !           378: 
        !           379: /*
        !           380:  *******************************************************************************
        !           381:  *
        !           382:  * IsAddr --
        !           383:  *
        !           384:  *     Returns TRUE if the string looks like an Internet address.
        !           385:  *     A string with a trailing dot is not an address, even if it looks
        !           386:  *     like one.
        !           387:  *
        !           388:  *     XXX doesn't treat 255.255.255.255 as an address.
        !           389:  *
        !           390:  *******************************************************************************
        !           391:  */
        !           392: 
        !           393: Boolean
        !           394: IsAddr(host, addrPtr)
        !           395:     char *host;
        !           396:     unsigned long *addrPtr;    /* If return TRUE, contains IP address */
        !           397: {
        !           398:     register char *cp;
        !           399:     unsigned long addr;
        !           400: 
        !           401:     if (isdigit(host[0])) {
        !           402:            /* Make sure it has only digits and dots. */
        !           403:            for (cp = host; *cp; ++cp) {
        !           404:                if (!isdigit(*cp) && *cp != '.') 
        !           405:                    return FALSE;
        !           406:            }
        !           407:            /* If it has a trailing dot, don't treat it as an address. */
        !           408:            if (*--cp != '.') { 
        !           409:                if ((addr = inet_addr(host)) != (unsigned long) -1) {
        !           410:                    *addrPtr = addr;
        !           411:                    return TRUE;
        !           412: #if 0
        !           413:                } else {
        !           414:                    /* XXX Check for 255.255.255.255 case */
        !           415: #endif
        !           416:                }
        !           417:            }
        !           418:     }
        !           419:     return FALSE;
        !           420: }
        !           421: 
        !           422: 
        !           423: /*
        !           424:  *******************************************************************************
        !           425:  *
        !           426:  *  SetDefaultServer --
        !           427:  *
        !           428:  *     Changes the default name server to the one specified by
        !           429:  *     the first argument. The command "server name" uses the current 
        !           430:  *     default server to lookup the info for "name". The command
        !           431:  *     "lserver name" uses the original server to lookup "name".
        !           432:  *
        !           433:  *  Side effects:
        !           434:  *     This routine will cause a core dump if the allocation requests fail.
        !           435:  *
        !           436:  *  Results:
        !           437:  *     SUCCESS         The default server was changed successfully.
        !           438:  *     NONAUTH         The server was changed but addresses of
        !           439:  *                     other servers who know about the requested server
        !           440:  *                     were returned.
        !           441:  *     Errors          No info about the new server was found or
        !           442:  *                     requests to the current server timed-out.
        !           443:  *
        !           444:  *******************************************************************************
        !           445:  */
        !           446: 
        !           447: int
        !           448: SetDefaultServer(string, local)
        !           449:     char       *string;
        !           450:     Boolean    local;
        !           451: {
        !           452:     register HostInfo  *newDefPtr;
        !           453:     struct in_addr     *servAddrPtr;
        !           454:     struct in_addr     addr;
        !           455:     char               newServer[NAME_LEN];
        !           456:     int                        result;
        !           457:     int                        i;
        !           458: 
        !           459:     /*
        !           460:      *  Parse the command line. It maybe of the form "server name",
        !           461:      *  "lserver name" or just "name".
        !           462:      */
        !           463: 
        !           464:     if (local) {
        !           465:        i = sscanf(string, " lserver %s", newServer);
        !           466:     } else {
        !           467:        i = sscanf(string, " server %s", newServer);
        !           468:     }
        !           469:     if (i != 1) {
        !           470:        i = sscanf(string, " %s", newServer);
        !           471:        if (i != 1) {
        !           472:            fprintf(stderr,"SetDefaultServer: invalid name: %s\n",  string);
        !           473:            return(ERROR);
        !           474:        }
        !           475:     }
        !           476: 
        !           477:     /*
        !           478:      * Allocate space for a HostInfo variable for the new server. Don't
        !           479:      * overwrite the old HostInfo struct because info about the new server
        !           480:      * might not be found and we need to have valid default server info.
        !           481:      */
        !           482: 
        !           483:     newDefPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
        !           484: 
        !           485: 
        !           486:     /*
        !           487:      * A 'local' lookup uses the original server that the program was
        !           488:      *  initialized with.
        !           489:      *
        !           490:      *  Check to see if we have the address of the server or the
        !           491:      *  address of a server who knows about this domain.
        !           492:      *  XXX For now, just use the first address in the list.
        !           493:      */
        !           494: 
        !           495:     if (local) {
        !           496:        servAddrPtr = &defaultAddr;
        !           497:     } else if (defaultPtr->addrList != NULL) {
        !           498:        servAddrPtr = (struct in_addr *) defaultPtr->addrList[0];
        !           499:     } else {
        !           500:        servAddrPtr = (struct in_addr *) defaultPtr->servers[0]->addrList[0];
        !           501:     }
        !           502: 
        !           503:     result = ERROR;
        !           504:     if (IsAddr(newServer, &addr.s_addr)) {
        !           505:        result = GetHostInfoByAddr(servAddrPtr, &addr, newDefPtr);
        !           506:        /* If we can't get the name, fall through... */
        !           507:     } 
        !           508:     if (result != SUCCESS && result != NONAUTH) {
        !           509:        result = GetHostInfoByName(servAddrPtr, C_IN, T_A, 
        !           510:                        newServer, newDefPtr, 1);
        !           511:     }
        !           512: 
        !           513:     if (result == SUCCESS || result == NONAUTH) {
        !           514:            /*
        !           515:             *  Found info about the new server. Free the resources for
        !           516:             *  the old server.
        !           517:             */
        !           518: 
        !           519:            FreeHostInfoPtr(defaultPtr);
        !           520:            free((char *)defaultPtr);
        !           521:            defaultPtr = newDefPtr;
        !           522:            strcpy(defaultServer, defaultPtr->name);
        !           523:            PrintHostInfo(stdout, "Default Server:", defaultPtr);
        !           524:            return(SUCCESS);
        !           525:     } else {
        !           526:            fprintf(stderr, "*** Can't find address for server %s: %s\n",
        !           527:                    newServer, DecodeError(result));
        !           528:            free((char *)newDefPtr);
        !           529: 
        !           530:            return(result);
        !           531:     }
        !           532: }
        !           533: 
        !           534: /*
        !           535:  *******************************************************************************
        !           536:  *
        !           537:  * DoLoookup --
        !           538:  *
        !           539:  *     Common subroutine for LookupHost and LookupHostWithServer.
        !           540:  *
        !           541:  *  Results:
        !           542:  *     SUCCESS         - the lookup was successful.
        !           543:  *     Misc. Errors    - an error message is printed if the lookup failed.
        !           544:  *
        !           545:  *******************************************************************************
        !           546:  */
        !           547: 
        !           548: static int
        !           549: DoLookup(host, servPtr, serverName)
        !           550:     char       *host;
        !           551:     HostInfo   *servPtr;
        !           552:     char       *serverName;
        !           553: {
        !           554:     int result;
        !           555:     struct in_addr *servAddrPtr;
        !           556:     struct in_addr addr; 
        !           557: 
        !           558:     /* Skip escape character */
        !           559:     if (host[0] == '\\')
        !           560:        host++;
        !           561: 
        !           562:     /*
        !           563:      *  If the user gives us an address for an address query, 
        !           564:      *  silently treat it as a PTR query. If the query type is already
        !           565:      *  PTR, then convert the address into the in-addr.arpa format.
        !           566:      *
        !           567:      *  Use the address of the server if it exists, otherwise use the
        !           568:      * address of a server who knows about this domain.
        !           569:      *  XXX For now, just use the first address in the list.
        !           570:      */
        !           571: 
        !           572:     if (servPtr->addrList != NULL) {
        !           573:        servAddrPtr = (struct in_addr *) servPtr->addrList[0];
        !           574:     } else {
        !           575:        servAddrPtr = (struct in_addr *) servPtr->servers[0]->addrList[0];
        !           576:     }
        !           577: 
        !           578:     /* 
        !           579:      * RFC1123 says we "SHOULD check the string syntactically for a 
        !           580:      * dotted-decimal number before looking it up [...]" (p. 13).
        !           581:      */
        !           582:     if (queryType == T_A && IsAddr(host, &addr.s_addr)) {
        !           583:        result = GetHostInfoByAddr(servAddrPtr, &addr, &curHostInfo);
        !           584:     } else {
        !           585:        if (queryType == T_PTR) {
        !           586:            CvtAddrToPtr(host);
        !           587:        } 
        !           588:        result = GetHostInfoByName(servAddrPtr, queryClass, queryType, host, 
        !           589:                        &curHostInfo, 0);
        !           590:     }
        !           591: 
        !           592:     switch (result) {
        !           593:        case SUCCESS:
        !           594:            /*
        !           595:             *  If the query was for an address, then the &curHostInfo
        !           596:             *  variable can be used by Finger.
        !           597:             *  There's no need to print anything for other query types
        !           598:             *  because the info has already been printed.
        !           599:             */
        !           600:            if (queryType == T_A) {
        !           601:                curHostValid = TRUE;
        !           602:                PrintHostInfo(filePtr, "Name:", &curHostInfo);
        !           603:            }
        !           604:            break;
        !           605: 
        !           606:        /*
        !           607:         * No Authoritative answer was available but we got names
        !           608:         * of servers who know about the host.
        !           609:         */
        !           610:        case NONAUTH:
        !           611:            PrintHostInfo(filePtr, "Name:", &curHostInfo);
        !           612:            break;
        !           613: 
        !           614:        case NO_INFO:
        !           615:            fprintf(stderr, "*** No %s (%s) records available for %s\n", 
        !           616:                        DecodeType(queryType), p_type(queryType), host);
        !           617:            break;
        !           618: 
        !           619:        case TIME_OUT:
        !           620:            fprintf(stderr, "*** Request to %s timed-out\n", serverName);
        !           621:            break;
        !           622: 
        !           623:        default:
        !           624:            fprintf(stderr, "*** %s can't find %s: %s\n", serverName, host,
        !           625:                    DecodeError(result));
        !           626:     }
        !           627:     return result;
        !           628: }
        !           629: 
        !           630: /*
        !           631:  *******************************************************************************
        !           632:  *
        !           633:  *  LookupHost --
        !           634:  *
        !           635:  *     Asks the default name server for information about the
        !           636:  *     specified host or domain. The information is printed
        !           637:  *     if the lookup was successful.
        !           638:  *
        !           639:  *  Results:
        !           640:  *     ERROR           - the output file could not be opened.
        !           641:  *     + results of DoLookup
        !           642:  *
        !           643:  *******************************************************************************
        !           644:  */
        !           645: 
        !           646: int
        !           647: LookupHost(string, putToFile)
        !           648:     char       *string;
        !           649:     Boolean    putToFile;
        !           650: {
        !           651:     char       host[NAME_LEN];
        !           652:     char       file[NAME_LEN];
        !           653:     int                result;
        !           654: 
        !           655:     /*
        !           656:      *  Invalidate the current host information to prevent Finger 
        !           657:      *  from using bogus info.
        !           658:      */
        !           659: 
        !           660:     curHostValid = FALSE;
        !           661: 
        !           662:     /*
        !           663:      *  Parse the command string into the host and
        !           664:      *  optional output file name.
        !           665:      *
        !           666:      */
        !           667: 
        !           668:     sscanf(string, " %s", host);       /* removes white space */
        !           669:     if (!putToFile) {
        !           670:        filePtr = stdout;
        !           671:     } else {
        !           672:        filePtr = OpenFile(string, file);
        !           673:        if (filePtr == NULL) {
        !           674:            fprintf(stderr, "*** Can't open %s for writing\n", file);
        !           675:            return(ERROR);
        !           676:        }
        !           677:        fprintf(filePtr,"> %s\n", string);
        !           678:     }
        !           679: 
        !           680:     PrintHostInfo(filePtr, "Server:", defaultPtr);
        !           681: 
        !           682:     result = DoLookup(host, defaultPtr, defaultServer);
        !           683: 
        !           684:     if (putToFile) {
        !           685:        fclose(filePtr);
        !           686:        filePtr = NULL;
        !           687:     }
        !           688:     return(result);
        !           689: }
        !           690: 
        !           691: /*
        !           692:  *******************************************************************************
        !           693:  *
        !           694:  *  LookupHostWithServer --
        !           695:  *
        !           696:  *     Asks the name server specified in the second argument for 
        !           697:  *     information about the host or domain specified in the first
        !           698:  *     argument. The information is printed if the lookup was successful.
        !           699:  *
        !           700:  *     Address info about the requested name server is obtained
        !           701:  *     from the default name server. This routine will return an
        !           702:  *     error if the default server doesn't have info about the 
        !           703:  *     requested server. Thus an error return status might not
        !           704:  *     mean the requested name server doesn't have info about the
        !           705:  *     requested host.
        !           706:  *
        !           707:  *     Comments from LookupHost apply here, too.
        !           708:  *
        !           709:  *  Results:
        !           710:  *     ERROR           - the output file could not be opened.
        !           711:  *     + results of DoLookup
        !           712:  *
        !           713:  *******************************************************************************
        !           714:  */
        !           715: 
        !           716: int
        !           717: LookupHostWithServer(string, putToFile)
        !           718:     char       *string;
        !           719:     Boolean    putToFile;
        !           720: {
        !           721:     char       file[NAME_LEN];
        !           722:     char       host[NAME_LEN];
        !           723:     char       server[NAME_LEN];
        !           724:     int                result;
        !           725:     static HostInfo serverInfo;
        !           726: 
        !           727:     curHostValid = FALSE;
        !           728: 
        !           729:     sscanf(string, " %s %s", host, server);
        !           730:     if (!putToFile) {
        !           731:        filePtr = stdout;
        !           732:     } else {
        !           733:        filePtr = OpenFile(string, file);
        !           734:        if (filePtr == NULL) {
        !           735:            fprintf(stderr, "*** Can't open %s for writing\n", file);
        !           736:            return(ERROR);
        !           737:        }
        !           738:        fprintf(filePtr,"> %s\n", string);
        !           739:     }
        !           740:     
        !           741:     result = GetHostInfoByName(
        !           742:                defaultPtr->addrList ?
        !           743:                    (struct in_addr *) defaultPtr->addrList[0] :
        !           744:                    (struct in_addr *) defaultPtr->servers[0]->addrList[0], 
        !           745:                C_IN, T_A, server, &serverInfo, 1);
        !           746: 
        !           747:     if (result != SUCCESS) {
        !           748:        fprintf(stderr,"*** Can't find address for server %s: %s\n", server,
        !           749:                 DecodeError(result));
        !           750:     } else {
        !           751:        PrintHostInfo(filePtr, "Server:", &serverInfo);
        !           752: 
        !           753:        result = DoLookup(host, &serverInfo, server);
        !           754:     }
        !           755:     if (putToFile) {
        !           756:        fclose(filePtr);
        !           757:        filePtr = NULL;
        !           758:     }
        !           759:     return(result);
        !           760: }
        !           761: 
        !           762: /*
        !           763:  *******************************************************************************
        !           764:  *
        !           765:  *  SetOption -- 
        !           766:  *
        !           767:  *     This routine is used to change the state information
        !           768:  *     that affect the lookups. The command format is
        !           769:  *        set keyword[=value]
        !           770:  *     Most keywords can be abbreviated. Parsing is very simplistic--
        !           771:  *     A value must not be separated from its keyword by white space.
        !           772:  *
        !           773:  *     Valid keywords:         Meaning:
        !           774:  *     all                     lists current values of options.
        !           775:  *     ALL                     lists current values of options, including
        !           776:  *                               hidden options.
        !           777:  *     [no]d2                  turn on/off extra debugging mode.
        !           778:  *     [no]debug               turn on/off debugging mode.
        !           779:  *     [no]defname             use/don't use default domain name.
        !           780:  *     [no]search              use/don't use domain search list.
        !           781:  *     domain=NAME             set default domain name to NAME.
        !           782:  *     [no]ignore              ignore/don't ignore trunc. errors.
        !           783:  *     query=value             set default query type to value,
        !           784:  *                             value is one of the query types in RFC883
        !           785:  *                             without the leading T_. (e.g., A, HINFO)
        !           786:  *     [no]recurse             use/don't use recursive lookup.
        !           787:  *     retry=#                 set number of retries to #.
        !           788:  *     root=NAME               change root server to NAME.
        !           789:  *     time=#                  set timeout length to #.
        !           790:  *     [no]vc                  use/don't use virtual circuit.
        !           791:  *     port                    TCP/UDP port to server.
        !           792:  *
        !           793:  *     Deprecated:
        !           794:  *     [no]primary             use/don't use primary server.
        !           795:  *
        !           796:  *  Results:
        !           797:  *     SUCCESS         the command was parsed correctly.
        !           798:  *     ERROR           the command was not parsed correctly.
        !           799:  *
        !           800:  *******************************************************************************
        !           801:  */
        !           802: 
        !           803: int
        !           804: SetOption(option)
        !           805:     register char *option;
        !           806: {
        !           807:     char       type[NAME_LEN];
        !           808:     char       *ptr;
        !           809:     int                tmp;
        !           810: 
        !           811:     while (isspace(*option))
        !           812:        ++option;
        !           813:     if (strncmp (option, "set ", 4) == 0)
        !           814:        option += 4;
        !           815:     while (isspace(*option))
        !           816:        ++option;
        !           817: 
        !           818:     if (*option == 0) {
        !           819:        fprintf(stderr, "*** Invalid set command\n");
        !           820:        return(ERROR);
        !           821:     } else {
        !           822:        if (strncmp(option, "all", 3) == 0) {
        !           823:            ShowOptions();
        !           824:        } else if (strncmp(option, "ALL", 3) == 0) {
        !           825:            ShowOptions();
        !           826:        } else if (strncmp(option, "d2", 2) == 0) {     /* d2 (more debug) */
        !           827:            _res.options |= (RES_DEBUG | RES_DEBUG2);
        !           828:        } else if (strncmp(option, "nod2", 4) == 0) {
        !           829:            _res.options &= ~RES_DEBUG2;
        !           830:            printf("d2 mode disabled; still in debug mode\n");
        !           831:        } else if (strncmp(option, "def", 3) == 0) {    /* defname */
        !           832:            _res.options |= RES_DEFNAMES;
        !           833:        } else if (strncmp(option, "nodef", 5) == 0) {
        !           834:            _res.options &= ~RES_DEFNAMES;
        !           835:        } else if (strncmp(option, "do", 2) == 0) {     /* domain */
        !           836:            ptr = strchr(option, '=');
        !           837:            if (ptr != NULL) {
        !           838:                sscanf(++ptr, "%s", _res.defdname);
        !           839:                res_re_init();
        !           840:            }
        !           841:        } else if (strncmp(option, "deb", 1) == 0) {    /* debug */
        !           842:            _res.options |= RES_DEBUG;
        !           843:        } else if (strncmp(option, "nodeb", 5) == 0) {
        !           844:            _res.options &= ~(RES_DEBUG | RES_DEBUG2);
        !           845:        } else if (strncmp(option, "ig", 2) == 0) {     /* ignore */
        !           846:            _res.options |= RES_IGNTC;
        !           847:        } else if (strncmp(option, "noig", 4) == 0) {
        !           848:            _res.options &= ~RES_IGNTC;
        !           849:        } else if (strncmp(option, "po", 2) == 0) {     /* port */
        !           850:            ptr = strchr(option, '=');
        !           851:            if (ptr != NULL) {
        !           852:                sscanf(++ptr, "%hu", &nsport);
        !           853:            }
        !           854: #ifdef deprecated
        !           855:        } else if (strncmp(option, "pri", 3) == 0) {    /* primary */
        !           856:            _res.options |= RES_PRIMARY;
        !           857:        } else if (strncmp(option, "nopri", 5) == 0) {
        !           858:            _res.options &= ~RES_PRIMARY;
        !           859: #endif
        !           860:        } else if (strncmp(option, "q", 1) == 0 ||      /* querytype */
        !           861:          strncmp(option, "ty", 2) == 0) {              /* type */
        !           862:            ptr = strchr(option, '=');
        !           863:            if (ptr != NULL) {
        !           864:                sscanf(++ptr, "%s", type);
        !           865:                queryType = StringToType(type, queryType);
        !           866:            }
        !           867:        } else if (strncmp(option, "cl", 2) == 0) {     /* query class */
        !           868:            ptr = strchr(option, '=');
        !           869:            if (ptr != NULL) {
        !           870:                sscanf(++ptr, "%s", type);
        !           871:                queryClass = StringToClass(type, queryClass);
        !           872:            }
        !           873:        } else if (strncmp(option, "rec", 3) == 0) {    /* recurse */
        !           874:            _res.options |= RES_RECURSE;
        !           875:        } else if (strncmp(option, "norec", 5) == 0) {
        !           876:            _res.options &= ~RES_RECURSE;
        !           877:        } else if (strncmp(option, "ret", 3) == 0) {    /* retry */
        !           878:            ptr = strchr(option, '=');
        !           879:            if (ptr != NULL) {
        !           880:                sscanf(++ptr, "%d", &tmp);
        !           881:                if (tmp >= 0) {
        !           882:                    _res.retry = tmp;
        !           883:                }
        !           884:            }
        !           885:        } else if (strncmp(option, "ro", 2) == 0) {     /* root */
        !           886:            ptr = strchr(option, '=');
        !           887:            if (ptr != NULL) {
        !           888:                sscanf(++ptr, "%s", rootServerName);
        !           889:            }
        !           890:        } else if (strncmp(option, "sea", 3) == 0) {    /* search list */
        !           891:            _res.options |= RES_DNSRCH;
        !           892:        } else if (strncmp(option, "nosea", 5) == 0) {
        !           893:            _res.options &= ~RES_DNSRCH;
        !           894:        } else if (strncmp(option, "srchl", 5) == 0) {  /* domain search list */
        !           895:            ptr = strchr(option, '=');
        !           896:            if (ptr != NULL) {
        !           897:                res_dnsrch(++ptr);
        !           898:            }
        !           899:        } else if (strncmp(option, "ti", 2) == 0) {     /* timeout */
        !           900:            ptr = strchr(option, '=');
        !           901:            if (ptr != NULL) {
        !           902:                sscanf(++ptr, "%d", &tmp);
        !           903:                if (tmp >= 0) {
        !           904:                    _res.retrans = tmp;
        !           905:                }
        !           906:            }
        !           907:        } else if (strncmp(option, "v", 1) == 0) {      /* vc */
        !           908:            _res.options |= RES_USEVC;
        !           909:        } else if (strncmp(option, "nov", 3) == 0) {
        !           910:            _res.options &= ~RES_USEVC;
        !           911:        } else {
        !           912:            fprintf(stderr, "*** Invalid option: %s\n",  option);
        !           913:            return(ERROR);
        !           914:        }
        !           915:     }
        !           916:     return(SUCCESS);
        !           917: }
        !           918: 
        !           919: /*
        !           920:  * Fake a reinitialization when the domain is changed.
        !           921:  */
        !           922: res_re_init()
        !           923: {
        !           924:     register char *cp, **pp;
        !           925:     int n;
        !           926: 
        !           927:     /* find components of local domain that might be searched */
        !           928:     pp = _res.dnsrch;
        !           929:     *pp++ = _res.defdname;
        !           930:     for (cp = _res.defdname, n = 0; *cp; cp++)
        !           931:        if (*cp == '.')
        !           932:            n++;
        !           933:     cp = _res.defdname;
        !           934:     for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; n--) {
        !           935:        cp = strchr(cp, '.');
        !           936:        *pp++ = ++cp;
        !           937:     }
        !           938:     *pp = 0;
        !           939:     _res.options |= RES_INIT;
        !           940: }
        !           941: 
        !           942: #define SRCHLIST_SEP '/'
        !           943: 
        !           944: res_dnsrch(cp)
        !           945:     register char *cp;
        !           946: {
        !           947:     register char **pp;
        !           948:     int n;
        !           949: 
        !           950:     (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
        !           951:     if ((cp = strchr(_res.defdname, '\n')) != NULL)
        !           952:            *cp = '\0';
        !           953:     /*
        !           954:      * Set search list to be blank-separated strings
        !           955:      * on rest of line.
        !           956:      */
        !           957:     cp = _res.defdname;
        !           958:     pp = _res.dnsrch;
        !           959:     *pp++ = cp;
        !           960:     for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
        !           961:            if (*cp == SRCHLIST_SEP) {
        !           962:                    *cp = '\0';
        !           963:                    n = 1;
        !           964:            } else if (n) {
        !           965:                    *pp++ = cp;
        !           966:                    n = 0;
        !           967:            }
        !           968:     }
        !           969:     if ((cp = strchr(pp[-1], SRCHLIST_SEP)) != NULL) {
        !           970:        *cp = '\0';
        !           971:     }
        !           972:     *pp = NULL;
        !           973: }
        !           974: 
        !           975: 
        !           976: /*
        !           977:  *******************************************************************************
        !           978:  *
        !           979:  *  ShowOptions --
        !           980:  *
        !           981:  *     Prints out the state information used by the resolver
        !           982:  *     library and other options set by the user.
        !           983:  *
        !           984:  *******************************************************************************
        !           985:  */
        !           986: 
        !           987: void
        !           988: ShowOptions()
        !           989: {
        !           990:     register char **cp;
        !           991: 
        !           992:     PrintHostInfo(stdout, "Default Server:", defaultPtr);
        !           993:     if (curHostValid) {
        !           994:        PrintHostInfo(stdout, "Host:", &curHostInfo);
        !           995:     }
        !           996: 
        !           997:     printf("Set options:\n");
        !           998:     printf("  %sdebug  \t", (_res.options & RES_DEBUG) ? "" : "no");
        !           999:     printf("  %sdefname\t", (_res.options & RES_DEFNAMES) ? "" : "no");
        !          1000:     printf("  %ssearch\t", (_res.options & RES_DNSRCH) ? "" : "no");
        !          1001:     printf("  %srecurse\n", (_res.options & RES_RECURSE) ? "" : "no");
        !          1002: 
        !          1003:     printf("  %sd2\t\t", (_res.options & RES_DEBUG2) ? "" : "no");
        !          1004:     printf("  %svc\t\t", (_res.options & RES_USEVC) ? "" : "no");
        !          1005:     printf("  %signoretc\t", (_res.options & RES_IGNTC) ? "" : "no");
        !          1006:     printf("  port=%u\n", nsport);
        !          1007: 
        !          1008:     printf("  querytype=%s\t", p_type(queryType));
        !          1009:     printf("  class=%s\t", p_class(queryClass));
        !          1010:     printf("  timeout=%d\t", _res.retrans);
        !          1011:     printf("  retry=%d\n", _res.retry);
        !          1012:     printf("  root=%s\n", rootServerName);
        !          1013:     printf("  domain=%s\n", _res.defdname);
        !          1014:     
        !          1015:     if (cp = _res.dnsrch) {
        !          1016:        printf("  srchlist=%s", *cp);
        !          1017:        for (cp++; *cp; cp++) {
        !          1018:            printf("%c%s", SRCHLIST_SEP, *cp);
        !          1019:        }
        !          1020:        putchar('\n');
        !          1021:     }
        !          1022:     putchar('\n');
        !          1023: }
        !          1024: #undef SRCHLIST_SEP
        !          1025: 
        !          1026: /*
        !          1027:  *******************************************************************************
        !          1028:  *
        !          1029:  *  PrintHelp --
        !          1030:  *
        !          1031:  *     Prints out the help file.
        !          1032:  *     (Code taken from Mail.)
        !          1033:  *
        !          1034:  *******************************************************************************
        !          1035:  */
        !          1036: 
        !          1037: void
        !          1038: PrintHelp()
        !          1039: {
        !          1040:        register int c;
        !          1041:        register FILE *helpFilePtr;
        !          1042: 
        !          1043:        if ((helpFilePtr = fopen(_PATH_HELPFILE, "r")) == NULL) {
        !          1044:            perror(_PATH_HELPFILE);
        !          1045:            return;
        !          1046:        } 
        !          1047:        while ((c = getc(helpFilePtr)) != EOF) {
        !          1048:            putchar((char) c);
        !          1049:        }
        !          1050:        fclose(helpFilePtr);
        !          1051: }
        !          1052: 
        !          1053: /*
        !          1054:  *******************************************************************************
        !          1055:  *
        !          1056:  * CvtAddrToPtr --
        !          1057:  *
        !          1058:  *     Convert a dotted-decimal Internet address into the standard
        !          1059:  *     PTR format (reversed address with .in-arpa. suffix).
        !          1060:  *
        !          1061:  *     Assumes the argument buffer is large enougth to hold the result.
        !          1062:  *
        !          1063:  *******************************************************************************
        !          1064:  */
        !          1065: 
        !          1066: static void
        !          1067: CvtAddrToPtr(name)
        !          1068:     char *name;
        !          1069: {
        !          1070:     char *p;
        !          1071:     int ip[4];
        !          1072:     struct in_addr addr;
        !          1073: 
        !          1074:     if (IsAddr(name, &addr.s_addr)) {
        !          1075:        p = inet_ntoa(addr);
        !          1076:        if (sscanf(p, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) {
        !          1077:            sprintf(name, "%d.%d.%d.%d.in-addr.arpa.", 
        !          1078:                ip[3], ip[2], ip[1], ip[0]);
        !          1079:        }
        !          1080:     }
        !          1081: }
        !          1082: 
        !          1083: /*
        !          1084:  *******************************************************************************
        !          1085:  *
        !          1086:  * ReadRC --
        !          1087:  *
        !          1088:  *     Use the contents of ~/.nslookuprc as options.
        !          1089:  *
        !          1090:  *******************************************************************************
        !          1091:  */
        !          1092: 
        !          1093: static void
        !          1094: ReadRC()
        !          1095: {
        !          1096:     register FILE *fp;
        !          1097:     register char *cp;
        !          1098:     char buf[NAME_LEN];
        !          1099: 
        !          1100:     if ((cp = getenv("HOME")) != NULL) {
        !          1101:        (void) strcpy(buf, cp);
        !          1102:        (void) strcat(buf, "/.nslookuprc");
        !          1103: 
        !          1104:        if ((fp = fopen(buf, "r")) != NULL) {
        !          1105:            while (fgets(buf, sizeof(buf), fp) != NULL) {
        !          1106:                if ((cp = strchr(buf, '\n')) != NULL) {
        !          1107:                    *cp = '\0';
        !          1108:                }
        !          1109:                (void) SetOption(buf);
        !          1110:            }
        !          1111:            (void) fclose(fp);
        !          1112:        }
        !          1113:     }
        !          1114: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.