⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ++Copyright++ 1985, 1989 * - * Copyright (c) 1985, 1989 *    The Regents of the University of California.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: * 	This product includes software developed by the University of * 	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. *  * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. *  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */#ifndef lintchar copyright[] ="@(#) Copyright (c) 1985,1989 Regents of the University of California.\n\ All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)main.c	5.42 (Berkeley) 3/3/91";static char rcsid[] = "$Id: main.c,v 4.9.1.3 1993/09/16 09:02:07 vixie Exp $";#endif /* not lint *//* ****************************************************************************** *   *   main.c -- *   *	Main routine and some action routines for the name server *	lookup program. * *	Andrew Cherenson *	U.C. Berkeley Computer Science Div. *	CS298-26, Fall 1985 *   ****************************************************************************** */#include <sys/param.h>#include <netdb.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <arpa/inet.h>#include <resolv.h>#include <signal.h>#include <setjmp.h>#include <ctype.h>#include <stdio.h>#include <errno.h>#include <limits.h>#include "res.h"#include "pathnames.h"#include "../../conf/portability.h"/* * Name of a top-level name server. Can be changed with  * the "set root" command. */#ifndef ROOT_SERVER#define		ROOT_SERVER "ns.internic.net."#endifchar		rootServerName[NAME_LEN] = ROOT_SERVER;/* *  Import the state information from the resolver library. */extern struct __res_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. */extern SIG_FN	IntrHandler();FILE		*filePtr;jmp_buf		env;/* * Browser command for help and view. */char		*pager;static void CvtAddrToPtr();static void ReadRC();/* ****************************************************************************** * *  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;{    char	*wantedHost = NULL;    Boolean	useLocalServer;    int		result;    int		i;    struct hostent	*hp;    /*     *  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     *     *	"Set" options are specified with a leading - and must come before     *	any arguments. For example, to find the well-known services for     *  a host, type "nslookup -query=wks host"     */    ReadRC();			/* look for options file */    ++argv; --argc;		/* skip prog name */    while (argc && *argv[0] == '-' && argv[0][1]) {	(void) SetOption (&(argv[0][1]));	++argv; --argc;    }    if (argc > 2) {	Usage();    }     if (argc && *argv[0] != '-') {	wantedHost = *argv;	/* name of host to be looked up */    }    useLocalServer = FALSE;    if (argc == 2) {	struct in_addr addr;	/*	 * Use an explicit name server. If the hostname lookup fails,	 * default to the server(s) in resolv.conf.	 */ 	if (inet_aton(*++argv, &addr)) {	    _res.nscount = 1;	    _res.nsaddr.sin_addr = addr;	} else {	    hp = gethostbyname(*argv);	    if (hp == NULL) {		fprintf(stderr, "*** Can't find server address for '%s': ", 			*argv);		herror((char *)NULL);		fputc('\n', stderr);	    } else {		for (i = 0; i < MAXNS && hp->h_addr_list[i] != NULL; i++) {		    bcopy(hp->h_addr_list[i], 			    (char *)&_res.nsaddr_list[i].sin_addr, 			    hp->h_length);		}		_res.nscount = i;	    } 	}    }    if (_res.nscount == 0 || useLocalServer) {	LocalServer(defaultPtr);    } else {	for (i = 0; i < _res.nscount; i++) {	    if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) {	        LocalServer(defaultPtr);		break;	    } else {		result = GetHostInfoByAddr(&(_res.nsaddr_list[i].sin_addr), 				    &(_res.nsaddr_list[i].sin_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 we have exhausted the list, tell the user about the	 *  command line argument to specify an address.	 */	if (i == _res.nscount) {	    fprintf(stderr, "*** Default servers are not available\n");	    exit(1);	}    }    strcpy(defaultServer, defaultPtr->name);#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);    } else {	PrintHostInfo(stdout, "Default Server:", defaultPtr);	pager = getenv("PAGER");	if (pager == NULL) {	    pager = _PATH_PAGERCMD;	}	/*	 * Setup the environment to allow the interrupt handler to return here.	 */	(void) setjmp(env);	/* 	 * Return here after a longjmp.	 */	signal(SIGINT, IntrHandler);	signal(SIGPIPE, SIG_IGN);	/*	 * Read and evaluate commands. The commands are described in commands.l	 * Yylex returns 0 when ^D or 'exit' is typed. 	 */	printf("> ");	fflush(stdout);	while(yylex()) {	    printf("> ");	    fflush(stdout);	}    }    exit(0);}LocalServer(defaultPtr)    HostInfo *defaultPtr;{    char	hostName[NAME_LEN];    (void) gethostname(hostName, sizeof(hostName));    defaultAddr.s_addr = htonl(INADDR_ANY);    (void) GetHostInfoByName(&defaultAddr, C_IN, T_A,			     "0.0.0.0", defaultPtr, 1);    free(defaultPtr->name);    defaultPtr->name = Calloc(1, sizeof(hostName)+1);    strcpy(defaultPtr->name, hostName);}/* ****************************************************************************** * *  Usage -- * *	Lists the proper methods to run the program and exits. * ****************************************************************************** */Usage(){    fprintf(stderr, "Usage:\n");    fprintf(stderr,"   nslookup [-opt ...]             # interactive mode using default server\n");    fprintf(stderr,"   nslookup [-opt ...] - server    # interactive mode using 'server'\n");    fprintf(stderr,"   nslookup [-opt ...] host        # just look up 'host' using default server\n");    fprintf(stderr,"   nslookup [-opt ...] host server # just look up 'host' using 'server'\n");    exit(1);}/* ****************************************************************************** * * IsAddr -- * *	Returns TRUE if the string looks like an Internet address. *	A string with a trailing dot is not an address, even if it looks *	like one. * ****************************************************************************** */BooleanIsAddr(host, addrPtr)    char *host;    struct in_addr *addrPtr;	/* If return TRUE, contains IP address */{    register char *cp;    if (isdigit(host[0])) {	    /* Make sure it has only digits and dots. */	    for (cp = host; *cp; ++cp) {		if (!isdigit(*cp) && *cp != '.') 		    return FALSE;	    }	    /* If it has a trailing dot, don't treat it as an address. */	    if (*--cp != '.') { 		return inet_aton(host, addrPtr);	    }    }    return FALSE;}/* ****************************************************************************** * *  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;    Boolean	local;{    register HostInfo	*newDefPtr;    struct in_addr	*servAddrPtr;    struct in_addr	addr;    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.     *     *  Check to see if we have the address of the server or the     *  address of a server who knows about this domain.     *  XXX For now, just use the first address in the list.     */    if (local) {	servAddrPtr = &defaultAddr;    } else if (defaultPtr->addrList != NULL) {	servAddrPtr = (struct in_addr *) defaultPtr->addrList[0];    } else {	servAddrPtr = (struct in_addr *) defaultPtr->servers[0]->addrList[0];    }    result = ERROR;    if (IsAddr(newServer, &addr)) {	result = GetHostInfoByAddr(servAddrPtr, &addr, newDefPtr);	/* If we can't get the name, fall through... */    }     if (result != SUCCESS && result != NONAUTH) {	result = GetHostInfoByName(servAddrPtr, 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);    }}/* ****************************************************************************** * * DoLoookup -- * *	Common subroutine for LookupHost and LookupHostWithServer. * *  Results: *	SUCCESS		- the lookup was successful. *	Misc. Errors	- an error message is printed if the lookup failed. * ****************************************************************************** */static intDoLookup(host, servPtr, serverName)    char	*host;    HostInfo	*servPtr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -