📄 master.c
字号:
if (ictx->parent != NULL) { COMMITALL; lctx->inc = ictx->parent; ictx->parent = NULL; incctx_destroy(lctx->mctx, ictx); RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS); line = isc_lex_getsourceline(lctx->lex); source = isc_lex_getsourcename(lctx->lex); ictx = lctx->inc; EXPECTEOL; continue; } done = ISC_TRUE; continue; } if (token.type == isc_tokentype_eol) { read_till_eol = ISC_FALSE; continue; /* blank line */ } if (read_till_eol) continue; if (token.type == isc_tokentype_initialws) { /* * Still working on the same name. */ initialws = ISC_TRUE; } else if (token.type == isc_tokentype_string) { /* * "$" Support. * * "$ORIGIN" and "$INCLUDE" can both take domain names. * The processing of "$ORIGIN" and "$INCLUDE" extends * across the normal domain name processing. */ if (strcasecmp(DNS_AS_STR(token), "$ORIGIN") == 0) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); finish_origin = ISC_TRUE; } else if (strcasecmp(DNS_AS_STR(token), "$TTL") == 0) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); result = dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); lctx->ttl = 0; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; limit_ttl(callbacks, source, line, &lctx->ttl); lctx->default_ttl = lctx->ttl; lctx->default_ttl_known = ISC_TRUE; EXPECTEOL; continue; } else if (strcasecmp(DNS_AS_STR(token), "$INCLUDE") == 0) { COMMITALL; if ((lctx->options & DNS_MASTER_NOINCLUDE) != 0) { (callbacks->error)(callbacks, "%s: %s:%lu: $INCLUDE not allowed", "dns_master_load", source, line); result = DNS_R_REFUSED; goto insist_and_cleanup; } if (ttl_offset != 0) { (callbacks->error)(callbacks, "%s: %s:%lu: $INCLUDE " "may not be used with $DATE", "dns_master_load", source, line); result = DNS_R_SYNTAX; goto insist_and_cleanup; } GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token, ISC_FALSE); if (include_file != NULL) isc_mem_free(mctx, include_file); include_file = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (include_file == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } GETTOKEN(lctx->lex, 0, &token, ISC_TRUE); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { if (token.type == isc_tokentype_eof) WARNUNEXPECTEDEOF(lctx->lex); isc_lex_ungettoken(lctx->lex, &token); /* * No origin field. */ result = pushfile(include_file, ictx->origin, lctx); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGITFILE(result, include_file); continue; } else if (result != ISC_R_SUCCESS) { LOGITFILE(result, include_file); goto insist_and_cleanup; } ictx = lctx->inc; line = isc_lex_getsourceline(lctx->lex); source = isc_lex_getsourcename(lctx->lex); continue; } /* * There is an origin field. Fall through * to domain name processing code and do * the actual inclusion later. */ finish_include = ISC_TRUE; } else if (strcasecmp(DNS_AS_STR(token), "$DATE") == 0) { isc_int64_t dump_time64; isc_stdtime_t dump_time, current_time; GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); isc_stdtime_get(¤t_time); result = dns_time64_fromtext(DNS_AS_STR(token), &dump_time64); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); dump_time64 = 0; } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; dump_time = (isc_stdtime_t)dump_time64; if (dump_time != dump_time64) { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %s:%lu: $DATE outside epoch", "dns_master_load", source, line); result = ISC_R_UNEXPECTED; goto insist_and_cleanup; } if (dump_time > current_time) { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %s:%lu: " "$DATE in future, using current date", "dns_master_load", source, line); dump_time = current_time; } ttl_offset = current_time - dump_time; EXPECTEOL; continue; } else if (strcasecmp(DNS_AS_STR(token), "$GENERATE") == 0) { /* * Lazy cleanup. */ if (range != NULL) isc_mem_free(mctx, range); if (lhs != NULL) isc_mem_free(mctx, lhs); if (gtype != NULL) isc_mem_free(mctx, gtype); if (rhs != NULL) isc_mem_free(mctx, rhs); /* RANGE */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); range = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (range == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } /* LHS */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); lhs = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (lhs == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } rdclass = 0; explicit_ttl = ISC_FALSE; /* CLASS? */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); if (dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); } /* TTL? */ if (dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl) == ISC_R_SUCCESS) { limit_ttl(callbacks, source, line, &lctx->ttl); lctx->ttl_known = ISC_TRUE; explicit_ttl = ISC_TRUE; GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); } /* CLASS? */ if (rdclass == 0 && dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); /* TYPE */ gtype = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (gtype == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } /* RHS */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); rhs = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (rhs == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } if (!lctx->ttl_known && !lctx->default_ttl_known) { (*callbacks->error)(callbacks, "%s: %s:%lu: no TTL specified", "dns_master_load", source, line); result = DNS_R_NOTTL; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); lctx->ttl = 0; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } else if (!explicit_ttl && lctx->default_ttl_known) { lctx->ttl = lctx->default_ttl; } /* * If the class specified does not match the * zone's class print out a error message and * exit. */ if (rdclass != 0 && rdclass != lctx->zclass) { goto bad_class; } result = generate(lctx, range, lhs, gtype, rhs, source, line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; EXPECTEOL; continue; } else if (strncasecmp(DNS_AS_STR(token), "$", 1) == 0) { (callbacks->error)(callbacks, "%s: %s:%lu: " "unknown $ directive '%s'", "dns_master_load", source, line, DNS_AS_STR(token)); result = DNS_R_SYNTAX; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } /* * Normal processing resumes. * * Find a free name buffer. */ for (new_in_use = 0; new_in_use < NBUFS; new_in_use++) if (!ictx->in_use[new_in_use]) break; INSIST(new_in_use < NBUFS); dns_fixedname_init(&ictx->fixed[new_in_use]); new_name = dns_fixedname_name(&ictx->fixed[new_in_use]); isc_buffer_init(&buffer, token.value.as_region.base, token.value.as_region.length); isc_buffer_add(&buffer, token.value.as_region.length); isc_buffer_setactive(&buffer, token.value.as_region.length); result = dns_name_fromtext(new_name, &buffer, ictx->origin, ISC_FALSE, NULL); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; /* * Finish $ORIGIN / $INCLUDE processing if required. */ if (finish_origin) { if (ictx->origin_in_use != -1) ictx->in_use[ictx->origin_in_use] = ISC_FALSE; ictx->origin_in_use = new_in_use; ictx->in_use[ictx->origin_in_use] = ISC_TRUE; ictx->origin = new_name; finish_origin = ISC_FALSE; EXPECTEOL; continue; } if (finish_include) { finish_include = ISC_FALSE; result = pushfile(include_file, new_name, lctx); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGITFILE(result, include_file); continue; } else if (result != ISC_R_SUCCESS) { LOGITFILE(result, include_file); goto insist_and_cleanup; } ictx = lctx->inc; line = isc_lex_getsourceline(lctx->lex); source = isc_lex_getsourcename(lctx->lex); continue; } /* * "$" Processing Finished */ /* * If we are processing glue and the new name does * not match the current glue name, commit the glue * and pop stacks leaving us in 'normal' processing * state. Linked lists are undone by commit(). */ if (ictx->glue != NULL && dns_name_compare(ictx->glue, new_name) != 0) { result = commit(callbacks, lctx, &glue_list, ictx->glue, source, ictx->glue_line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; if (ictx->glue_in_use != -1) ictx->in_use[ictx->glue_in_use] = ISC_FALSE; ictx->glue_in_use = -1; ictx->glue = NULL; rdcount = rdcount_save; rdlcount = rdlcount_save; target = target_save; } /* * If we are in 'normal' processing state and the new * name does not match the current name, see if the * new name is for glue and treat it as such, * otherwise we have a new name so commit what we * have. */ if ((ictx->glue == NULL) && (ictx->current == NULL || dns_name_compare(ictx->current, new_name) != 0)) { if (current_has_delegation && is_glue(¤t_list, new_name)) { rdcount_save = rdcount; rdlcount_save = rdlcount; target_save = target; ictx->glue = new_name; ictx->glue_in_use = new_in_use; ictx->in_use[ictx->glue_in_use] = ISC_TRUE; } else { result = commit(callbacks, lctx, ¤t_list, ictx->current, source, ictx->current_line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; rdcount = 0; rdlcount = 0; if (ictx->current_in_use != -1) ictx->in_use[ictx->current_in_use] = ISC_FALSE; ictx->current_in_use = new_in_use; ictx->in_use[ictx->current_in_use] = ISC_TRUE; ictx->current = new_name; current_has_delegation = ISC_FALSE; isc_buffer_init(&target, target_mem, target_size); } } if ((lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0 && !dns_name_issubdomain(new_name, lctx->top)) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(new_name, namebuf, sizeof(namebuf)); /* * Ignore out-of-zone data. */ (*callbacks->warn)(callbacks, "%s:%lu: " "ignoring out-of-zone data (%s)", source, line, namebuf); ictx->drop = ISC_TRUE; } else ictx->drop = ISC_FALSE; } else { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s:%lu: isc_lex_gettoken() returned " "unexpeced token type (%d)", source, line, token.type); result = ISC_R_UNEXPECTED; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } /* * Find TTL, class and type. Both TTL and class are optional * and may occur in any order if they exist. TTL and class * come before type which must exist. * * [<TTL>] [<class>] <type> <RDATA> * [<class>] [<TTL>] <type> <RDATA> */ type = 0; rdclass = 0; GETTOKEN(lctx->lex, 0, &token, initialws); if (initialws) { if (token.type == isc_tokentype_eol) { read_till_eol = ISC_FALSE; continue; /* blank line */ } if (token.type == isc_tokentype_eof) { WARNUNEXPECTEDEOF(lctx->lex); read_till_eol = ISC_FALSE; isc_lex_ungettoken(lctx->lex, &token); continue; } if (ictx->current == NULL) { (*callbacks->error)(callbacks, "%s:%lu: no current owner name", source, line); result = DNS_R_NOOWNER; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } } if (dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); explicit_ttl = ISC_FALSE; if (dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -