📄 db.c
字号:
/* * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC 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. *//* $Id: db.c,v 1.69.2.1.10.4 2004/03/08 02:07:52 marka Exp $ *//*** *** Imports ***/#include <config.h>#include <isc/buffer.h>#include <isc/mem.h>#include <isc/once.h>#include <isc/rwlock.h>#include <isc/string.h>#include <isc/util.h>#include <dns/callbacks.h>#include <dns/db.h>#include <dns/log.h>#include <dns/master.h>#include <dns/rdata.h>#include <dns/rdataset.h>#include <dns/result.h>/*** *** Private Types ***/struct dns_dbimplementation { const char * name; dns_dbcreatefunc_t create; isc_mem_t * mctx; void * driverarg; ISC_LINK(dns_dbimplementation_t) link;};/*** *** Supported DB Implementations Registry ***//* * Built in database implementations are registered here. */#include "rbtdb.h"#include "rbtdb64.h"static ISC_LIST(dns_dbimplementation_t) implementations;static isc_rwlock_t implock;static isc_once_t once = ISC_ONCE_INIT;static dns_dbimplementation_t rbtimp;static dns_dbimplementation_t rbt64imp;static voidinitialize(void) { RUNTIME_CHECK(isc_rwlock_init(&implock, 0, 0) == ISC_R_SUCCESS); rbtimp.name = "rbt"; rbtimp.create = dns_rbtdb_create; rbtimp.mctx = NULL; rbtimp.driverarg = NULL; ISC_LINK_INIT(&rbtimp, link); rbt64imp.name = "rbt64"; rbt64imp.create = dns_rbtdb64_create; rbt64imp.mctx = NULL; rbt64imp.driverarg = NULL; ISC_LINK_INIT(&rbt64imp, link); ISC_LIST_INIT(implementations); ISC_LIST_APPEND(implementations, &rbtimp, link); ISC_LIST_APPEND(implementations, &rbt64imp, link);}static inline dns_dbimplementation_t *impfind(const char *name) { dns_dbimplementation_t *imp; for (imp = ISC_LIST_HEAD(implementations); imp != NULL; imp = ISC_LIST_NEXT(imp, link)) if (strcasecmp(name, imp->name) == 0) return (imp); return (NULL);}/*** *** Basic DB Methods ***/isc_result_tdns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], dns_db_t **dbp){ dns_dbimplementation_t *impinfo; RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); /* * Create a new database using implementation 'db_type'. */ REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(dns_name_isabsolute(origin)); RWLOCK(&implock, isc_rwlocktype_read); impinfo = impfind(db_type); if (impinfo != NULL) { isc_result_t result; result = ((impinfo->create)(mctx, origin, type, rdclass, argc, argv, impinfo->driverarg, dbp)); RWUNLOCK(&implock, isc_rwlocktype_read); return (result); } RWUNLOCK(&implock, isc_rwlocktype_read); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DB, ISC_LOG_ERROR, "unsupported database type '%s'", db_type); return (ISC_R_NOTFOUND);}voiddns_db_attach(dns_db_t *source, dns_db_t **targetp) { /* * Attach *targetp to source. */ REQUIRE(DNS_DB_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); (source->methods->attach)(source, targetp); ENSURE(*targetp == source);}voiddns_db_detach(dns_db_t **dbp) { /* * Detach *dbp from its database. */ REQUIRE(dbp != NULL); REQUIRE(DNS_DB_VALID(*dbp)); ((*dbp)->methods->detach)(dbp); ENSURE(*dbp == NULL);}isc_result_tdns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp){ REQUIRE(DNS_DB_VALID(db)); return (isc_ondestroy_register(&db->ondest, task, eventp));}isc_boolean_tdns_db_iscache(dns_db_t *db) { /* * Does 'db' have cache semantics? */ REQUIRE(DNS_DB_VALID(db)); if ((db->attributes & DNS_DBATTR_CACHE) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_db_iszone(dns_db_t *db) { /* * Does 'db' have zone semantics? */ REQUIRE(DNS_DB_VALID(db)); if ((db->attributes & (DNS_DBATTR_CACHE|DNS_DBATTR_STUB)) == 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_db_isstub(dns_db_t *db) { /* * Does 'db' have stub semantics? */ REQUIRE(DNS_DB_VALID(db)); if ((db->attributes & DNS_DBATTR_STUB) != 0) return (ISC_TRUE); return (ISC_FALSE);}isc_boolean_tdns_db_issecure(dns_db_t *db) { /* * Is 'db' secure? */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); return ((db->methods->issecure)(db));}isc_boolean_tdns_db_ispersistent(dns_db_t *db) { /* * Is 'db' persistent? */ REQUIRE(DNS_DB_VALID(db)); return ((db->methods->ispersistent)(db));}dns_name_t *dns_db_origin(dns_db_t *db) { /* * The origin of the database. */ REQUIRE(DNS_DB_VALID(db)); return (&db->origin);}dns_rdataclass_tdns_db_class(dns_db_t *db) { /* * The class of the database. */ REQUIRE(DNS_DB_VALID(db)); return (db->rdclass);}isc_result_tdns_db_beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) { /* * Begin loading 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(addp != NULL && *addp == NULL); REQUIRE(dbloadp != NULL && *dbloadp == NULL); return ((db->methods->beginload)(db, addp, dbloadp));}isc_result_tdns_db_endload(dns_db_t *db, dns_dbload_t **dbloadp) { /* * Finish loading 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(dbloadp != NULL && *dbloadp != NULL); return ((db->methods->endload)(db, dbloadp));}isc_result_tdns_db_load(dns_db_t *db, const char *filename) { isc_result_t result, eresult; dns_rdatacallbacks_t callbacks; unsigned int options = 0; /* * Load master file 'filename' into 'db'. */ REQUIRE(DNS_DB_VALID(db)); if ((db->attributes & DNS_DBATTR_CACHE) != 0) options |= DNS_MASTER_AGETTL; dns_rdatacallbacks_init(&callbacks); result = dns_db_beginload(db, &callbacks.add, &callbacks.add_private); if (result != ISC_R_SUCCESS) return (result); result = dns_master_loadfile(filename, &db->origin, &db->origin, db->rdclass, options, &callbacks, db->mctx); eresult = dns_db_endload(db, &callbacks.add_private); /* * We always call dns_db_endload(), but we only want to return its * result if dns_master_loadfile() succeeded. If dns_master_loadfile() * failed, we want to return the result code it gave us. */ if (eresult != ISC_R_SUCCESS && (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) result = eresult; return (result);}isc_result_tdns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { /* * Dump 'db' into master file 'filename'. */ REQUIRE(DNS_DB_VALID(db)); return ((db->methods->dump)(db, version, filename));}/*** *** Version Methods ***/voiddns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp) { /* * Open the current version for reading. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); REQUIRE(versionp != NULL && *versionp == NULL); (db->methods->currentversion)(db, versionp);}isc_result_tdns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp) { /* * Open a new version for reading and writing. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); REQUIRE(versionp != NULL && *versionp == NULL); return ((db->methods->newversion)(db, versionp));}voiddns_db_attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp){ /* * Attach '*targetp' to 'source'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); REQUIRE(source != NULL); REQUIRE(targetp != NULL && *targetp == NULL); (db->methods->attachversion)(db, source, targetp); ENSURE(*targetp != NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -