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

📄 db_load.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#if !defined(lint) && !defined(SABER)static char sccsid[] = "@(#)db_load.c	4.38 (Berkeley) 3/2/91";static char rcsid[] = "$Id: db_load.c,v 4.9.1.5 1993/12/06 00:43:02 vixie Exp $";#endif /* not lint *//* * ++Copyright++ 1986, 1988, 1990 * - * Copyright (c) 1986, 1988, 1990 *    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-- *//* * Load data base from ascii backupfile.  Format similar to RFC 883. */#include <sys/param.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <arpa/inet.h>#include <stdio.h>#include <syslog.h>#include <ctype.h>#include <netdb.h>#include "named.h"static int		gettoken __P((register FILE *, char *)),			getnum __P((FILE *, char *, int)),			getnonblank __P((FILE *, char *)),			getprotocol __P((FILE *, char *)),			getservices __P((int, char *, FILE *, char *));static void		makename __P((char *, char *));static int		empty_token = 0;/* * Map class and type names to number */struct map {	char	token[8];	int	val;};struct map m_class[] = {	"in",		C_IN,#ifdef notdef	"any",		C_ANY,		/* any is a QCLASS, not CLASS */#endif	"chaos",	C_CHAOS,	"hs",		C_HS,};#define NCLASS (sizeof(m_class) / sizeof(struct map))struct map m_type[] = {	"a",		T_A,	"ns",		T_NS,	"cname",	T_CNAME,	"soa",		T_SOA,	"mb",		T_MB,	"mg",		T_MG,	"mr",		T_MR,	"null",		T_NULL,	"wks",		T_WKS,	"ptr",		T_PTR,	"hinfo",	T_HINFO,	"minfo",	T_MINFO,	"mx",		T_MX,	"uinfo",	T_UINFO,	"txt",		T_TXT,	"rp",		T_RP,	"afsdb",	T_AFSDB,	"uid",		T_UID,	"gid",		T_GID,#ifdef notdef	"any",		T_ANY,		/* any is a QTYPE, not TYPE */#endif#ifdef ALLOW_T_UNSPEC        "unspec",       T_UNSPEC,#endif /* ALLOW_T_UNSPEC */};#define NTYPE (sizeof(m_type) / sizeof(struct map))/* * Parser token values */#define CURRENT	1#define DOT	2#define AT	3#define DNAME	4#define INCLUDE	5#define ORIGIN	6#define ERROR	7static int clev;	/* a zone deeper in a heirachy has more credability *//* int * db_load(filename, in_origin, zp, doinginclude) *	load a database from `filename' into zone `zp'.  append `origin' *	to all nonterminal domain names in the file.  `doinginclude' is *	true if this is a $INCLUDE file. * returns: *	-1 = can't open file *	0 = success *	>0 = number of errors encountered */intdb_load(filename, in_origin, zp, doinginclude)	char *filename, *in_origin;	struct zoneinfo *zp;	int doinginclude;{	register char *cp;	register struct map *mp;	char domain[MAXDNAME];	char origin[MAXDNAME];	char tmporigin[MAXDNAME];	char buf[MAXDATA];	char data[MAXDATA];	char *cp1;	char *op;	int c, class, type, ttl, dbflags, dataflags, multiline;	static int read_soa;	/* number of soa's read */	struct databuf *dp;	FILE *fp;	int slineno, i, errs = 0, didinclude = 0;	register u_int32_t n;	struct stat sb;	struct in_addr ina;#ifdef SECURE_ZONES	extern int build_secure_netlist();#endif	if (!doinginclude) {	    read_soa = 0;	    clev = db_getclev(in_origin);	}	dprintf(1, (ddt,"db_load(%s, %s, %d, %d)\n",		    filename, in_origin, zp - zones, doinginclude));	(void) strcpy(origin, in_origin);	if ((fp = fopen(filename, "r")) == NULL) {		syslog(LOG_ERR, "%s: %m", filename);		dprintf(1, (ddt, "db_load: error opening file %s\n",			    filename));		return (-1);	}	if (zp->z_type == Z_CACHE) {		dbflags = DB_NODATA | DB_NOHINTS;		dataflags = DB_F_HINT;	} else {		dbflags = DB_NODATA;		dataflags = 0;	}	gettime(&tt);	if (fstat(fileno(fp), &sb) < 0) {		syslog(LOG_ERR, "%s: %m", filename);		sb.st_mtime = (int)tt.tv_sec;	}	slineno = lineno;	lineno = 1;	domain[0] = '\0';	class = zp->z_class;	zp->z_state &= ~(Z_INCLUDE|Z_DB_BAD); 	while ((c = gettoken(fp, filename)) != EOF) {		switch (c) {		case INCLUDE:			if (!getword((char *)buf, sizeof(buf), fp))				/* file name*/				break;			if (!getword(tmporigin, sizeof(tmporigin), fp))				strcpy(tmporigin, origin);			else {				makename(tmporigin, origin);				endline(fp);			}			didinclude = 1;			errs += db_load((char *)buf, tmporigin, zp, 1);			continue;		case ORIGIN:			(void) strcpy((char *)buf, origin);			if (!getword(origin, sizeof(origin), fp))				break;			dprintf(3, (ddt, "db_load: origin %s, buf %s\n",				    origin, buf));			makename(origin, buf);			dprintf(3, (ddt, "db_load: origin now %s\n", origin));			continue;		case DNAME:			if (!getword(domain, sizeof(domain), fp))				break;			n = strlen(domain) - 1;			if (domain[n] == '.')				domain[n] = '\0';			else if (*origin) {				(void) strcat(domain, ".");				(void) strcat(domain, origin);			}			goto gotdomain;		case AT:			(void) strcpy(domain, origin);			goto gotdomain;		case DOT:			domain[0] = '\0';			/* fall thru ... */		case CURRENT:		gotdomain:			if (!getword((char *)buf, sizeof(buf), fp)) {				if (c == CURRENT)					continue;				break;			}			cp = buf;			ttl = 0;			if (isdigit(*cp)) {				n = 0;				do					n = n * 10 + (*cp++ - '0');				while (isdigit(*cp));				if (zp->z_type == Z_CACHE) {				    /* this allows the cache entry to age */				    /* while sitting on disk (powered off) */				    if (n > max_cache_ttl)					n = max_cache_ttl;				    n += sb.st_mtime;				}				ttl = n;				if (!getword((char *)buf, sizeof(buf), fp))					break;			}			for (mp = m_class; mp < m_class+NCLASS; mp++)				if (!strcasecmp((char *)buf, mp->token)) {					class = mp->val;					(void) getword((char *)buf,						       sizeof(buf), fp);					break;				}			for (mp = m_type; mp < m_type+NTYPE; mp++)				if (!strcasecmp((char *)buf, mp->token)) {					type = mp->val;					goto fndtype;				}			dprintf(1, (ddt, "Line %d: Unknown type: %s.\n",				    lineno, buf));			errs++; 			syslog(LOG_ERR, "Line %d: Unknown type: %s.\n",				lineno, buf);			break;		fndtype:#ifdef ALLOW_T_UNSPEC			/* Don't do anything here for T_UNSPEC...			 * read input separately later			 */                        if (type != T_UNSPEC) {#endif			    if (!getword((char *)buf, sizeof(buf), fp))				break;			    dprintf(3,				    (ddt,				     "d='%s', c=%d, t=%d, ttl=%d, data='%s'\n",				     domain, class, type, ttl, buf));#ifdef ALLOW_T_UNSPEC                        }#endif			/*			 * Convert the ascii data 'buf' to the proper format			 * based on the type and pack into 'data'.			 */			switch (type) {			case T_A:				if (!inet_aton(buf, &ina))					goto err;				n = ntohl(ina.s_addr);				cp = data;				PUTLONG(n, cp);				n = sizeof(u_int32_t);				break;			case T_HINFO:				n = strlen((char *)buf);				if (n > 255) {				    syslog(LOG_WARNING,					"%s: line %d: CPU type too long",					filename, lineno);				    n = 255;				}				data[0] = n;				bcopy(buf, (char *)data + 1, (int)n);				n++;				if (!getword((char *)buf, sizeof(buf), fp))					break;				i = strlen((char *)buf);				if (i > 255) {				    syslog(LOG_WARNING,					   "%s:%d: OS type too long",					   filename, lineno);				    i = 255;				}				data[n] = i;				bcopy(buf, data + n + 1, i);				n += i + 1;				endline(fp);				break;			case T_SOA:			case T_MINFO:			case T_RP:				(void) strcpy((char *)data, (char *)buf);				makename(data, origin);				cp = data + strlen((char *)data) + 1;				if (!getword((char *)cp,					     sizeof(data) - (cp - data), fp)) {					n = cp - data;					break;				}				makename(cp, origin);				cp += strlen((char *)cp) + 1;				if (type != T_SOA) {					n = cp - data;					break;				}				if (class != zp->z_class) {					syslog(LOG_WARNING,					       "%s:%d: %s",					       filename, lineno,					       "SOA class not same as zone's");				}				c = getnonblank(fp, filename);				if (c == '(') {					multiline = 1;				} else {					multiline = 0;					ungetc(c, fp);				}				zp->z_serial = getnum(fp, filename, 1);				n = (u_int32_t) zp->z_serial;				PUTLONG(n, cp);				zp->z_refresh = getnum(fp, filename, 0);				n = (u_int32_t) zp->z_refresh;				PUTLONG(n, cp);				if (zp->z_type == Z_SECONDARY#if defined(STUBS) 				    || zp->z_type == Z_STUB#endif				    ) {					zp->z_time = sb.st_mtime						   + zp->z_refresh;				}				zp->z_retry = getnum(fp, filename, 0);				n = (u_int32_t) zp->z_retry;				PUTLONG(n, cp);				zp->z_expire = getnum(fp, filename, 0);				n = (u_int32_t) zp->z_expire;				PUTLONG (n, cp);				zp->z_minimum = getnum(fp, filename, 0);				n = (u_int32_t) zp->z_minimum;				PUTLONG (n, cp);				n = cp - data;				if (multiline) {					if (getnonblank(fp, filename) != ')')						goto err;				}                                read_soa++;				endline(fp);				break;			case T_UID:			case T_GID:				n = 0;				cp = buf;				while (isdigit(*cp))					n = n * 10 + (*cp++ - '0');				if (cp == buf)					goto err;				cp = data;				PUTLONG(n, cp);				n = sizeof(u_int32_t);				break;			case T_WKS:				/* Address */				if (!inet_aton(buf, &ina))					goto err;				n = ntohl(ina.s_addr);				cp = data;				PUTLONG(n, cp);				*cp = (char)getprotocol(fp, filename);				/* Protocol */				n = sizeof(u_int32_t) + sizeof(char);				/* Services */				n = getservices((int)n, data, fp, filename);				break;			case T_NS:			case T_CNAME:			case T_MB:			case T_MG:			case T_MR:			case T_PTR:				(void) strcpy((char *)data, (char *)buf);				makename(data, origin);				n = strlen((char *)data) + 1;				break;			case T_UINFO:				cp = strchr((char *)buf, '&');				bzero(data, sizeof(data));				if ( cp != NULL) {					(void) strncpy((char *)data,					    (char *)buf, cp - buf);					op = strchr(domain, '.');					if ( op != NULL)					    (void) strncat((char *)data,						domain,op-domain);					else						(void) strcat((char *)data,						    domain);					(void) strcat((char *)data,					    (char *)++cp);				} else					(void) strcpy((char *)data,					    (char *)buf);				n = strlen((char *)data) + 1;				break;			case T_MX:			case T_AFSDB:				n = 0;				cp = buf;				while (isdigit(*cp))					n = n * 10 + (*cp++ - '0');				/* catch bad values */				if ((cp == buf) || (n > 65535))					goto err;				cp = data;				PUTSHORT((u_int16_t)n, cp);				if (!getword((char *)buf, sizeof(buf), fp))					    break;				(void) strcpy((char *)cp, (char *)buf);				makename(cp, origin);				/* get pointer to place in data */				cp += strlen((char *)cp) +1;				/* now save length */				n = (cp - data);				break;			case T_TXT:				i = strlen((char *)buf);				cp = data;				cp1 = buf;				/*				 * there is expansion here so make sure we				 * don't overflow data				 */				if (i > sizeof(data) * 255 / 256) {				    syslog(LOG_WARNING,					"%s: line %d: TXT record truncated",					filename, lineno);				    i = sizeof(data) * 255 / 256;				}				while (i > 255) {				    *cp++ = 255;				    bcopy(cp1, cp, 255);				    cp += 255;				    cp1 += 255;				    i -= 255;				}				*cp++ = i;				bcopy(cp1, cp, i);				cp += i;				n = cp - data;				endline(fp);				break;#ifdef ALLOW_T_UNSPEC                        case T_UNSPEC:                                {                                    int rcode;                                    fgets(buf, sizeof(buf), fp);				    dprintf(1, (ddt, "loading T_UNSPEC\n"));				    if (rcode = atob(buf,						     strlen((char*)buf),						     data, sizeof(data),						     &n)) {					if (rcode == CONV_OVERFLOW) {						dprintf(1,							(ddt,				       "Load T_UNSPEC: input buffer overflow\n"							 )							);						errs++;						syslog(LOG_ERR,				       "Load T_UNSPEC: input buffer overflow");					} else {						dprintf(1,							(ddt,				     "Load T_UNSPEC: Data in bad atob format\n"							 )							);						errs++;						syslog(LOG_ERR,				     "Load T_UNSPEC: Data in bad atob format");					}                                    }                                }                                break;#endif /* ALLOW_T_UNSPEC */			default:				goto err;			}#ifdef STUBS			if (type == T_SOA && zp->z_type == Z_STUB)				continue;#endif			dp = savedata(class, type, (u_int32_t)ttl,				(u_char *)data, (int)n);			dp->d_zone = zp - zones;			dp->d_flags = dataflags;

⌨️ 快捷键说明

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