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