📄 db_load.c
字号:
#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 + -