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

📄 info_hes.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry at Imperial College, London. * * 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. * *	@(#)info_hes.c	8.1 (Berkeley) 6/6/93 * * $Id: info_hes.c,v 5.2.2.1 1992/02/09 15:08:29 jsp beta $ * *//* * Get info from Hesiod * * Zone transfer code from Bruce Cole <cole@cs.wisc.edu> */#include "am.h"#ifdef HAS_HESIOD_MAPS#include <hesiod.h>#define	HES_PREFIX	"hesiod."#define	HES_PREFLEN	7#ifdef HAS_HESIOD_RELOAD#include <arpa/nameser.h>#include <resolv.h>#include <sys/uio.h>#include <netdb.h>/* * Patch up broken system include files */#ifndef C_HS#define C_HS	4#endif#ifndef T_TXT#define	T_TXT	16#endifstatic int soacnt;static struct timeval hs_timeout;static int servernum;#endif /* HAS_HESIOD_RELOAD *//* * No easy way to probe the server - check the map name begins with "hesiod." */int hesiod_init P((char *map, time_t *tp));int hesiod_init(map, tp)char *map;time_t *tp;{#ifdef DEBUG	dlog("hesiod_init(%s)", map);#endif	*tp = 0;	return strncmp(map, HES_PREFIX, HES_PREFLEN) == 0 ? 0 : ENOENT;}/* * Make Hesiod name.  Skip past the "hesiod." * at the start of the map name and append * ".automount".  The net effect is that a lookup * of /defaults in hesiod.home will result in a * call to hes_resolve("/defaults", "home.automount"); */#ifdef notdef#define MAKE_HES_NAME(dest, src) sprintf(dest, "%s%s", src + HES_PREFLEN, ".automount")#endif/* * Do a Hesiod nameserver call. * Modify time is ignored by Hesiod - XXX */int hesiod_search P((mnt_map *m, char *map, char **pval, time_t *tp));int hesiod_search(m, map, key, pval, tp)mnt_map *m;char *map;char *key;char **pval;time_t *tp;{	int error;	char hes_key[MAXPATHLEN];	char **rvec;#ifdef DEBUG	dlog("hesiod_search(m=%x, map=%s, key=%s, pval=%x tp=%x)", m, map, key, pval, tp);#endif	/*MAKE_HES_NAME(hes_map, map);*/	sprintf(hes_key, "%s.%s", key, map+HES_PREFLEN);	/*	 * Call the resolver	 */#ifdef DEBUG	dlog("hesiod_search: hes_resolve(%s, %s)", hes_key, "automount");#ifdef HAS_HESIOD_RELOAD	if (debug_flags & D_FULL)		_res.options |= RES_DEBUG;#endif#endif	rvec = hes_resolve(hes_key, "automount");	/*	 * If a reply was forthcoming then return	 * it (and free subsequent replies)	 */	if (rvec && *rvec) {		*pval = *rvec;		while (*++rvec)			free(*rvec);		return 0;	}	/*	 * Otherwise reflect the hesiod error into a Un*x error	 */#ifdef DEBUG	dlog("hesiod_search: Error: %d", hes_error());#endif	switch (hes_error()) {	case HES_ER_NOTFOUND:	error = ENOENT; break;	case HES_ER_CONFIG:	error = EIO; break;	case HES_ER_NET:	error = ETIMEDOUT; break;	default:		error = EINVAL; break;	}#ifdef DEBUG	dlog("hesiod_search: Returning: %d", error);#endif	return error;}#ifdef HAS_HESIOD_RELOAD/* * Zone transfer... */#define MAXHSNS 8#define MAX_NSADDR 16static char *hs_domain;static mnt_map *hs_map;static int hs_nscount;static char nsaddr_list[MAX_NSADDR][sizeof(struct in_addr)];int hesiod_reload P((mnt_map *m, char *map, void (*fn)()));int hesiod_reload(m, map, fn)mnt_map *m;char *map;void (*fn)();{	char *zone_name, *cp;	short domainlen;	int status;#ifdef DEBUG	dlog("hesiod_reload (%x %s %x)", m, map, fn);#endif DEBUG	if (status = res_init()) {#ifdef DEBUG		dlog("hesiod_reload: res_init failed with %d", status);#endif		return(status);	}	_res.retrans = 90;	hs_map = m;	domainlen = strlen(hostdomain);	zone_name = hes_to_bind(map+HES_PREFLEN, "automount");	if (*zone_name == '.')		zone_name++;	hs_domain = zone_name;	/* Traverse the DNS tree until we find an SOA we can transfer from.	 (Our initial zone_name is likely to just be a subtree of a	 real zone). */	do {		/* If we can't find any NS records, go up a level in the		   DNS tree */		if (hs_get_ns_list(zone_name) == 0 &&		    hs_zone_transfer(zone_name) == 0)			return(0);		/* Move up DNS tree by one component */		if (cp = strchr(zone_name, '.'))			zone_name = ++cp;		else			break;	} while (strlen(zone_name) >= domainlen);#ifdef DEBUG	dlog("hesiod_reload: Giving up on %s", hs_domain);#endif	return(-1);}hs_zone_transfer(domain)char *domain;{	int status, len;	char buf[PACKETSZ];	/* Want to make sure ansbuf is well alligned */	long ansbuf[PACKETSZ/sizeof(long)];#ifdef DEBUG	dlog("hs_zone_transfer (%s)", domain);#endif	if ((len = res_mkquery(QUERY, domain, C_HS, T_AXFR,			       (char *)NULL, 0, NULL, buf, PACKETSZ)) == -1) {#ifdef DEBUG		dlog("hs_zone_transfer: res_mkquery failed");#endif		errno = 0;		return(-1);	}	if ((status = hs_res_send(buf, len, (char *)ansbuf, PACKETSZ)) == -1) {#ifdef DEBUG	    dlog("hs_zone_transfer: hs_res_send failed.  status %d errno %d",		 status, errno);#endif		errno = 0;		return(-1);	}	return(0);}#define hs_server_addr(ns) ((struct in_addr *) nsaddr_list[ns])hs_res_send(buf, buflen, answer, anslen)char *buf;int buflen;char *answer;int anslen;{	int retry, ns;	u_short id, len;	HEADER *hp = (HEADER *) buf;	struct iovec iov[2];	static int s = -1;	int status;	struct sockaddr_in server;	soacnt = 0;	id = hp->id;	/*	 * Send request, RETRY times, or until successful	 */	for (retry = _res.retry; retry > 0; retry--) {		for (ns = 0; ns < hs_nscount; ns++) {			hs_timeout.tv_sec =				(_res.retrans << (_res.retry - retry))				/ hs_nscount;			if (hs_timeout.tv_sec <= 0)				hs_timeout.tv_sec = 1;			hs_timeout.tv_usec = 0;			if (s < 0) {				s = socket(AF_INET, SOCK_STREAM, 0);				if (s < 0) {					continue;				}				servernum = ns;				bcopy(hs_server_addr(ns), &server.sin_addr,				      sizeof(struct in_addr));				server.sin_family = AF_INET;				server.sin_port = htons(NAMESERVER_PORT);									if (connect(s, &server,					    sizeof(struct sockaddr)) < 0) {					(void) close(s);					s = -1;					continue;				}			}			/*			 * Send length & message			 */			len = htons((u_short)buflen);			iov[0].iov_base = (caddr_t)&len;			iov[0].iov_len = sizeof(len);			iov[1].iov_base = buf;			iov[1].iov_len = buflen;			if (writev(s, iov, 2) != sizeof(len) + buflen) {				(void) close(s);				s = -1;				continue;			}			status = 0;			while (s != -1 && soacnt < 2 && status != -2) {				if ((status =				     hs_readresp(s, answer, anslen)) == -1) {					(void) close(s);					s = -1;					continue;				}			}			if (status == -2) {				/* There was a permanent error transfering this				   zone.  Give up. */				if (s != -1) {					(void) close(s);					s = -1;				}				return(-1);			}			if (s == -1)				continue;			return (0);		}	}	if (errno == 0)		errno = ETIMEDOUT;	return (-1);}/* Returns:   0: Success   -1: Error   -2: Permanent failure*/

⌨️ 快捷键说明

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