📄 main.c
字号:
/* * Copyright (c) 1985 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of California at Berkeley. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. */#ifndef lintstatic char sccsid[] = "@(#)main.c 1.1 92/07/30 SMI from UCB 5.15 3/26/88";#endif /* not lint *//* ******************************************************************************* * * main.c -- * * Main routine and some action routines for the name server * lookup program. * * Andrew Cherenson CS298-26 Fall 1985 * ******************************************************************************* */#include <stdio.h>#include <strings.h>#include <sys/param.h>#include <netdb.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <resolv.h>#include <signal.h>#include <setjmp.h>#include "res.h"/* * Location of the help file. */#ifndef HELPFILE#define HELPFILE "/usr/lib/nslookup.help"#endif/* * Name of a top-level name server. Can be changed with * the "set root" command. */#define ROOT_SERVER "sri-nic.arpa."char rootServerName[NAME_LEN];/* * Import the state information from the resolver library. */extern struct state _res;/* * Info about the most recently queried host. */HostInfo curHostInfo;int curHostValid = FALSE;/* * Info about the default name server. */HostInfo *defaultPtr = NULL;char defaultServer[NAME_LEN];struct in_addr defaultAddr;/* * Initial name server query type is Address. */int queryType = T_A;int queryClass = C_IN;/* * Stuff for Interrupt (control-C) signal handler. * SockFD is the file descriptor for sockets used to * connect with the name servers. It has to be global to * allow the interrupt handler can close open sockets. */extern int IntrHandler();int sockFD = -1;FILE *filePtr;jmp_buf env;/* ******************************************************************************* * * main -- * * Initializes the resolver library and determines the address * of the initial name server. The yylex routine is used to * read and perform commands. * ******************************************************************************* */main(argc, argv) int argc; char **argv;{ int result; char hostName[NAME_LEN]; char *wantedHost = NULL; int useLocalServer; int i; struct hostent *hp; extern int h_errno; /* * Initialize the resolver library routines. */ if (res_init() == -1) { fprintf(stderr,"*** Can't initialize resolver.\n"); exit(1); } /* * Allocate space for the default server's host info and * find the server's address and name. If the resolver library * already has some addresses for a potential name server, * then use them. Otherwise, see if the current host has a server. * Command line arguments may override the choice of initial server. */ defaultPtr = (HostInfo *) Calloc(1, sizeof(HostInfo)); /* * Parse the arguments: * no args = go into interactive mode, use default host as server * 1 arg = use as host name to be looked up, default host will be server * non-interactive mode * 2 args = 1st arg: * if it is '-', then * ignore but go into interactive mode * else * use as host name to be looked up, * go into non-interactive mode * 2nd arg: name or inet address of server * */ useLocalServer = FALSE; if (argc > 1) { if (argc > 3) { Usage(); } argv++; /* skip prog name */ if (*argv[0] != '-') { wantedHost = *argv; /* name of host to be looked up */ } if (argc == 3) { /* * Set explicit name server address. */ _res.nscount = 1; _res.nsaddr.sin_addr.s_addr = inet_addr(*++argv); if (_res.nsaddr.sin_addr.s_addr == (unsigned)-1) { hp = gethostbyname(*argv); if (hp == NULL){ herror(h_errno); _res.nscount = 0; useLocalServer = TRUE; } else { bcopy(hp->h_addr_list[0], &_res.nsaddr.sin_addr, hp->h_length); useLocalServer = FALSE; } } } } if (_res.nscount > 0 && !useLocalServer) { for (i = 0; i < _res.nscount; i++) { if ((_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) || (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_LOOPBACK)) { useLocalServer = TRUE; break; } else { result = FindHostInfo(&(_res.nsaddr_list[i].sin_addr), &(_res.nsaddr_list[i].sin_addr), sizeof(struct in_addr), defaultPtr); if (result != SUCCESS) { fprintf(stderr, "*** Can't find server name for address %s: %s\n", inet_ntoa(_res.nsaddr_list[i].sin_addr), DecodeError(result)); } else { defaultAddr = _res.nsaddr_list[i].sin_addr; break; } } } if (i == _res.nscount) useLocalServer = 1; } gethostname(hostName, sizeof(hostName));#ifdef SOMEDAY strcpy(defaultServer, hostName); (void) GetHostInfo(&defaultAddr, C_IN, T_A, "0.0.0.0", defaultPtr, 1); defaultPtr->name = hostName;#else/* * Internet address of the current host if 4.2BSD style */#define LOCALHOST "127.0.0.1" if (useLocalServer) { defaultAddr.s_addr = inet_addr(LOCALHOST); result = GetHostInfo(&defaultAddr, C_IN, T_A, hostName, defaultPtr, 1); if (result != SUCCESS) { fprintf(stderr, "*** Can't find initialize address for server %s: %s\n", defaultServer, DecodeError(result)); defaultPtr->name = "localhost"; defaultPtr->addrList = (char **) Calloc(1, sizeof(char *)); defaultPtr->addrList[0] = (char *)&defaultAddr.s_addr; } } strcpy(defaultServer, defaultPtr->name);#endif strcpy(rootServerName, ROOT_SERVER);#ifdef DEBUG#ifdef DEBUG2 _res.options |= RES_DEBUG2;#endif _res.options |= RES_DEBUG; _res.retry = 2;#endif DEBUG /* * If we're in non-interactive mode, look up the wanted host and quit. * Otherwise, print the initial server's name and continue with * the initialization. */ if (wantedHost != (char *) NULL) { LookupHost(wantedHost, 0); exit(0); } else { PrintHostInfo(stdout, "Default Server:", defaultPtr); } /* * Setup the environment to allow the interrupt handler to return here. */ (void) setjmp(env); /* * Return here after a longjmp. */ signal(SIGPIPE, SIG_IGN); signal(SIGINT, IntrHandler); /* * Read and evaluate commands. The commands are described in commands.l * Yylex returns 0 when ^D or 'exit' is typed. */ printf("> "); while(yylex()) { printf("> "); } exit(0); /* NOTREACHED */}/* ******************************************************************************* * * Usage -- * * Lists the proper methods to run the program and exits. * ******************************************************************************* */Usage(){ fprintf(stderr, "Usage:\n"); fprintf(stderr, "\tnslookup # interactive mode using default server\n"); fprintf(stderr, "\tnslookup - server # interactive mode using 'server'\n"); fprintf(stderr, "\tnslookup host # just look up 'host' using default server\n"); fprintf(stderr, "\tnslookup host server # just look up 'host' using 'server'\n"); exit(1);}/* ******************************************************************************* * * SetDefaultServer -- * * Changes the default name server to the one specified by * the first argument. The command "server name" uses the current * default server to lookup the info for "name". The command * "lserver name" uses the original server to lookup "name". * * Side effects: * This routine will cause a core dump if the allocation requests fail. * * Results: * SUCCESS The default server was changed successfully. * NONAUTH The server was changed but addresses of * other servers who know about the requested server * were returned. * Errors No info about the new server was found or * requests to the current server timed-out. * ******************************************************************************* */intSetDefaultServer(string, local) char *string; int local;{ register HostInfo *newDefPtr; char newServer[NAME_LEN]; int result; int i; /* * Parse the command line. It maybe of the form "server name", * "lserver name" or just "name". */ if (local) { i = sscanf(string, " lserver %s", newServer); } else { i = sscanf(string, " server %s", newServer); } if (i != 1) { i = sscanf(string, " %s", newServer); if (i != 1) { fprintf(stderr,"SetDefaultServer: invalid name: %s\n", string); return(ERROR); } } /* * Allocate space for a HostInfo variable for the new server. Don't * overwrite the old HostInfo struct because info about the new server * might not be found and we need to have valid default server info. */ newDefPtr = (HostInfo *) Calloc(1, sizeof(HostInfo)); /* * A 'local' lookup uses the original server that the program was * initialized with. */ if (local) { result = GetHostInfo(&defaultAddr, C_IN, T_A, newServer, newDefPtr, 1); } else { /* * Check to see if we have the address of the server or the * address of a server who knows about this domain. * * For now, just use the first address in the list. */ if (defaultPtr->addrList == NULL) { result = GetHostInfo( (struct in_addr *) defaultPtr->servers[0]->addrList[0], C_IN, T_A, newServer, newDefPtr, 1); } else { result = GetHostInfo((struct in_addr *) defaultPtr->addrList[0], C_IN, T_A, newServer, newDefPtr, 1); } } if (result == SUCCESS || result == NONAUTH) { /* * Found info about the new server. Free the resources for * the old server. */ FreeHostInfoPtr(defaultPtr); free((char *)defaultPtr); defaultPtr = newDefPtr; strcpy(defaultServer, defaultPtr->name); PrintHostInfo(stdout, "Default Server:", defaultPtr); return(SUCCESS); } else { fprintf(stderr, "*** Can't find address for server %s: %s\n", newServer, DecodeError(result)); free((char *)newDefPtr); return(result); }}/* ******************************************************************************* * * LookupHost -- * * Asks the default name server for information about the * specified host or domain. The information is printed * if the lookup was successful. * * Results: * SUCCESS - the lookup was successful. * ERROR - the output file could not be opened. * Misc. Errors - an error message is printed if the lookup failed. * ******************************************************************************* */intLookupHost(string, putToFile) char *string;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -