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 + -
显示快捷键?