dlz_bdbhpt_driver.c

来自「非常好的dns解析软件」· C语言 代码 · 共 861 行 · 第 1/2 页

C
861
字号
		free(tmp);	if (tmp_zone_host != NULL)		free(tmp_zone_host);	if (tmp_zone != NULL)		free(tmp_zone);	/* get rid of cursors */	if (xfr_cursor != NULL)		xfr_cursor->c_close(xfr_cursor);	if (dns_cursor != NULL)		dns_cursor->c_close(xfr_cursor);	return result;}/*% * Performs bdbhpt cleanup. * Used by bdbhpt_create if there is an error starting up. * Used by bdbhpt_destroy when the driver is shutting down. */static voidbdbhpt_cleanup(bdbhpt_instance_t *db) {	isc_mem_t *mctx;	/* close databases */	if (db->data != NULL)		db->data->close(db->data, 0);	if (db->xfr != NULL)		db->xfr->close(db->xfr, 0);	if (db->zone != NULL)		db->zone->close(db->zone, 0);	if (db->client != NULL)		db->client->close(db->client, 0);	/* close environment */	if (db->dbenv != NULL)		db->dbenv->close(db->dbenv, 0);	/* cleanup memory */	if (db->mctx != NULL) {		/* save mctx for later */		mctx = db->mctx;		/* return, and detach the memory */		isc_mem_put(mctx, db, sizeof(bdbhpt_instance_t));		isc_mem_detach(&mctx);	}}static isc_result_tbdbhpt_findzone(void *driverarg, void *dbdata, const char *name){	isc_result_t result;	bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;	DBT key, data;	UNUSED(driverarg);	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	data.flags = DB_DBT_MALLOC;	key.data = strdup(name);	if (key.data == NULL)		return (ISC_R_NOMEMORY);	/*	 * reverse string to take advantage of BDB locality of reference	 * if we need futher lookups because the zone doesn't match the	 * first time.	 */	key.data = bdbhpt_strrev(key.data);	key.size = strlen(key.data);	switch(db->zone->get(db->zone, NULL, &key, &data, 0)) {	case DB_NOTFOUND:		result = ISC_R_NOTFOUND;		break;	case 0:		result = ISC_R_SUCCESS;		break;	default:		result = ISC_R_FAILURE;	}	/* free any memory duplicate string in the key field */	if (key.data != NULL)		free(key.data);	/* free any memory allocated to the data field. */	if (data.data != NULL)		free(data.data);	return result;}static isc_result_tbdbhpt_lookup(const char *zone, const char *name, void *driverarg,	      void *dbdata, dns_sdlzlookup_t *lookup){	isc_result_t result = ISC_R_NOTFOUND;	bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;	DBC *data_cursor = NULL;	DBT key, data;	int bdbhptres;	int flags;	bdbhpt_parsed_data_t pd;	char *tmp = NULL;	char *keyStr = NULL;	UNUSED(driverarg);	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	key.size = strlen(zone) + strlen(name) + 1;	/* allocate mem for key */	key.data = keyStr = malloc((key.size + 1) * sizeof(char));	if (keyStr == NULL)		return ISC_R_NOMEMORY;	strcpy(keyStr, zone);	strcat(keyStr, " ");	strcat(keyStr, name);	/* get a cursor to loop through data */	if (db->data->cursor(db->data, NULL, &data_cursor, 0) != 0) {		result = ISC_R_FAILURE;		goto lookup_cleanup;	}	result = ISC_R_NOTFOUND;	flags = DB_SET;	while ((bdbhptres = data_cursor->c_get(data_cursor, &key, &data,					       flags)) == 0) {		flags = DB_NEXT_DUP;		tmp = realloc(tmp, data.size + 1);		if (tmp == NULL)			goto lookup_cleanup;		strncpy(tmp, data.data, data.size);		tmp[data.size] = '\0';		if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS)			goto lookup_cleanup;		result = dns_sdlz_putrr(lookup, pd.type, pd.ttl, pd.data);		if (result != ISC_R_SUCCESS)			goto lookup_cleanup;	} /* end while loop */ lookup_cleanup:	/* get rid of cursor */	if (data_cursor != NULL)		data_cursor->c_close(data_cursor);	if (keyStr != NULL)		free(keyStr);	if (tmp != NULL)		free(tmp);	return result;}/*% Initializes, sets flags and then opens Berkeley databases. */static isc_result_tbdbhpt_opendb(DB_ENV *db_env, DBTYPE db_type, DB **db, const char *db_name,	      char *db_file, int flags) {	int result;	/* Initialize the database. */	if ((result = db_create(db, db_env, 0)) != 0) {		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "bdbhpt could not initialize %s database. "			      "bdbhpt error: %s",			      db_name, db_strerror(result));		return ISC_R_FAILURE;	}	/* set database flags. */	if ((result = (*db)->set_flags(*db, flags)) != 0) {		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "bdbhpt could not set flags for %s database. "			      "bdbhpt error: %s",			      db_name, db_strerror(result));		return ISC_R_FAILURE;	}	/* open the database. */	if ((result = (*db)->open(*db, NULL, db_file, db_name, db_type,				  DB_RDONLY | bdbhpt_threads, 0)) != 0) {		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "bdbhpt could not open %s database in %s. "			      "bdbhpt error: %s",			      db_name, db_file, db_strerror(result));		return ISC_R_FAILURE;	}	return ISC_R_SUCCESS;}static isc_result_tbdbhpt_create(const char *dlzname, unsigned int argc, char *argv[],	      void *driverarg, void **dbdata){	isc_result_t result;	int bdbhptres;	int bdbFlags = 0;	bdbhpt_instance_t *db = NULL;	UNUSED(dlzname);	UNUSED(driverarg);	/* verify we have 4 arg's passed to the driver */	if (argc != 4) {		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "bdbhpt driver requires at least "			      "3 command line args.");		return (ISC_R_FAILURE);	}	switch((char) *argv[1]) {		/*		 * Transactional mode.  Highest safety - lowest speed.		 */	case 'T':	case 't':		bdbFlags = DB_INIT_MPOOL | DB_INIT_LOCK |			   DB_INIT_LOG | DB_INIT_TXN;		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),			      "bdbhpt driver using transactional mode.");		break;		/*		 * Concurrent mode.  Lower safety (no rollback) -		 * higher speed.		 */	case 'C':	case 'c':		bdbFlags = DB_INIT_CDB | DB_INIT_MPOOL;		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),			      "bdbhpt driver using concurrent mode.");		break;		/*		 * Private mode. No inter-process communication & no locking.		 * Lowest saftey - highest speed.		 */	case 'P':	case 'p':		bdbFlags = DB_PRIVATE | DB_INIT_MPOOL;		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),			      "bdbhpt driver using private mode.");		break;	default:		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "bdbhpt driver requires the operating mode "			      "be set to P or C or T.  You specified '%s'",			      argv[1]);		return (ISC_R_FAILURE);	}	/* allocate and zero memory for driver structure */	db = isc_mem_get(ns_g_mctx, sizeof(bdbhpt_instance_t));	if (db == NULL) {		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "Could not allocate memory for "			      "database instance object.");		return (ISC_R_NOMEMORY);	}	memset(db, 0, sizeof(bdbhpt_instance_t));	/* attach to the memory context */	isc_mem_attach(ns_g_mctx, &db->mctx);	/*	 * create bdbhpt environment	 * Basically bdbhpt allocates and assigns memory to db->dbenv	 */	bdbhptres = db_env_create(&db->dbenv, 0);	if (bdbhptres != 0) {		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "bdbhpt environment could not be created. "			      "bdbhpt error: %s",			      db_strerror(bdbhptres));		result = ISC_R_FAILURE;		goto init_cleanup;	}	/* open bdbhpt environment */	bdbhptres = db->dbenv->open(db->dbenv, argv[2],				    bdbFlags | bdbhpt_threads | DB_CREATE, 0);	if (bdbhptres != 0) {		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "bdbhpt environment at '%s' could not be opened."			      " bdbhpt error: %s",			      argv[2], db_strerror(bdbhptres));		result = ISC_R_FAILURE;		goto init_cleanup;	}	/* open dlz_data database. */	result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->data,			       dlz_data, argv[3], DB_DUP | DB_DUPSORT);	if (result != ISC_R_SUCCESS)		goto init_cleanup;	/* open dlz_xfr database. */	result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->xfr,			       dlz_xfr, argv[3], DB_DUP | DB_DUPSORT);	if (result != ISC_R_SUCCESS)		goto init_cleanup;	/* open dlz_zone database. */	result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->zone,			       dlz_zone, argv[3], 0);	if (result != ISC_R_SUCCESS)		goto init_cleanup;	/* open dlz_client database. */	result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->client,			       dlz_client, argv[3], DB_DUP | DB_DUPSORT);	if (result != ISC_R_SUCCESS)		goto init_cleanup;	*dbdata = db;	return(ISC_R_SUCCESS); init_cleanup:	bdbhpt_cleanup(db);	return result;}static voidbdbhpt_destroy(void *driverarg, void *dbdata){	UNUSED(driverarg);	bdbhpt_cleanup((bdbhpt_instance_t *) dbdata);}/* * bdbhpt_authority not needed as authority data is returned by lookup */static dns_sdlzmethods_t dlz_bdbhpt_methods = {	bdbhpt_create,	bdbhpt_destroy,	bdbhpt_findzone,	bdbhpt_lookup,	NULL,	bdbhpt_allnodes,	bdbhpt_allowzonexfr};/*% * Wrapper around dns_sdlzregister(). */isc_result_tdlz_bdbhpt_init(void) {	isc_result_t result;	/*	 * Write debugging message to log	 */	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,		      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),		      "Registering DLZ bdbhpt driver.");	result = dns_sdlzregister("bdbhpt", &dlz_bdbhpt_methods, NULL,				  DNS_SDLZFLAG_RELATIVEOWNER |				  DNS_SDLZFLAG_RELATIVERDATA |				  DNS_SDLZFLAG_THREADSAFE,				  ns_g_mctx, &dlz_bdbhpt);	if (result != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "dns_sdlzregister() failed: %s",				 isc_result_totext(result));		result = ISC_R_UNEXPECTED;	}	return result;}/*% * Wrapper around dns_sdlzunregister(). */voiddlz_bdbhpt_clear(void) {	/*	 * Write debugging message to log	 */	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,		      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),		      "Unregistering DLZ bdbhpt driver.");	if (dlz_bdbhpt != NULL)		dns_sdlzunregister(&dlz_bdbhpt);}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?