db_load.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,648 行 · 第 1/3 页
C
1,648 行
#ifndef lintstatic char *sccsid = "@(#)db_load.c 4.2 (ULTRIX) 11/15/90";#endif lint/************************************************************************ * * * Copyright (c) 1984-1990 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * Copyright (c) 1986 Regents of the University of California * All Rights Reserved * static char sccsid[] = "@(#)db_load.c 4.26 (Berkeley) 2/28/88"; *//* * Modification History: * * 18-Jan-88 logcher * Added BIND 4.7.2 with ifdef-ed MIT Hesiod support. * * 26-Jan-88 logcher * Added BIND 4.7.3. * * 08-Jun-88 logcher * Added the correct MIT Hesiod support. * * 11-Nov-88 logcher * Updated with V3.0 changes. * * 17-May-89 logcher * Added BIND 4.8 with MIT Hesiod support. * * 10-Jan-90 sue * Incorporated Hesiod changes from MIT to implement multiple * "character strings" in a TXT record according to RFC1035. *//* * Load data base from ascii backupfile. Format similar to RFC 883. */#include <sys/param.h>#include <sys/time.h>#include <sys/stat.h>#include <netinet/in.h>#include <stdio.h>#include <syslog.h>#include <ctype.h>#include <netdb.h>#include <arpa/nameser.h>#include "ns.h"#include "db.h"extern char *index();extern int max_cache_ttl;/* * 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, "uid", T_UID, "gid", T_GID, "txt", T_TXT,#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 7int lineno; /* current line number */struct valuelist { struct valuelist *next, *prev; char *name; char *proto; short port;} *servicelist, *protolist;file_ref_st *load_prep(zp, filename, origin, zonenum) struct zoneinfo *zp; char *filename; char *origin; int zonenum;{ file_ref_st *load_info; if((load_info = (file_ref_st *)malloc(sizeof(file_ref_st))) == NULL) { syslog(LOG_ERR, "load_prep: Bad Malloc.\n");#ifdef DEBUG if (debug) fprintf(ddt,"load_prep: Bad Malloc.\n");#endif return(NULL); } if((load_info->files = (files_st *)malloc(sizeof(files_st))) == NULL) { syslog(LOG_ERR, "load_prep: Bad Malloc.\n");#ifdef DEBUG if (debug) fprintf(ddt,"load_prep: Bad Malloc.\n");#endif free(load_info); return(NULL); } if((load_info->zp = (struct zoneinfo *) malloc(sizeof(struct zoneinfo))) == NULL) { syslog(LOG_ERR, "load_prep: Bad Malloc.\n");#ifdef DEBUG if (debug) fprintf(ddt,"load_prep: Bad Malloc.\n");#endif free(load_info->files); free(load_info); return(NULL); } zp->z_load_info = load_info; set_zp(zp, load_info->zp); (void) strcpy(load_info->files->f_name, filename); load_info->files->next = NULL; load_info->files_tail = load_info->files; load_info->fp = NULL; (void) strcpy(load_info->origin, origin); load_info->next = NULL; load_info->zonenum = zonenum; return(load_info);}#ifdef ULTRIXFUNCdb_load(load_info, num_iter) file_ref_st *load_info; /* pointer to the structure which describes what data to load. */ int num_iter; /* the number of iterations through the while loop below that this function should go through. If an include entry is found, num_iter is overrided. If num_iter == -1 then no limit exists. */{ register struct zoneinfo *zp; register char domain[MAXDNAME]; register char origin[MAXDNAME]; register FILE *fp; register u_char *cp; register struct map *mp; char tmporigin[MAXDNAME]; u_char buf[MAXDATA], *tmpdata, *tmpbuf; u_char data[MAXDATA]; char *op; int c; int class, type; int ttl; struct databuf *dp; int i, errs = -2; int result; FILE *fp_in;/* 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 if(load_info->next != NULL) { if((result = db_load(load_info->next, num_iter)) < -2) { errs = result; goto err; } else { if(result == -2) return(-2); else { load_info->format_errs += load_info->next->format_errs; free(load_info->next); load_info->next = NULL; num_iter = result; } } } else { if(num_iter < -1) errs--; } if(load_info->fp == NULL) { /* This load_info struct has not been initialized. Start reading the file from the start. */#ifdef DEBUG if (debug) fprintf(ddt,"db_load(%s, %s, %d)\n", load_info->zp->z_source, load_info->origin, load_info->zonenum);#endif /* */ if ((load_info->fp = fopen(load_info->files->f_name, "r")) == NULL) { if (load_info->zp->z_type != Z_SECONDARY) syslog(LOG_ERR,"db_load: error opening file %s\n", load_info->files->f_name);#ifdef DEBUG if (debug) fprintf(ddt,"db_load: error opening file %s\n", load_info->files->f_name);#endif errs--; goto err; } load_info->lineno = 1; if (load_info->zp->z_type == Z_CACHE) { load_info->dbflags = DB_NODATA | DB_NOHINTS; load_info->dataflags = DB_F_HINT; } else { load_info->dbflags = DB_NODATA; load_info->dataflags = 0; } gettime(&tt); if (fstat(fileno(load_info->fp), &load_info->files->f_stats) < 0) { syslog(LOG_ERR,"db_load: error in fstat, file %s\n", load_info->files->f_name);#ifdef DEBUG if (debug) fprintf(ddt,"db_load: error in fstat file %s\n", load_info->files->f_name);#endif errs--; goto err; } if(load_info->files->f_stats.st_mtime > load_info->zp->z_ftime) load_info->zp->z_ftime = load_info->files->f_stats.st_mtime; /* A primary assumes that the data in the load file is is not in the process of expiring. */ if(load_info->zp->z_type == Z_PRIMARY) load_info->zp->z_lastupdate = tt.tv_sec; else load_info->zp->z_lastupdate = load_info->files->f_stats.st_mtime; load_info->domain[0] = '\0'; load_info->class = C_IN; load_info->format_errs = 0; } /* copy the following vars into stackspace in order to prevent any de-referencing */ fp = load_info->fp; zp = load_info->zp; (void) strcpy(origin, load_info->origin); (void) strcpy(domain, load_info->domain); /* Set lineno to the line in cur_file that we are "reading". */ lineno = load_info->lineno; class = load_info->class; /* We have started to read the file. continue. */ while ((num_iter == -1 || num_iter - 1 >= 0) && (c = gettoken(fp)) != EOF && (num_iter == -1 || --num_iter >= 0)) { switch (c) { case INCLUDE: /* An include entry implies that another file should be read at this point. Copy all of the new file to the temp file, and set environment vars */ if (!getword(buf, sizeof(buf), fp)) /* file name */ break; if (!getword(tmporigin, sizeof(tmporigin), fp)) strcpy(tmporigin, origin); else { makename(tmporigin, origin); endline(fp); } if((load_info->next = load_prep(zp, buf, tmporigin, load_info->zonenum)) == NULL){ syslog(LOG_ERR, "Bad load_prep call"); errs--; goto err; } free(load_info->next->zp); load_info->next->zp = zp; zp->z_load_info = load_info; load_info->lineno = lineno; /* if num_iter == -1 then process till the end otherwise, consider the copying of an entire file enough steps to use all of num_iter. */ if (num_iter != -1) num_iter = 1; if((result = db_load(load_info->next,num_iter)) < -2) { free(load_info->next); load_info->next = NULL; errs = result; goto err; } lineno = load_info->lineno; load_info->files_tail->next = load_info->next->files; load_info->files_tail = load_info->next->files_tail; if(result == -2) { num_iter = 0; } else { load_info->format_errs += load_info->next->format_errs; free(load_info->next); load_info->next = NULL; num_iter = result; } 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 += load_info->files->f_stats.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 load_info->format_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", load_info->files->f_name, 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", load_info->files->f_name, 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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?