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

📄 host.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* return overall result */	return(excode);}/*** PROCESS_NAME -- Process a single command line argument** ------------------------------------------------------****	Returns:**		EX_OK if information was obtained successfully.**		Appropriate exit code otherwise.****	Wrapper for execute_name() to hide administrative tasks.*/intprocess_name(name)input char *name;			/* command line argument */{	int result;			/* result status of action taken */	static int save_querytype;	static bool save_reverse;	static bool firstname = TRUE;	/* separate subsequent pieces of output */	if (!firstname && (verbose || debug || checkmode))		printf("\n");/* * Some global variables are redefined further on. Save their initial * values in the first pass, and restore them during subsequent passes. */	if (firstname)	{		save_querytype = querytype;		save_reverse = reverse;		firstname = FALSE;	}	else	{		querytype = save_querytype;		reverse = save_reverse;	}/* * Do the real work. */	result = execute_name(name);	return(result);}/*** EXECUTE_NAME -- Process a single command line argument** ------------------------------------------------------****	Returns:**		EX_OK if information was obtained successfully.**		Appropriate exit code otherwise.****	Outputs:**		Defines queryname appropriately.****	Side effects:**		May redefine querytype and reverse if necessary.*/intexecute_name(name)input char *name;			/* command line argument */{	ipaddr_t addr;			/* explicit address of query */	bool result;			/* result status of action taken */	/* check for nonsense input name */	if (strlength(name) > MAXDNAME)	{		errmsg("Query name %s too long", name);		return(EX_USAGE);	}/* * Analyze name and type to be queried about. * In regular mode, the querytype is used to formulate the nameserver * query, and any response is filtered out when processing the answer. * In listmode, the querytype is used to filter out the proper records. */	queryname = name;	if (queryname[0] == '\0')		queryname = ".";	if (sameword(queryname, "."))		addr = NOT_DOTTED_QUAD;	else		addr = inet_addr(queryname);	/* invert dotted quad if so requested */	if ((addr != NOT_DOTTED_QUAD) && reverse)	{		queryname = in_addr_arpa(queryname);		if (queryname == NULL)		{			errmsg("Invalid dotted quad %s", name);			return(EX_USAGE);		}		addr = NOT_DOTTED_QUAD;	}	else		reverse = FALSE;	/* set querytype for regular mode if unspecified */	if ((querytype == T_NONE) && !listmode)	{		if ((addr != NOT_DOTTED_QUAD) || reverse)			querytype = T_PTR;		else			querytype = T_A;	}	/* cannot have dotted quad in listmode */	if (listmode && (addr != NOT_DOTTED_QUAD))	{		errmsg("Invalid query name %s", queryname);		return(EX_USAGE);	}	/* must have regular name or dotted quad in addrmode */	if (addrmode && reverse)	{		errmsg("Invalid query name %s", queryname);		return(EX_USAGE);	}	/* show what we are going to query about */	if (verbose)		show_types(queryname, querytype, queryclass);/* * All set. Perform requested function. */	result = execute(addr);	return(result ? EX_OK : EX_UNAVAILABLE);}/*** EXECUTE -- Perform the requested function** -----------------------------------------****	Returns:**		TRUE if information was obtained successfully.**		FALSE otherwise.****	The whole environment has been set up and checked.*/boolexecute(addr)input ipaddr_t addr;			/* explicit address of query */{	struct hostent *hp;	char newnamebuf[MAXDNAME+1];	char *newname = NULL;		/* name to which CNAME is aliased */	int ncnames = 0;		/* count of CNAMEs in chain */	bool result;			/* result status of action taken *//* * Special mode to check reverse mappings of host addresses. */	if (addrmode)	{		if (addr == NOT_DOTTED_QUAD)			result = check_addr(queryname);		else			result = check_name(addr);		return(result);	}/* * Special mode to list contents of specified zone. */	if (listmode)	{		result = list_zone(queryname);		return(result);	}/* * Regular mode to query about specified host. */	result = FALSE;	h_errno = TRY_AGAIN;	/* retry until positive result or permanent failure */	while (result == FALSE && h_errno == TRY_AGAIN)	{		/* reset before each query */		realname = NULL;		if (addr == NOT_DOTTED_QUAD)		{			/* reset CNAME indicator */			cname = NULL;			/* lookup the name in question */			if (newname == NULL)				result = get_hostinfo(queryname);			else				result = get_hostinfo(newname);			/* recurse on CNAMEs, but not too deep */			if (cname && (querytype != T_CNAME))			{				newname = strcpy(newnamebuf, cname);				if (++ncnames > 5)				{					errmsg("Possible CNAME loop");					return(FALSE);				}				result = FALSE;				h_errno = TRY_AGAIN;				continue;			}		}		else		{			hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);			if (hp != NULL)			{				print_host("Name", hp);				result = TRUE;			}		}		/* only retry if so requested */		if (!waitmode)			break;	}	/* use actual name if available */	if (realname != NULL)		queryname = realname;	/* explain the reason of a failure */	if (result == FALSE)		ns_error(queryname, querytype, queryclass);	return(result);}/*** SET_SERVER -- Override default nameserver with explicit server** --------------------------------------------------------------****	Returns:**		None.**		Aborts the program if an unknown host was given.****	Side effects:**		The global variable server is set to indicate**		that an explicit server is being used.****	The default nameserver addresses in the resolver database**	which are initialized by res_init() from /etc/resolv.conf**	are replaced with the (possibly multiple) addresses of an**	explicitly named server host. If a dotted quad is given,**	only that single address will be used.*/voidset_server(name)input char *name;			/* name of server to be queried */{	register int i;	struct hostent *hp;	struct in_addr inaddr;	ipaddr_t addr;			/* explicit address of server */	/* check for nonsense input name */	if (strlength(name) > MAXDNAME)	{		errmsg("Server name %s too long", name);		exit(EX_USAGE);	}	addr = inet_addr(name);	inaddr.s_addr = addr;	if (addr == NOT_DOTTED_QUAD)	{		/* lookup all of its addresses; this must not fail */		hp = gethostbyname(name);		if (hp == NULL)		{			ns_error(name, T_A, C_IN);			errmsg("Error in looking up server name");			exit(EX_NOHOST);		}		for (i = 0; i < MAXNS && hp->h_addr_list[i]; i++)		{			nslist(i).sin_family = AF_INET;			nslist(i).sin_port = htons(NAMESERVER_PORT);			nslist(i).sin_addr = incopy(hp->h_addr_list[i]);		}		_res.nscount = i;	}	else	{		/* lookup the name, but use only the given address */		hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);		nslist(0).sin_family = AF_INET;		nslist(0).sin_port = htons(NAMESERVER_PORT);		nslist(0).sin_addr = inaddr;		_res.nscount = 1;	}	if (hp != NULL)	{		server = strcpy(serverbuf, hp->h_name);		print_host("Server", hp);	}	else	{		server = strcpy(serverbuf, inet_ntoa(inaddr));		printf("Server: %s\n\n", server);	}}/*** FATAL -- Abort program when illegal option encountered** ------------------------------------------------------****	Returns:**		Aborts after issuing error message.*/void /*VARARGS1*/fatal(fmt, a, b, c, d)input char *fmt;			/* format of message */input char *a, *b, *c, *d;		/* optional arguments */{	(void) fprintf(stderr, fmt, a, b, c, d);	(void) fprintf(stderr, "\n");	exit(EX_USAGE);}/*** ERRMSG -- Issue error message to error output** ---------------------------------------------****	Returns:**		None.****	Side effects:**		Increments the global error count.*/void /*VARARGS1*/errmsg(fmt, a, b, c, d)input char *fmt;			/* format of message */input char *a, *b, *c, *d;		/* optional arguments */{	(void) fprintf(stderr, fmt, a, b, c, d);	(void) fprintf(stderr, "\n");	/* flag an error */	Errors++;}/*** GET_HOSTINFO -- Principal routine to query about given name** -----------------------------------------------------------****	Returns:**		TRUE if requested info was obtained successfully.**		FALSE otherwise.****	This is the equivalent of the resolver module res_search().****	In this program RES_DEFNAMES is always on, and RES_DNSRCH**	is off by default. This means that single names without dot**	are always, and only, tried within the own default domain,**	and compound names are assumed to be already fully qualified.****	The default BIND behaviour can be simulated by turning on**	RES_DNSRCH with -R. The given name, whether or not compound,**	is then	first tried within the possible search domains.****	Note. In the latter case, the search terminates in case the**	specified name exists but does not have the desired type.**	The BIND behaviour is to continue the search. This can be**	simulated with the undocumented option -B.*/boolget_hostinfo(name)input char *name;			/* name to query about */{	register char **domain;	register char *cp;	int dot;			/* number of dots in query name */	bool result;			/* result status of action taken */	char oldnamebuf[2*MAXDNAME+2];	char *oldname;			/* saved actual name when NO_DATA */	int nodata = 0;			/* NO_DATA status during DNSRCH */	int nquery = 0;			/* number of extra search queries *//* * Single dot means root zone. */	if (sameword(name, "."))	{		result = get_domaininfo(name, (char *)NULL);		return(result);	}/* * Count number of dots. Move to the end of the name. */	for (dot = 0, cp = name; *cp != '\0'; cp++)		if (*cp == '.')			dot++;/* * Check for aliases of single name. * Note that the alias is supposed to be fully qualified. */	if (dot == 0 && (cp = hostalias(name)) != NULL)	{		if (verbose)			printf("Aliased to \"%s\"\n", cp);		result = get_domaininfo(cp, (char *)NULL);		return(result);	}/* * Trailing dot means absolute (fully qualified) address. */	if (dot != 0 && cp[-1] == '.')	{		cp[-1] = '\0';		result = get_domaininfo(name, (char *)NULL);		cp[-1] = '.';		return(result);	}/* * Append own default domain and other search domains if appropriate. */	if ((dot == 0 && bitset(RES_DEFNAMES, _res.options)) ||	    (dot != 0 && bitset(RES_DNSRCH, _res.options)))	{		for (domain = _res.dnsrch; *domain; domain++)		{			result = get_domaininfo(name, *domain);			if (result)				return(result);			/* keep count of extra search queries */			nquery++;			/* in case nameserver not present */			if (errno == ECONNREFUSED)				return(FALSE);			/* if no further search desired (single name) */	    		if (!bitset(RES_DNSRCH, _res.options))				break;			/* if name exists but has not requested type */			if (h_errno == NO_DATA || h_errno == NO_RREC)			{				if (bindcompat)				{					/* remember status and search up */					oldname = strcpy(oldnamebuf, realname);					nodata = h_errno;					continue;				}				return(FALSE);			}			/* retry only if name does not exist at all */			if (h_errno != HOST_NOT_FOUND && h_errno != NO_HOST)				break;		}	}/* * Single name lookup failed. */	if (dot == 0)	{		/* unclear what actual name should be */		if (nquery != 1)			realname = NULL;		/* restore nodata status from search */		if (bindcompat && nodata)		{			realname = strcpy(realnamebuf, oldname);			h_errno = nodata;		}		/* set status in case we never queried */		if (!bitset(RES_DEFNAMES, _res.options))			h_errno = HOST_NOT_FOUND;		return(FALSE);	}

⌨️ 快捷键说明

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