db_load.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,648 行 · 第 1/3 页

C
1,648
字号
				if (!getword(cp, sizeof(data) - (cp - data),fp)) {					n = cp - data;					break;				}				makename(cp, origin);				cp += strlen(cp) + 1;				if (type == T_MINFO) {					n = cp - data;					break;				}				if (getnonblank(fp) != '(')					goto format_err;				zp->z_serial = getnum(fp);				n = (u_long) zp->z_serial;				PUTLONG(n, cp);				zp->z_refresh = getnum(fp);				n = (u_long) zp->z_refresh;				PUTLONG(n, cp);				/* A primary assumes that the data in the				   file being loaded is correct now.  The				   modification time of the file is of no				   consequence.				*/#ifdef PRIMARY_MAINT				if(zp->z_type == Z_PRIMARY)					load_info->z_time = tt + zp->z_refresh;				else if(zp->type == Z_SECONDARY)#else PRIMARY_MAINT				if(zp->z_type == Z_SECONDARY)#endif PRIMARY_MAINT					zp->z_time =						load_info->files->						f_stats.st_mtime +						zp->z_refresh;				zp->z_retry = getnum(fp);				n = (u_long) zp->z_retry;				PUTLONG(n, cp)				zp->z_expire = getnum(fp);				n = (u_long) zp->z_expire;				PUTLONG (n, cp);				zp->z_minimum = getnum(fp);				n = (u_long) zp->z_minimum;				PUTLONG (n, cp);				n = cp - data;				if (getnonblank(fp) != ')')					goto format_err;				endline(fp);#ifdef ULTRIXFUNC				zp->z_class = class;#endif ULTRIXFUNC				break;			case T_UID:			case T_GID:				n = 0;				cp = buf;				while (isdigit(*cp))					n = n * 10 + (*cp++ - '0');				if (cp == buf)					goto format_err;				cp = data;				PUTLONG(n, cp);				n = sizeof(long);				break;			case T_WKS:				/* Address */				n = ntohl((u_long)inet_addr((char *)buf));				cp = data;				PUTLONG(n, cp);				*cp = getprotocol(fp, load_info->files->f_name);				/* Protocol */				n = sizeof(u_long) + sizeof(char);				/* Services */				n = getservices((int)n, data, fp,				    load_info->files->f_name);				break;			case T_NS:			case T_CNAME:			case T_MB:			case T_MG:			case T_MR:			case T_PTR:				(void) strcpy(data, buf);				makename(data, origin);				n = strlen(data) + 1;				break;			case T_UINFO:				cp = (u_char *)index(buf, '&');				bzero(data, sizeof(data));				if ( cp != NULL) {					(void) strncpy(data, buf, cp - buf);					op = index(domain, '.');					if ( op != NULL)					    (void) strncat(data,						domain,op-domain);					else						(void) strcat(data, domain);					(void) strcat(data, ++cp);				} else					(void) strcpy(data, buf);				n = strlen(data) + 1;				break;			case T_MX:				n = 0;				cp = buf;				while (isdigit(*cp))					n = n * 10 + (*cp++ - '0');				/* catch bad values */				if ((cp == buf) || (n > 64535))					goto format_err;				cp = data;				PUTSHORT((u_short)n, cp);				if (!getword(buf, sizeof(buf), fp))					    break;				(void) strcpy(cp,buf);				makename(cp, origin);				/* get pointer to place in data */				cp += strlen(cp) +1;				/* now save length */				n = (cp - data);				break;			case T_TXT:				i = strlen(buf);				n = 0;				tmpdata = &data[0];				tmpbuf = buf;				while (i > 255) {					*tmpdata++ = 255;					bcopy(tmpbuf, tmpdata, 255);					tmpdata += 255;					tmpbuf += 255;					i -= 255;					n += 256;				}				*tmpdata++ = i;				bcopy(tmpbuf, tmpdata, i);				n += i + 1;				break;#ifdef ALLOW_T_UNSPEC                        case T_UNSPEC:                                {                                    int rcode;                                    fgets(buf, sizeof(buf), fp);#ifdef DEBUG				    if (debug)                                    	fprintf(ddt, "loading T_UNSPEC\n");#endif DEBUG                                    if (rcode = atob(buf, strlen(buf), data,                                                         MAXDATA, &n)) {                                        if (rcode == CONV_OVERFLOW) {#ifdef DEBUG                                            if (debug)                                               fprintf(ddt,		       				   "Load T_UNSPEC: input buffer overflow\n");#endif DEBUG					    load_info->format_errs++;                                            syslog(LOG_ERR,						 "Load T_UNSPEC: input buffer overflow");                                         } else {#ifdef DEBUG                                            if (debug)                                                fprintf(ddt,						   "Load T_UNSPEC: Data in bad atob format\n");#endif DEBUG					    load_info->format_errs++;                                            syslog(LOG_ERR,						   "Load T_UNSPEC: Data in bad atob format");                                         }                                    }                                }                                break;#endif ALLOW_T_UNSPEC			default:				goto format_err;			}#ifdef AUTHEN			dp = savedata(class, type, (u_long)ttl, AUTH_CACHE,				      ONE, data, (int)n);#else AUTHEN			dp = savedata(class, type, (u_long)ttl, data, (int)n);#endif AUTHEN			dp->d_zone = load_info->zonenum;			dp->d_flags = load_info ->dataflags;			if ((c = db_update(domain, dp, dp, load_info->dbflags			   | DB_LOADDB,			   (zp->z_type == Z_CACHE)? fcachetab : hashtab)) < 0) {#ifdef DEBUG				if (debug && (c != DATAEXISTS))					fprintf(ddt,"update failed\n");#endif				free( (struct databuf *) dp);			}			continue;		case ERROR:			break;		}	format_err:		load_info->format_errs++;		syslog(LOG_ERR, "%s: line %d: database format error (%s)",			load_info->files->f_name, lineno, buf);#ifdef DEBUG		if (debug)			fprintf(ddt,"%s: line %d: database format error ('%s', %d)\n",				load_info->files->f_name, lineno, buf, n);#endif		while ((c = getc(fp)) != EOF && c != '\n')			;		if (c == '\n')			lineno++;	}err:	if(errs < -2) {		/* the load encountered an error */		if(load_info->next != NULL) {			free(load_info->next);			load_info->next = NULL;		}		if(load_info->fp)			fclose(load_info->fp);		return(errs);	}		if(c != EOF) {		/* the load is not finished but so far there are no errors */		/* copy the following vars back into the load_info struct */		(void) strcpy(load_info->origin, origin);		(void) strcpy(load_info->domain, domain);		load_info->class = class;		/* Set load_info->lineno to the line in fp that we			are "reading". */		load_info->lineno = lineno;		return(-2);	} else {		/* the load finished correctly */		(void) fclose(load_info->fp);		return(num_iter);	}}#else ULTRIXFUNC/* * Load the database from 'filename'. Origin is appended to all domain * names in the file. */db_load(filename, in_origin, zp)	char *filename, *in_origin;	struct zoneinfo *zp;{	register u_char *cp;	register struct map *mp;	char domain[MAXDNAME];	char origin[MAXDNAME];	char tmporigin[MAXDNAME];	u_char buf[MAXDATA], *tmpdata, *tmpbuf;	u_char data[MAXDATA];	char *op;	int c;	int class, type, ttl, dbflags, dataflags;	struct databuf *dp;	FILE *fp;	int slineno, i, errs = 0, didinclude = 0;/* If T_UNSPEC is used, this can't be a register variable. */#ifndef ALLOW_T_UNSPEC	register u_long n;#else	u_long n;#endif	struct stat sb;#ifdef DEBUG	if (debug)		fprintf(ddt,"db_load(%s, %s, %d)\n",		    filename, in_origin, zp - zones);#endif	(void) strcpy(origin, in_origin);	if ((fp = fopen(filename, "r")) == NULL) {		if (zp->z_type != Z_SECONDARY)			syslog(LOG_ERR, "%s: %m", filename);#ifdef DEBUG		if (debug)		    fprintf(ddt,"db_load: error opening file %s\n", filename);#endif		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 = C_IN;	while ((c = gettoken(fp)) != EOF) {		switch (c) {		case INCLUDE:			if (!getword(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(buf, tmporigin, zp);			continue;		case ORIGIN:			(void) strcpy(buf, origin);			if (!getword(origin, sizeof(origin), fp))				break;#ifdef DEBUG			if (debug > 3)				fprintf(ddt,"db_load: origin %s, buf %s\n",				    origin, buf);#endif			makename(origin, buf);#ifdef DEBUG			if (debug > 3)				fprintf(ddt,"db_load: origin now %s\n", origin);#endif			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(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(buf, sizeof(buf), fp))					break;			}			for (mp = m_class; mp < m_class+NCLASS; mp++)				if (!strcasecmp(buf, mp->token)) {					class = mp->val;					(void) getword(buf, sizeof(buf), fp);					break;				}			for (mp = m_type; mp < m_type+NTYPE; mp++)				if (!strcasecmp(buf, mp->token)) {					type = mp->val;					goto fndtype;				}#ifdef DEBUG			if (debug)				fprintf(ddt,"Line %d: Unknown type: %s.\n",					lineno, buf);#endif			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 ALLOW_T_UNSPEC			    if (!getword(buf, sizeof(buf), fp))				break;#ifdef DEBUG			    if (debug >= 3)			        fprintf(ddt,				    "d='%s', c=%d, t=%d, ttl=%d, data='%s'\n",				    domain, class, type, ttl, buf);#endif#ifdef ALLOW_T_UNSPEC                        }#endif ALLOW_T_UNSPEC			/*			 * Convert the ascii data 'buf' to the proper format			 * based on the type and pack into 'data'.			 */			switch (type) {			case T_A:				n = ntohl((u_long)inet_addr((char *)buf));				cp = data;				PUTLONG(n, cp);				n = sizeof(u_long);				break;			case T_HINFO:				n = strlen(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(buf, sizeof(buf), fp))					break;				i = strlen(buf);				if (i > 255) {				    syslog(LOG_WARNING,					"%s: line %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:				(void) strcpy(data, buf);				makename(data, origin);				cp = data + strlen(data) + 1;				if (!getword(cp, sizeof(data) - (cp - data),fp)) {					n = cp - data;					break;				}				makename(cp, origin);				cp += strlen(cp) + 1;				if (type == T_MINFO) {					n = cp - data;					break;				}				if (getnonblank(fp) != '(')					goto err;				zp->z_serial = getnum(fp);				n = (u_long) zp->z_serial;				PUTLONG(n, cp);				zp->z_refresh = getnum(fp);				n = (u_long) zp->z_refresh;				PUTLONG(n, cp);				zp->z_time = sb.st_mtime + zp->z_refresh;				zp->z_retry = getnum(fp);				n = (u_long) zp->z_retry;				PUTLONG(n, cp);				zp->z_expire = getnum(fp);				n = (u_long) zp->z_expire;				PUTLONG (n, cp);				zp->z_minimum = getnum(fp);				n = (u_long) zp->z_minimum;				PUTLONG (n, cp);				n = cp - data;				if (getnonblank(fp) != ')')					goto err;				endline(fp);#ifdef ULTRIXFUNC				zp->z_class = class;#endif ULTRIXFUNC				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(long);				break;			case T_WKS:				/* Address */				n = ntohl((u_long)inet_addr((char *)buf));				cp = data;				PUTLONG(n, cp);				*cp = getprotocol(fp, filename);				/* Protocol */				n = sizeof(u_long) + 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(data, buf);				makename(data, origin);				n = strlen(data) + 1;				break;			case T_UINFO:				cp = (u_char *)index(buf, '&');				bzero(data, sizeof(data));

⌨️ 快捷键说明

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