|
|
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.