1: /*
   2:  *******************************************************************************
   3:  *
   4:  *   main.c --
   5:  *
   6:  *  	Main routine and some action routines for the name server
   7:  *	lookup program.
   8:  *
   9:  *	Copyright (c) 1985 Regents of the University of California.
  10:  *	All rights reserved.  The Berkeley software License Agreement
  11:  *	specifies the terms and conditions for redistribution.
  12:  *
  13:  *  	Andrew Cherenson 	CS298-26  Fall 1985
  14:  *
  15:  *******************************************************************************
  16:  */
  17: 
  18: #ifndef lint
  19: char copyright[] =
  20: "@(#) Copyright (c) 1985 Regents of the University of California.\n\
  21:  All rights reserved.\n";
  22: #endif not lint
  23: 
  24: #ifndef lint
  25: static char sccsid[] = "@(#)main.c	5.7 (Berkeley) 5/6/86";
  26: #endif not lint
  27: 
  28: #include <stdio.h>
  29: #include <strings.h>
  30: #include <sys/types.h>
  31: #include <netdb.h>
  32: #include <sys/socket.h>
  33: #include <netinet/in.h>
  34: #include <arpa/nameser.h>
  35: #include <resolv.h>
  36: #include <signal.h>
  37: #include <setjmp.h>
  38: #include "res.h"
  39: 
  40: /*
  41:  *  Location of the help file.
  42:  */
  43: 
  44: #define HELPFILE "/usr/local/nslookup.help"
  45: 
  46: 
  47: /*
  48:  *  Internet address of the current host.
  49:  */
  50: 
  51: #define LOCALHOST "127.0.0.1"
  52: 
  53: 
  54: /*
  55:  * Name of a top-level name server. Can be changed with
  56:  * the "set root" command.
  57:  */
  58: 
  59: #define     ROOT_SERVER "sri-nic.arpa"
  60: char        rootServerName[NAME_LEN];
  61: 
  62: 
  63: /*
  64:  *  Import the state information from the resolver library.
  65:  */
  66: 
  67: extern struct state _res;
  68: 
  69: 
  70: /*
  71:  *  Info about the most recently queried host.
  72:  */
  73: 
  74: HostInfo    curHostInfo;
  75: int     curHostValid = FALSE;
  76: 
  77: 
  78: /*
  79:  *  Info about the default name server.
  80:  */
  81: 
  82: HostInfo    *defaultPtr = NULL;
  83: char        defaultServer[NAME_LEN];
  84: struct in_addr  defaultAddr;
  85: 
  86: 
  87: /*
  88:  *  Initial name server query type is Address.
  89:  */
  90: 
  91: int         queryType = T_A;
  92: 
  93: /*
  94:  * Stuff for Interrupt (control-C) signal handler.
  95:  *  SockFD is the file descriptor for sockets used to
  96:  *  connect with the name servers. It has to be global to
  97:  *  allow the interrupt handler can close open sockets.
  98:  */
  99: 
 100: extern int  IntrHandler();
 101: int         sockFD = -1;
 102: FILE        *filePtr;
 103: jmp_buf     env;
 104: 
 105: 
 106: /*
 107:  *******************************************************************************
 108:  *
 109:  *  main --
 110:  *
 111:  *	Initializes the resolver library and determines the address
 112:  *	of the initial name server. The yylex routine is used to
 113:  *	read and perform commands.
 114:  *
 115:  *******************************************************************************
 116:  */
 117: 
 118: main(argc, argv)
 119:     int argc;
 120:     char **argv;
 121: {
 122:     int     result;
 123:     char    hostName[NAME_LEN];
 124:     char    *cp;
 125:     char    *find;
 126:     int     useLocalServer;
 127:     int     i;
 128:     struct hostent  *hp;
 129: 
 130:     /*
 131:      *  Initialize the resolver library routines.
 132:      */
 133: 
 134:     if (res_init() == -1) {
 135:     fprintf(stderr,"*** Can't find initialize resolver.\n");
 136:     exit(1);
 137:     }
 138: 
 139:     /*
 140:      *  Allocate space for the default server's host info and
 141:      *  find the server's address and name. If the resolver library
 142:      *  already has some addresses for a potential name server,
 143:      *  then use them. Otherwise, see if the current host has a server.
 144:      *  Command line arguments may override the choice of initial server.
 145:      */
 146: 
 147:     defaultPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
 148: 
 149:     useLocalServer = FALSE;
 150:     if (argc != 0) {
 151:     find = *++argv;
 152:     if (argc == 3) {
 153:             /*
 154:              *	Set explicit name server address.
 155:              *
 156:              */
 157:         _res.nscount = 1;
 158:         _res.nsaddr.sin_addr.s_addr = inet_addr(*++argv);
 159:         if (_res.nsaddr.sin_addr.s_addr == (unsigned)-1) {
 160:         hp = gethostbyname(*argv);
 161:         if (hp == NULL){
 162:             hperror(hp);
 163:                 _res.nscount = 0;
 164:                     useLocalServer = TRUE;
 165:         } else {
 166:             bcopy(hp->h_addr_list[0], &_res.nsaddr.sin_addr,
 167:                hp->h_length);
 168:                 useLocalServer = FALSE;
 169:         }
 170:         }
 171:         }
 172:     if (argc > 3) {
 173:         fprintf(stderr,
 174:         "Usage: nslookup findhost { servername | address }\n");
 175:         exit(1);
 176:     }
 177:     }
 178: 
 179: 
 180:     if (_res.nscount > 0 && !useLocalServer) {
 181:     for (i = 0; i < _res.nscount; i++) {
 182:         if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) {
 183:             useLocalServer = TRUE;
 184:         break;
 185:         } else {
 186:         result = FindHostInfo(&(_res.nsaddr_list[i].sin_addr),
 187:                     &(_res.nsaddr_list[i].sin_addr),
 188:                     sizeof(struct in_addr),
 189:                     defaultPtr);
 190:         if (result != SUCCESS) {
 191:             fprintf(stderr,
 192:             "*** Can't find server name for address %s: %s\n",
 193:                inet_ntoa(_res.nsaddr_list[i].sin_addr),
 194:                DecodeError(result));
 195:         } else {
 196:             defaultAddr = _res.nsaddr_list[i].sin_addr;
 197:             break;
 198:         }
 199:         }
 200:     }
 201: 
 202:     /*
 203: 	 *  If we have exhausted the list, tell the user about the
 204: 	 *  command line argument to specify an address.
 205: 	 */
 206: 
 207:     if (i == _res.nscount) {
 208:         fprintf(stderr,
 209:         "*** Default servers are not available\n");
 210:         exit(1);
 211:     }
 212: 
 213:     }
 214:     if (useLocalServer) {
 215: 
 216:     defaultAddr.s_addr = inet_addr(LOCALHOST);
 217:     gethostname(hostName, sizeof(hostName));
 218: 
 219:     result = GetHostInfo(&defaultAddr, T_A, hostName, defaultPtr);
 220:     if (result != SUCCESS) {
 221:         fprintf(stderr,
 222:         "*** Can't find initialize address for server %s: %s\n",
 223:                 defaultServer, DecodeError(result));
 224:         exit(1);
 225:     }
 226:     }
 227:     strcpy(defaultServer, defaultPtr->name);
 228:     PrintHostInfo(stdout, "Default Server:", defaultPtr);
 229: 
 230:     strcpy(rootServerName, ROOT_SERVER);
 231: 
 232: /*
 233:     _res.options |= (RES_DEBUG | RES_DEBUG2);
 234:     _res.options |= RES_DEBUG;
 235:     _res.retry    = 2;
 236: */
 237:     _res.options &= ~RES_DEFNAMES;
 238: 
 239:     if (find) {
 240:     hp = gethostbyname(find);
 241:     if (hp == NULL) {
 242:         hperror(h_errno);
 243:         exit(1);
 244:         }
 245:         printanswer(hp);
 246:     exit(0);
 247:     }
 248: 
 249:     /*
 250:      * Setup the environment to allow the interrupt handler to return here.
 251:      */
 252: 
 253:     (void) setjmp(env);
 254: 
 255:     /*
 256:      * Return here after a longjmp.
 257:      */
 258: 
 259:     signal(SIGINT, IntrHandler);
 260: 
 261:     /*
 262:      * Read and evaluate commands. Yylex returns 0 when ^D or 'exit'
 263:      * is typed.
 264:      */
 265:     printf("> ");
 266:     while(yylex()) {
 267:     printf("> ");
 268:     }
 269: }
 270: 
 271: /*
 272:  *******************************************************************************
 273:  *
 274:  *  SetDefaultServer --
 275:  *
 276:  *	Changes the default name server to the one specified by
 277:  *	the first argument. The command "server name" uses the current
 278:  *	default server to lookup the info for "name". The command
 279:  *	"lserver name" uses the original server to lookup "name".
 280:  *
 281:  *  Side effects:
 282:  *	This routine will cause a core dump if the allocation requests fail.
 283:  *
 284:  *  Results:
 285:  *	SUCCESS 	The default server was changed successfully.
 286:  *	NONAUTH		The server was changed but addresses of
 287:  *			other servers who know about the requested server
 288:  *			were returned.
 289:  *	Errors		No info about the new server was found or
 290:  *			requests to the current server timed-out.
 291:  *
 292:  *******************************************************************************
 293:  */
 294: 
 295: int
 296: SetDefaultServer(string, local)
 297:     char *string;
 298:     int  local;
 299: {
 300:     register HostInfo   *newDefPtr;
 301:     char        newServer[NAME_LEN];
 302:     int         result;
 303:     int         i;
 304: 
 305:     /*
 306:      *  Parse the command line. It maybe of the form "server name",
 307:      *  "lserver name" or just "name".
 308:      */
 309: 
 310:     if (local) {
 311:     i = sscanf(string, " lserver %s", newServer);
 312:     } else {
 313:     i = sscanf(string, " server %s", newServer);
 314:     }
 315:     if (i != 1) {
 316:     i = sscanf(string, " %s", newServer);
 317:     if (i != 1) {
 318:         fprintf(stderr,"SetDefaultServer: invalid name: %s\n",  string);
 319:         return(ERROR);
 320:     }
 321:     }
 322: 
 323:     /*
 324:      * Allocate space for a HostInfo variable for the new server. Don't
 325:      * overwrite the old HostInfo struct because info about the new server
 326:      * might not be found and we need to have valid default server info.
 327:      */
 328: 
 329:     newDefPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
 330: 
 331: 
 332:     /*
 333:      *	A 'local' lookup uses the original server that the program was
 334:      *  initialized with.
 335:      */
 336: 
 337:     if (local) {
 338:     result = GetHostInfo(&defaultAddr, T_A, newServer, newDefPtr);
 339:     } else {
 340: 
 341:     /*
 342: 	 *  Check to see if we have the address of the server or the
 343: 	 *	address of a server who knows about this domain.
 344: 	 *
 345: 	 *  For now, just use the first address in the list.
 346: 	 */
 347:     if (defaultPtr->addrList == NULL) {
 348:         result = GetHostInfo(
 349:             (struct in_addr *) defaultPtr->servers[0]->addrList[0],
 350:                 T_A, newServer, newDefPtr);
 351:     } else {
 352:         result = GetHostInfo((struct in_addr *) defaultPtr->addrList[0],
 353:                 T_A, newServer, newDefPtr);
 354:     }
 355:     }
 356: 
 357:     if (result == SUCCESS || result == NONAUTH) {
 358:         /*
 359: 	     *  Found info about the new server. Free the resources for
 360: 	     *  the old server.
 361: 	     */
 362: 
 363:         FreeHostInfoPtr(defaultPtr);
 364:         free((char *)defaultPtr);
 365:         defaultPtr = newDefPtr;
 366:         strcpy(defaultServer, defaultPtr->name);
 367:         PrintHostInfo(stdout, "Default Server:", defaultPtr);
 368:         return(SUCCESS);
 369:     } else {
 370:         fprintf(stderr, "*** Can't find address for server %s: %s\n",
 371:             newServer, DecodeError(result));
 372:         free((char *)newDefPtr);
 373: 
 374:         return(result);
 375:     }
 376: }
 377: 
 378: /*
 379:  *******************************************************************************
 380:  *
 381:  *  LookupHost --
 382:  *
 383:  *	Asks the default name server for information about the
 384:  *	specified host or domain. The information is printed
 385:  *	if the lookup was successful.
 386:  *
 387:  *  Results:
 388:  *	SUCCESS		- the lookup was successful.
 389:  *	ERROR		- the output file could not be opened.
 390:  *	Misc. Errors	- an error message is printed if the lookup failed.
 391:  *
 392:  *******************************************************************************
 393:  */
 394: 
 395: int
 396: LookupHost(string, putToFile)
 397:     char *string;
 398:     int  putToFile;
 399: {
 400:     char    host[NAME_LEN];
 401:     char    file[NAME_LEN];
 402:     int     result;
 403: 
 404:     /*
 405:      *  Invalidate the current host information to prevent Finger
 406:      *  from using bogus info.
 407:      */
 408: 
 409:     curHostValid = FALSE;
 410: 
 411:     /*
 412:      *	 Parse the command string into the host and
 413:      *	 optional output file name.
 414:      *
 415:      */
 416: 
 417:     sscanf(string, " %s", host);    /* removes white space */
 418:     if (!putToFile) {
 419:     filePtr = stdout;
 420:     } else {
 421:     filePtr = OpenFile(string, file);
 422:     if (filePtr == NULL) {
 423:         fprintf(stderr, "*** Can't open %s for writing\n", file);
 424:         return(ERROR);
 425:     }
 426:     fprintf(filePtr,"> %s\n", string);
 427:     }
 428: 
 429:     PrintHostInfo(filePtr, "Server:", defaultPtr);
 430: 
 431:     /*
 432:      *  Check to see if we have the address of the server or the
 433:      *	address of a server who knows about this domain.
 434:      *
 435:      *  For now, just use the first address in the list.
 436:      */
 437: 
 438:     if (defaultPtr->addrList == NULL) {
 439:     result = GetHostInfo(
 440:             (struct in_addr *) defaultPtr->servers[0]->addrList[0],
 441:               queryType, host, &curHostInfo);
 442:     } else {
 443:     result = GetHostInfo((struct in_addr *) defaultPtr->addrList[0],
 444:               queryType, host, &curHostInfo);
 445:     }
 446: 
 447:     switch(result) {
 448:     case SUCCESS:
 449:         /*
 450: 	     *  If the query was for an address, then the curHostInfo
 451: 	     *  variable can be used by Finger.
 452: 	     *  There's no need to print anything for other query types
 453: 	     *  because the info has already been printed.
 454: 	     */
 455:         if (queryType == T_A) {
 456:         curHostValid = TRUE;
 457:         PrintHostInfo(filePtr, "Name:", &curHostInfo);
 458:         }
 459:         break;
 460: 
 461:     /*
 462: 	 * No Authoritative answer was available but we got names
 463: 	 * of servers who know about the host.
 464: 	 */
 465:     case NONAUTH:
 466:         PrintHostInfo(filePtr, "Name:", &curHostInfo);
 467:         break;
 468: 
 469:     case NO_INFO:
 470:         fprintf(stderr, "*** No %s information is available for %s\n",
 471:             DecodeType(queryType), host);
 472:         break;
 473: 
 474:     case TIME_OUT:
 475:         fprintf(stderr, "*** Request to %s timed-out\n", defaultServer);
 476:         break;
 477: 
 478:     default:
 479:         fprintf(stderr, "*** %s can't find %s: %s\n", defaultServer, host,
 480:             DecodeError(result));
 481:     }
 482:     if (putToFile) {
 483:     fclose(filePtr);
 484:     filePtr = NULL;
 485:     }
 486:     return(result);
 487: }
 488: 
 489: /*
 490:  *******************************************************************************
 491:  *
 492:  *  LookupHostWithServer --
 493:  *
 494:  *	Asks the name server specified in the second argument for
 495:  *	information about the host or domain specified in the first
 496:  *	argument. The information is printed if the lookup was successful.
 497:  *
 498:  *	Address info about the requested name server is obtained
 499:  *	from the default name server. This routine will return an
 500:  *	error if the default server doesn't have info about the
 501:  *	requested server. Thus an error return status might not
 502:  *	mean the requested name server doesn't have info about the
 503:  *	requested host.
 504:  *
 505:  *	Comments from LookupHost apply here, too.
 506:  *
 507:  *  Results:
 508:  *	SUCCESS		- the lookup was successful.
 509:  *	ERROR		- the output file could not be opened.
 510:  *	Misc. Errors	- an error message is printed if the lookup failed.
 511:  *
 512:  *******************************************************************************
 513:  */
 514: 
 515: int
 516: LookupHostWithServer(string, putToFile)
 517:     char *string;
 518:     int  putToFile;
 519: {
 520:     char    file[NAME_LEN];
 521:     char    host[NAME_LEN];
 522:     char    server[NAME_LEN];
 523:     int     result;
 524:     static HostInfo serverInfo;
 525: 
 526:     curHostValid = FALSE;
 527: 
 528:     sscanf(string, " %s %s", host, server);
 529:     if (!putToFile) {
 530:     filePtr = stdout;
 531:     } else {
 532:     filePtr = OpenFile(string, file);
 533:     if (filePtr == NULL) {
 534:         fprintf(stderr, "*** Can't open %s for writing\n", file);
 535:         return(ERROR);
 536:     }
 537:     fprintf(filePtr,"> %s\n", string);
 538:     }
 539: 
 540: 
 541:     if (defaultPtr->addrList == NULL) {
 542:     result = GetHostInfo(
 543:             (struct in_addr *) defaultPtr->servers[0]->addrList[0],
 544:                 T_A, server, &serverInfo);
 545:     } else {
 546:     result = GetHostInfo((struct in_addr *) defaultPtr->addrList[0],
 547:                 T_A, server, &serverInfo);
 548:     }
 549: 
 550:     if (result != SUCCESS) {
 551:     fprintf(stderr,"*** Can't find address for server %s: %s\n", server,
 552:          DecodeError(result));
 553:     } else {
 554:     PrintHostInfo(filePtr, "Server:", &serverInfo);
 555: 
 556:     if (serverInfo.addrList == NULL) {
 557:         result = GetHostInfo(
 558:             (struct in_addr *) serverInfo.servers[0]->addrList[0],
 559:                   queryType, host, &curHostInfo);
 560:     } else {
 561:         result = GetHostInfo((struct in_addr *) serverInfo.addrList[0],
 562:                   queryType, host, &curHostInfo);
 563:     }
 564: 
 565: 
 566:     switch(result) {
 567: 
 568:         case SUCCESS:
 569:         if (queryType == T_A) {
 570:             curHostValid = TRUE;
 571:             PrintHostInfo(filePtr, "Name:", &curHostInfo);
 572:         }
 573:         break;
 574: 
 575:         case NONAUTH:
 576:         PrintHostInfo(filePtr, "Name:", &curHostInfo);
 577:         break;
 578: 
 579:         case NO_INFO:
 580:         fprintf(stderr, "*** No %s information is available for %s\n",
 581:             DecodeType(queryType), host);
 582:         break;
 583: 
 584:         case TIME_OUT:
 585:         fprintf(stderr, "*** Request to %s timed-out\n", server);
 586:         break;
 587: 
 588:         default:
 589:         fprintf(stderr, "*** %s can't find %s: %s\n", server, host,
 590:             DecodeError(result));
 591:     }
 592:     }
 593:     if (putToFile) {
 594:     fclose(filePtr);
 595:     filePtr = NULL;
 596:     }
 597:     return(result);
 598: }
 599: 
 600: /*
 601:  *******************************************************************************
 602:  *
 603:  *  SetOption --
 604:  *
 605:  *	This routine is used to change the state information
 606:  *	that affect the lookups. The command format is
 607:  *	   set keyword[=value]
 608:  *	Most keywords can be abbreviated. Parsing is very simplistic--
 609:  *	A value must not be separated from its keyword by white space.
 610:  *
 611:  *	Valid keywords:		Meaning:
 612:  *	[no]aaonly	  	authoritative query only or not (hidden).
 613:  *	all			lists current values of options.
 614:  *	ALL			lists current values of options, including
 615:  *				  hidden options.
 616:  *	[no]d2			turn on/off extra debugging mode (hidden).
 617:  *	[no]debug 		turn on/off debugging mode.
 618:  *	[no]defname	  	use/don't use default domain name.
 619:  *	domain=NAME		set default domain name to NAME.
 620:  *	[no]ignore		ignore/don't ignore trunc. errors (hidden).
 621:  *	[no]primary 		use/don't use primary server (hidden).
 622:  *	query=value		set default query type to value,
 623:  *				value is one of the query types in RFC883
 624:  *				without the leading T_.	(e.g. A, HINFO)
 625:  *	[no]recurse		use/don't use recursive lookup.
 626:  *	retry=#			set number of retries to #.
 627:  *	root=NAME		change root server to NAME.
 628:  *	time=#			set timeout length to #.
 629:  *	[no]vc			use/don't use virtual circuit.
 630:  *
 631:  *  Results:
 632:  *	SUCCESS		the command was parsed correctly.
 633:  *	ERROR		the command was not parsed correctly.
 634:  *
 635:  *******************************************************************************
 636:  */
 637: 
 638: int
 639: SetOption(string)
 640:     char *string;
 641: {
 642:     char    option[NAME_LEN];
 643:     char    type[NAME_LEN];
 644:     char    *ptr;
 645:     int     i;
 646: 
 647:     i = sscanf(string, " set %s", option);
 648:     if (i != 1) {
 649:     fprintf(stderr, "*** Invalid option: %s\n",  option);
 650:     return(ERROR);
 651:     } else {
 652:     if (strncmp(option, "all", 3) == 0) {
 653:         ShowOptions(FALSE);
 654:     } else if (strncmp(option, "ALL", 3) == 0) {
 655:         ShowOptions(TRUE);
 656:     } else if (strncmp(option, "aa", 2) == 0) { /* aaonly */
 657:         _res.options |= RES_AAONLY;
 658:     } else if (strncmp(option, "noaa", 4) == 0) {
 659:         _res.options &= ~RES_AAONLY;
 660:     } else if (strncmp(option, "deb", 3) == 0) {    /* debug */
 661:         _res.options |= RES_DEBUG;
 662:     } else if (strncmp(option, "nodeb", 5) == 0) {
 663:         _res.options &= ~(RES_DEBUG | RES_DEBUG2);
 664:     } else if (strncmp(option, "d2", 2) == 0) { /* d2 (more debug) */
 665:         _res.options |= (RES_DEBUG | RES_DEBUG2);
 666:     } else if (strncmp(option, "nod2", 4) == 0) {
 667:         _res.options &= ~RES_DEBUG2;
 668:     } else if (strncmp(option, "def", 3) == 0) {    /* defname */
 669:         _res.options |= RES_DEFNAMES;
 670:     } else if (strncmp(option, "nodef", 5) == 0) {
 671:         _res.options &= ~RES_DEFNAMES;
 672:     } else if (strncmp(option, "do", 2) == 0) { /* domain */
 673:         ptr = index(option, '=');
 674:         if (ptr != NULL) {
 675:         sscanf(++ptr, "%s", _res.defdname);
 676:         }
 677:     } else if (strncmp(option, "i", 1) == 0) {  /* ignore */
 678:         _res.options |= RES_IGNTC;
 679:     } else if (strncmp(option, "noi", 3) == 0) {
 680:         _res.options &= ~RES_IGNTC;
 681:     } else if (strncmp(option, "p", 1) == 0) {  /* primary */
 682:         _res.options |= RES_PRIMARY;
 683:     } else if (strncmp(option, "nop", 3) == 0) {
 684:         _res.options &= ~RES_PRIMARY;
 685:     } else if (strncmp(option, "q", 1) == 0) {  /* querytype */
 686:         ptr = index(option, '=');
 687:         if (ptr != NULL) {
 688:         sscanf(++ptr, "%s", type);
 689:         queryType = StringToType(type);
 690:         }
 691:     } else if (strncmp(option, "rec", 3) == 0) {    /* recurse */
 692:         _res.options |= RES_RECURSE;
 693:     } else if (strncmp(option, "norec", 5) == 0) {
 694:         _res.options &= ~RES_RECURSE;
 695:     } else if (strncmp(option, "ret", 3) == 0) {    /* retry */
 696:         ptr = index(option, '=');
 697:         if (ptr != NULL) {
 698:         sscanf(++ptr, "%d", &_res.retry);
 699:         }
 700:     } else if (strncmp(option, "ro", 2) == 0) { /* root */
 701:         ptr = index(option, '=');
 702:         if (ptr != NULL) {
 703:         sscanf(++ptr, "%s", rootServerName);
 704:         }
 705:     } else if (strncmp(option, "t", 1) == 0) {  /* timeout */
 706:         ptr = index(option, '=');
 707:         if (ptr != NULL) {
 708:         sscanf(++ptr, "%d", &_res.retrans);
 709:         }
 710:     } else if (strncmp(option, "v", 1) == 0) {  /* vc */
 711:         _res.options |= RES_USEVC;
 712:     } else if (strncmp(option, "nov", 3) == 0) {
 713:         _res.options &= ~RES_USEVC;
 714:     } else {
 715:         fprintf(stderr, "*** Invalid option: %s\n",  option);
 716:         return(ERROR);
 717:     }
 718:     }
 719:     return(SUCCESS);
 720: }
 721: 
 722: /*
 723:  *******************************************************************************
 724:  *
 725:  *  ShowOptions --
 726:  *
 727:  *	Prints out the state information used by the resolver
 728:  *	library and other options set by the user.
 729:  *
 730:  *******************************************************************************
 731:  */
 732: 
 733: void
 734: ShowOptions(special)
 735:     int special;
 736: {
 737:     int i;
 738: 
 739:     PrintHostInfo(stdout, "Default Server:", defaultPtr);
 740:     if (curHostValid) {
 741:     PrintHostInfo(stdout, "Host:", &curHostInfo);
 742:     }
 743: 
 744:     printf("Set options:\n");
 745:     printf("  %sdebug\t", (_res.options & RES_DEBUG) ? "" : "no");
 746:     printf("  %sdefname\t", (_res.options & RES_DEFNAMES) ? "" : "no");
 747:     printf("  %srecurse\t", (_res.options & RES_RECURSE) ? "" : "no");
 748:     printf("  %svc\n", (_res.options & RES_USEVC) ? "" : "no");
 749: 
 750:     if (special) {
 751:     printf("  %saa\t", (_res.options & RES_AAONLY) ? "" : "no");
 752:     printf("  %sd2\t", (_res.options & RES_DEBUG2) ? "" : "no");
 753:     printf("  %signoretc\t", (_res.options & RES_IGNTC) ? "" : "no");
 754:     printf("  %sprimary\n", (_res.options & RES_PRIMARY) ? "" : "no");
 755:     }
 756: 
 757:     printf("  querytype=%s\t", p_type(queryType));
 758:     printf("  timeout=%d\t", _res.retrans);
 759:     printf("  retry=%d\n", _res.retry);
 760:     printf("  domain=%s\n", _res.defdname);
 761:     printf("  root=%s\n", rootServerName);
 762: 
 763:     if (special) {
 764:     printf("\n");
 765:     printf("State info:\n");
 766:     printf("  current packet id:       %d\n", _res.id);
 767:     printf("  number of name servers:  %d\n", _res.nscount);
 768:     printf("  name server addresses:   %s\n",
 769:                     inet_ntoa(_res.nsaddr_list[0].sin_addr));
 770:     for (i = 1; i < _res.nscount; i++) {
 771:         printf("                           %s\n",
 772:             inet_ntoa(_res.nsaddr_list[i].sin_addr));
 773:     }
 774:     }
 775: }
 776: 
 777: /*
 778:  *******************************************************************************
 779:  *
 780:  *  PrintHelp --
 781:  *
 782:  *	Prints out the help file.
 783: *	(Code taken from Mail.)
 784:  *
 785:  *******************************************************************************
 786:  */
 787: 
 788: void
 789: PrintHelp()
 790: {
 791:     register char c;
 792:     register FILE *filePtr;
 793: 
 794:     if ((filePtr = fopen(HELPFILE, "r")) == NULL) {
 795:         perror(HELPFILE);
 796:         return;
 797:     }
 798:     while ((c = getc(filePtr)) != EOF) {
 799:         putchar(c);
 800:     }
 801:     fclose(filePtr);
 802: }

Defined functions

LookupHost defined in line 395; never used
LookupHostWithServer defined in line 515; never used
PrintHelp defined in line 788; never used
SetDefaultServer defined in line 295; never used
SetOption defined in line 638; never used
ShowOptions defined in line 733; used 3 times
main defined in line 118; never used

Defined variables

copyright defined in line 19; never used
curHostValid defined in line 75; used 6 times
defaultAddr defined in line 84; used 4 times
defaultServer defined in line 83; used 5 times
env defined in line 103; used 1 times
queryType defined in line 91; used 10 times
rootServerName defined in line 60; used 3 times
sccsid defined in line 25; never used
sockFD defined in line 101; used 31 times

Defined macros

HELPFILE defined in line 44; used 2 times
LOCALHOST defined in line 51; used 1 times
ROOT_SERVER defined in line 59; used 1 times
Last modified: 1986-05-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3216
Valid CSS Valid XHTML 1.0 Strict