Blame contrib/sdb/bdb/bdb.c

Packit 5ce601
/*
Packit 5ce601
 * Copyright (C) 2002  Nuno M. Rodrigues.
Packit 5ce601
 *
Packit 5ce601
 * Permission to use, copy, modify, and distribute this software for any
Packit 5ce601
 * purpose with or without fee is hereby granted, provided that the above
Packit 5ce601
 * copyright notice and this permission notice appear in all copies.
Packit 5ce601
 *
Packit 5ce601
 * THE SOFTWARE IS PROVIDED "AS IS" AND NUNO M. RODRIGUES
Packit 5ce601
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
Packit 5ce601
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
Packit 5ce601
 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
Packit 5ce601
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
Packit 5ce601
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
Packit 5ce601
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
Packit 5ce601
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Packit 5ce601
 */
Packit 5ce601
Packit 5ce601
Packit 5ce601
/*
Packit 5ce601
 * BIND 9.1.x simple database driver
Packit 5ce601
 * implementation, using Berkeley DB.
Packit 5ce601
 */
Packit 5ce601
Packit 5ce601
#include <errno.h>
Packit 5ce601
#include <stdio.h>
Packit 5ce601
#include <string.h>
Packit 5ce601
#include <stdlib.h>
Packit 5ce601
Packit 5ce601
#include <isc/file.h>
Packit 5ce601
#include <isc/log.h>
Packit 5ce601
#include <isc/lib.h>
Packit 5ce601
#include <isc/mem.h>
Packit 5ce601
#include <isc/msgs.h>
Packit 5ce601
#include <isc/msgcat.h>
Packit 5ce601
#include <isc/region.h>
Packit 5ce601
#include <isc/result.h>
Packit 5ce601
#include <isc/types.h>
Packit 5ce601
#include <isc/util.h>
Packit 5ce601
Packit 5ce601
#include <dns/sdb.h>
Packit 5ce601
#include <dns/log.h>
Packit 5ce601
#include <dns/lib.h>
Packit 5ce601
#include <dns/ttl.h>
Packit 5ce601
Packit Service d3afd5
#include <named/bdb.h>
Packit 5ce601
#include <named/globals.h>
Packit 5ce601
#include <named/config.h>
Packit 5ce601
Packit 5ce601
#include <db.h>
Packit 5ce601
Packit 5ce601
#define DRIVERNAME	"bdb"
Packit 5ce601
Packit 5ce601
static dns_sdbimplementation_t *bdb_imp;
Packit 5ce601
Packit 5ce601
static isc_result_t
Packit 5ce601
bdb_create(const char *zone, int argc, char **argv,
Packit 5ce601
	   void *unused, void **dbdata)
Packit 5ce601
{
Packit 5ce601
	int ret;
Packit 5ce601
Packit 5ce601
	UNUSED(zone);
Packit 5ce601
	UNUSED(unused);
Packit 5ce601
Packit 5ce601
	if (argc < 1)
Packit 5ce601
		return ISC_R_FAILURE;	/* database path must be given */
Packit 5ce601
Packit 5ce601
	if (db_create((DB **)dbdata, NULL, 0) != 0) {
Packit 5ce601
		/*
Packit 5ce601
		 * XXX Should use dns_msgcat et al
Packit 5ce601
		 * but seems to be unavailable.
Packit 5ce601
		 */
Packit 5ce601
		isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
Packit 5ce601
			       DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL, isc_msgcat,
Packit 5ce601
			       ISC_MSGSET_GENERAL, ISC_MSG_FATALERROR,
Packit 5ce601
			       "db_create");
Packit 5ce601
		return ISC_R_FAILURE;
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	if (isc_file_exists(*argv) != true) {
Packit 5ce601
		isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
Packit 5ce601
			       DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL, isc_msgcat,
Packit 5ce601
			       ISC_MSGSET_GENERAL, ISC_MSG_FATALERROR,
Packit 5ce601
			       "isc_file_exists: %s", *argv);
Packit 5ce601
		return ISC_R_FAILURE;
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	if ((ret = (*(DB **)dbdata)->open(*(DB **)dbdata, *argv, NULL, DB_HASH,
Packit 5ce601
	    DB_RDONLY, 0)) != 0) {
Packit 5ce601
			isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
Packit 5ce601
				       DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL,
Packit 5ce601
				       isc_msgcat, ISC_MSGSET_GENERAL,
Packit 5ce601
				       ISC_MSG_FATALERROR, "DB->open: %s",
Packit 5ce601
				       db_strerror(ret));
Packit 5ce601
			return ISC_R_FAILURE;
Packit 5ce601
	}
Packit 5ce601
	return ISC_R_SUCCESS;
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static isc_result_t
Packit 5ce601
#ifdef DNS_CLIENTINFO_VERSION
Packit 5ce601
bdb_lookup(const char *zone, const char *name, void *dbdata,
Packit 5ce601
	   dns_sdblookup_t *l, dns_clientinfomethods_t *methods,
Packit 5ce601
	   dns_clientinfo_t *clientinfo)
Packit 5ce601
#else
Packit 5ce601
bdb_lookup(const char *zone, const char *name, void *dbdata,
Packit 5ce601
	   dns_sdblookup_t *l)
Packit 5ce601
#endif /* DNS_CLIENTINFO_VERSION */
Packit 5ce601
{
Packit 5ce601
	int ret;
Packit 5ce601
	char *type, *rdata;
Packit 5ce601
	dns_ttl_t ttl;
Packit 5ce601
	isc_consttextregion_t ttltext;
Packit 5ce601
	DBC *c;
Packit 5ce601
	DBT key, data;
Packit 5ce601
Packit 5ce601
	UNUSED(zone);
Packit 5ce601
#ifdef DNS_CLIENTINFO_VERSION
Packit 5ce601
	UNUSED(methods);
Packit 5ce601
	UNUSED(clientinfo);
Packit 5ce601
#endif /* DNS_CLIENTINFO_VERSION */
Packit 5ce601
Packit 5ce601
	if ((ret = ((DB *)dbdata)->cursor((DB *)dbdata, NULL, &c, 0)) != 0) {
Packit 5ce601
		isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
Packit 5ce601
			       DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
Packit 5ce601
			       isc_msgcat, ISC_MSGSET_GENERAL,
Packit 5ce601
			       ISC_MSG_FAILED, "DB->cursor: %s",
Packit 5ce601
			       db_strerror(ret));
Packit 5ce601
		return ISC_R_FAILURE;
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	memset(&key, 0, sizeof(DBT));
Packit 5ce601
	memset(&data, 0, sizeof(DBT));
Packit 5ce601
Packit 5ce601
	(const char *)key.data = name;
Packit 5ce601
	key.size = strlen(name);
Packit 5ce601
Packit 5ce601
	ret = c->c_get(c, &key, &data, DB_SET);
Packit 5ce601
	while (ret == 0) {
Packit 5ce601
		((char *)key.data)[key.size] = 0;
Packit 5ce601
		((char *)data.data)[data.size] = 0;
Packit 5ce601
		ttltext.base = strtok((char *)data.data, " ");
Packit 5ce601
		ttltext.length = strlen(ttltext.base);
Packit 5ce601
		dns_ttl_fromtext((isc_textregion_t *)&ttltext, &ttl);
Packit 5ce601
		type = strtok(NULL, " ");
Packit 5ce601
		rdata = type + strlen(type) + 1;
Packit 5ce601
Packit 5ce601
		if (dns_sdb_putrr(l, type, ttl, rdata) != ISC_R_SUCCESS) {
Packit 5ce601
			isc_log_iwrite(dns_lctx,
Packit 5ce601
				       DNS_LOGCATEGORY_DATABASE,
Packit 5ce601
				       DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
Packit 5ce601
				       isc_msgcat, ISC_MSGSET_GENERAL,
Packit 5ce601
				       ISC_MSG_FAILED, "dns_sdb_putrr");
Packit 5ce601
			return ISC_R_FAILURE;
Packit 5ce601
		}
Packit 5ce601
		ret = c->c_get(c, &key, &data, DB_NEXT_DUP);
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	c->c_close(c);
Packit 5ce601
	return ISC_R_SUCCESS;
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static isc_result_t
Packit 5ce601
bdb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *n)
Packit 5ce601
{
Packit 5ce601
	int ret;
Packit 5ce601
	char *type, *rdata;
Packit 5ce601
	dns_ttl_t ttl;
Packit 5ce601
	isc_consttextregion_t ttltext;
Packit 5ce601
	DBC *c;
Packit 5ce601
	DBT key, data;
Packit 5ce601
Packit 5ce601
	UNUSED(zone);
Packit 5ce601
Packit 5ce601
	if ((ret = ((DB *)dbdata)->cursor((DB *)dbdata, NULL, &c, 0)) != 0) {
Packit 5ce601
		isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
Packit 5ce601
			       DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
Packit 5ce601
			       isc_msgcat, ISC_MSGSET_GENERAL,
Packit 5ce601
			       ISC_MSG_FAILED, "DB->cursor: %s",
Packit 5ce601
			       db_strerror(ret));
Packit 5ce601
		return ISC_R_FAILURE;
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	memset(&key, 0, sizeof(DBT));
Packit 5ce601
	memset(&data, 0, sizeof(DBT));
Packit 5ce601
Packit 5ce601
	while (c->c_get(c, &key, &data, DB_NEXT) == 0) {
Packit 5ce601
		((char *)key.data)[key.size] = 0;
Packit 5ce601
		((char *)data.data)[data.size] = 0;
Packit 5ce601
		ttltext.base = strtok((char *)data.data, " ");
Packit 5ce601
		ttltext.length = strlen(ttltext.base);
Packit 5ce601
		dns_ttl_fromtext((isc_textregion_t *)&ttltext, &ttl);
Packit 5ce601
		type = strtok(NULL, " ");
Packit 5ce601
		rdata = type + strlen(type) + 1;
Packit 5ce601
Packit 5ce601
		if (dns_sdb_putnamedrr(n, key.data, type, ttl, rdata) !=
Packit 5ce601
		    ISC_R_SUCCESS) {
Packit 5ce601
			isc_log_iwrite(dns_lctx,
Packit 5ce601
				       DNS_LOGCATEGORY_DATABASE,
Packit 5ce601
				       DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
Packit 5ce601
				       isc_msgcat, ISC_MSGSET_GENERAL,
Packit 5ce601
				       ISC_MSG_FAILED, "dns_sdb_putnamedrr");
Packit 5ce601
			return ISC_R_FAILURE;
Packit 5ce601
		}
Packit 5ce601
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	c->c_close(c);
Packit 5ce601
	return ISC_R_SUCCESS;
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static isc_result_t
Packit 5ce601
bdb_destroy(const char *zone, void *unused, void **dbdata)
Packit 5ce601
{
Packit 5ce601
Packit 5ce601
	UNUSED(zone);
Packit 5ce601
	UNUSED(unused);
Packit 5ce601
Packit 5ce601
	(*(DB **)dbdata)->close(*(DB **)dbdata, 0);
Packit 5ce601
Packit 5ce601
	return ISC_R_SUCCESS;
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
isc_result_t
Packit 5ce601
bdb_init(void)
Packit 5ce601
{
Packit 5ce601
	static dns_sdbmethods_t bdb_methods = {
Packit 5ce601
		bdb_lookup,
Packit 5ce601
		NULL,
Packit 5ce601
		bdb_allnodes,
Packit 5ce601
		bdb_create,
Packit 5ce601
		bdb_destroy,
Packit 5ce601
		NULL /* lookup2 */
Packit 5ce601
	};
Packit 5ce601
Packit 5ce601
	return dns_sdb_register(DRIVERNAME, &bdb_methods, NULL, 0, ns_g_mctx,
Packit 5ce601
				&bdb_imp);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
void
Packit 5ce601
bdb_clear(void)
Packit 5ce601
{
Packit 5ce601
Packit 5ce601
	if (bdb_imp != NULL)
Packit 5ce601
		dns_sdb_unregister(&bdb_imp);
Packit 5ce601
}