#ifdef DLZ_BDB
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/formatcheck.h>
#include <isc/lex.h>
#include <isc/mem.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/util.h>
#include <db.h>
static void
show_usage(void);
int
getzone(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
int
gethost(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
void
bdb_cleanup(void);
isc_result_t
bdb_opendb(DBTYPE db_type, DB **db_out, const char *db_name, int flags);
void
put_data(isc_boolean_t dns_data, char *input_key, char *input_data);
void
insert_data(void);
isc_result_t
openBDB(void);
isc_result_t
open_lexer(void);
void
close_lexer(void);
isc_result_t
bulk_write(char type, DB *database, DBC *dbcursor, DBT *bdbkey, DBT *bdbdata);
void
operation_add(void);
void
operation_bulk(void);
void
operation_listOrDelete(isc_boolean_t dlt);
#define max_data_len 10000
#define dlz_data "dns_data"
#define dlz_zone "dns_zone"
#define dlz_host "dns_host"
#define dlz_client "dns_client"
#define BDBparseErr 1
typedef struct bdb_instance {
DB_ENV *dbenv;
DB *data;
DBC *cursor;
DBC *cursor2;
DBC *cursor3;
DBC *cursor4;
DB *zone;
DB *host;
DB *client;
} bdb_instance_t;
#define list 1
#define dele 2
#define add 3
#define bulk 4
#define quit(i) close_lexer(); bdb_cleanup(); exit(i);
#define checkOp(x) if (x != 0) {fprintf(stderr, "\nonly one operation "\
"(l e d a f s) may be specified\n"); quit(2);}
#define checkParam(x, y) if (x != NULL) {fprintf(stderr, "\n%s may only "\
"be specified once\n", y); quit(2);}
#define checkInvalidParam(x, y, z) if (x != NULL) {fprintf(stderr, "\n%s "\
"may not be specified %s\n", y, z); quit(2);}
#define checkInvalidOption(w, x, y, z) if (w == x) {fprintf(stderr, "\n%s "\
"may not be specified %s\n", y, z); quit(2);}
int operation = 0;
isc_boolean_t create_allowed = isc_boolean_false;
char *key = NULL;
isc_boolean_t list_everything = isc_boolean_false;
unsigned int key_val;
char *zone = NULL;
char *host = NULL;
char *c_zone = NULL;
char *c_ip = NULL;
char *a_data = NULL;
char *bulk_file = NULL;
char *db_envdir = NULL;
char *db_file = NULL;
bdb_instance_t db;
isc_lex_t *lexer = NULL;
isc_mem_t *lex_mctx = NULL;
char lex_data_buf[max_data_len];
isc_buffer_t lex_buffer;
static void
show_usage(void) {
fprintf(stderr, "\n\n\
---Usage:---------------------------------------------------------------------\
\n\n\
List data:\n\
dlzbdb -l [-k key] [-z zone] [-h host] [-c client_zone] [-i client_ip]\n\
BDB_environment BDB_database\n\n\
Delete data:\n\
dlzbdb -d [-k key] [-c client_zone] [-i client_ip]\n\
BDB_environment BDB_database\n\n\
Bulk load data from file:\n\
dlzbdb -f file_to_load BDB_environment BDB_database\n\n\
Bulk load data from stdin\n\
dlzbdb -s BDB_environment BDB_database\n\n\
Add data:\n\
dlzbdb -a \"dns data to be added\" BDB_environment BDB_database\n\n\
Export data:\n\
dlzbdb -e BDB_environment BDB_database\n\n\
Normally operations can only be performed on an existing database files.\n\
Use the -n flag with any operation to allow files to be created.\n\
Existing files will NOT be truncated by using the -n flag.\n\
The -n flag will allow a new database to be created, or allow new\n\
environment files to be created for an existing database.\n\n\
---Format for -f & -a options:------------------------------------------------\
\n\n\
db_type zone host dns_type ttl ip\n\
db_type zone host dns_type ttl mx_priority mail_host\n\
db_type zone host dns_type ttl nm_svr resp_psn serial refresh retry expire min\
\n\
db_type zone client_ip\n\n\
---Examples:------------------------------------------------------------------\
\n\n\
d mynm.com www A 10 127.0.0.1\n\
d mynm.com @ MX 10 5 mail\n\
d mynm.com @ SOA 10 ns1.mynm.com. root.mynm.com. 2 28800 7200 604800 86400\n\
c mynm.com 127.0.0.1\n\
c mynm.com 192.168.0.10\n\
");
quit(1);
}
int
getzone(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey) {
char *tmp;
char *left;
char *right;
int result=0;
UNUSED(dbp);
UNUSED(pkey);
tmp = right = malloc(pdata->size + 1);
if (right == NULL) {
result = BDBparseErr;
goto getzone_cleanup;
}
strncpy(right, pdata->data, pdata->size);
right[pdata->size] = '\0';
left = isc_string_separate(&right, " ");
skey->data = strdup(left);
if (skey->data == NULL) {
result = BDBparseErr;
goto getzone_cleanup;
}
skey->size = strlen(skey->data);
skey->flags = DB_DBT_APPMALLOC;
getzone_cleanup:
if (tmp != NULL)
free(tmp);
return result;
}
int
gethost(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey) {
char *tmp;
char *left;
char *right;
int result=0;
UNUSED(dbp);
UNUSED(pkey);
tmp = right = malloc(pdata->size + 1);
if (tmp == NULL) {
result = BDBparseErr;
goto gethost_cleanup;
}
strncpy(right, pdata->data, pdata->size);
right[pdata->size] = '\0';
isc_string_separate(&right, " ");
if (right == NULL) {
result = BDBparseErr;
goto gethost_cleanup;
}
left = isc_string_separate(&right, " ");
skey->data = strdup(left);
if (skey->data == NULL) {
result = BDBparseErr;
goto gethost_cleanup;
}
skey->size = strlen(skey->data);
skey->flags = DB_DBT_APPMALLOC;
gethost_cleanup:
if (tmp != NULL)
free(tmp);
return result;
}
void
bdb_cleanup(void) {
if (db.cursor4 != NULL) {
db.cursor4->c_close(db.cursor4);
db.cursor4 = NULL;
}
if (db.cursor3 != NULL) {
db.cursor3->c_close(db.cursor3);
db.cursor3 = NULL;
}
if (db.cursor2 != NULL) {
db.cursor2->c_close(db.cursor2);
db.cursor2 = NULL;
}
if (db.cursor != NULL) {
db.cursor->c_close(db.cursor);
db.cursor = NULL;
}
if (db.data != NULL) {
db.data->close(db.data, 0);
db.data = NULL;
}
if (db.host != NULL) {
db.host->close(db.host, 0);
db.host = NULL;
}
if (db.zone != NULL) {
db.zone->close(db.zone, 0);
db.zone = NULL;
}
if (db.client != NULL) {
db.client->close(db.client, 0);
db.client = NULL;
}
if (db.dbenv != NULL) {
db.dbenv->close(db.dbenv, 0);
db.dbenv = NULL;
}
}
isc_result_t
bdb_opendb(DBTYPE db_type, DB **db_out, const char *db_name, int flags) {
int result;
int createFlag = 0;
if ((result = db_create(db_out, db.dbenv, 0)) != 0) {
fprintf(stderr, "BDB could not initialize %s database. BDB error: %s",
db_name, db_strerror(result));
return ISC_R_FAILURE;
}
if ((result = (*db_out)->set_flags(*db_out, flags)) != 0) {
fprintf(stderr, "BDB could not set flags for %s database. BDB error: %s",
db_name, db_strerror(result));
return ISC_R_FAILURE;
}
if (create_allowed == isc_boolean_true) {
createFlag = DB_CREATE;
}
if ((result = (*db_out)->open(*db_out, NULL, db_file, db_name, db_type,
createFlag, 0)) != 0) {
fprintf(stderr, "BDB could not open %s database in %s. BDB error: %s",
db_name, db_file, db_strerror(result));
return ISC_R_FAILURE;
}
return ISC_R_SUCCESS;
}
void
put_data(isc_boolean_t dns_data, char *input_key, char *input_data) {
int bdbres;
DBT key, data;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
if (!dns_data && input_key != NULL) {
key.data = input_key;
key.size = strlen(input_key);
key.flags = 0;
}
data.data = input_data;
data.size = strlen(input_data);
data.flags = 0;
if (dns_data) {
bdbres = db.data->put(db.data, NULL, &key, &data, DB_APPEND);
} else {
bdbres = db.client->put(db.client, NULL, &key, &data, 0);
}
if (bdbres != 0) {
fprintf(stderr, "BDB could not insert data. Error: %s",
db_strerror(bdbres));
quit(5);
}
}
void
insert_data(void) {
unsigned int opt =
ISC_LEXOPT_EOL |
ISC_LEXOPT_EOF |
ISC_LEXOPT_QSTRING |
ISC_LEXOPT_QSTRINGMULTILINE;
isc_result_t result;
isc_token_t token;
isc_boolean_t loop = isc_boolean_true;
isc_boolean_t have_czone = isc_boolean_false;
char data_arr[max_data_len];
isc_buffer_t buf;
char data_arr2[max_data_len];
isc_buffer_t buf2;
char data_type = 'u';
isc_buffer_init(&buf, &data_arr, max_data_len);
isc_buffer_init(&buf2, &data_arr2, max_data_len);
while (loop) {
result = isc_lex_gettoken(lexer, opt, &token);
if (result != ISC_R_SUCCESS)
goto data_cleanup;
switch(token.type) {
case isc_tokentype_string:
if (data_type == 'u') {
strncpy(&data_type, token.value.as_pointer, 1);
if (strlen(token.value.as_pointer) > 1 || (
data_type != 'd' && data_type != 'D' &&
data_type != 'c' && data_type != 'C') ) {
data_type = 'b';
}
} else if (data_type == 'c' || data_type == 'C') {
if (have_czone == isc_boolean_true) {
isc_buffer_putstr(&buf2, token.value.as_pointer);
isc_buffer_putmem(&buf2, "\0", 1);
} else {
isc_buffer_putstr(&buf, token.value.as_pointer);
isc_buffer_putmem(&buf, "\0", 1);
have_czone = isc_boolean_true;
}
} else {
isc_buffer_putstr(&buf, token.value.as_pointer);
isc_buffer_putstr(&buf, " ");
}
break;
case isc_tokentype_qstring:
isc_buffer_putstr(&buf, "\"");
isc_buffer_putstr(&buf, token.value.as_pointer);
isc_buffer_putstr(&buf, "\" ");
break;
case isc_tokentype_eol:
case isc_tokentype_eof:
if ((data_type != 'u' && isc_buffer_usedlength(&buf) > 0) || data_type == 'b') {
if (data_type == 'd' || data_type == 'D') {
isc_buffer_putmem(&buf, "\0", 1);
put_data(isc_boolean_true, NULL, (char *) &data_arr);
} else if (data_type == 'c' || data_type == 'C') {
put_data(isc_boolean_false, (char *) &data_arr,
(char *) &data_arr2);
} else if (data_type == 'b') {
fprintf(stderr, "Bad / unknown token encountered on line %lu."\
" Skipping line.", isc_lex_getsourceline(lexer) - 1);
} else {
fprintf(stderr, "Bad / unknown db data type encountered on " \
"line %lu. Skipping line\n", isc_lex_getsourceline(lexer) - 1);
}
}
if (token.type == isc_tokentype_eof) {
loop = isc_boolean_false;
}
isc_buffer_clear(&buf);
isc_buffer_clear(&buf2);
have_czone = isc_boolean_false;
data_type ='u';
break;
default:
data_type = 'b';
break;
}
}
return;
data_cleanup:
fprintf(stderr, "Unknown error processing tokens during \"add\" or " \
"\"bulk\" operation.\nStoped processing on line %lu.",
isc_lex_getsourceline(lexer));
}
isc_result_t
openBDB(void) {
int bdbres;
isc_result_t result;
bdbres = db_env_create(&db.dbenv, 0);
if (bdbres != 0) {
fprintf(stderr, "BDB environment could not be created. BDB error: %s",
db_strerror(bdbres));
result = ISC_R_FAILURE;
goto openBDB_cleanup;
}
if (create_allowed == isc_boolean_true) {
bdbres = db.dbenv->open(db.dbenv, db_envdir,
DB_INIT_CDB | DB_INIT_MPOOL | DB_CREATE, 0);
} else {
bdbres = db.dbenv->open(db.dbenv, db_envdir,
DB_INIT_CDB | DB_INIT_MPOOL, 0);
}
if (bdbres != 0) {
fprintf(stderr, "BDB environment at '%s' could not be opened. BDB " \
"error: %s", db_envdir, db_strerror(bdbres));
result = ISC_R_FAILURE;
goto openBDB_cleanup;
}
result = bdb_opendb(DB_RECNO, &db.data, dlz_data, 0);
if (result != ISC_R_SUCCESS)
goto openBDB_cleanup;
result = bdb_opendb(DB_BTREE, &db.host, dlz_host, DB_DUP | DB_DUPSORT);
if (result != ISC_R_SUCCESS)
goto openBDB_cleanup;
result = bdb_opendb(DB_BTREE, &db.zone, dlz_zone, DB_DUP | DB_DUPSORT);
if (result != ISC_R_SUCCESS)
goto openBDB_cleanup;
result = bdb_opendb(DB_BTREE, &db.client, dlz_client, DB_DUP | DB_DUPSORT);
if (result != ISC_R_SUCCESS)
goto openBDB_cleanup;
bdbres = db.data->associate(db.data, NULL, db.host, gethost, 0);
if (bdbres != 0) {
fprintf(stderr, "BDB could not associate %s database with %s. BDB "\
"error: %s", dlz_host, dlz_data, db_strerror(bdbres));
result = ISC_R_FAILURE;
goto openBDB_cleanup;
}
bdbres = db.data->associate(db.data, NULL, db.zone, getzone, 0);
if (bdbres != 0) {
fprintf(stderr, "BDB could not associate %s database with %s. BDB "\
"error: %s", dlz_zone, dlz_data, db_strerror(bdbres));
result = ISC_R_FAILURE;
goto openBDB_cleanup;
}
return result;
openBDB_cleanup:
bdb_cleanup();
return result;
}
isc_result_t
open_lexer(void) {
isc_result_t result;
if (lexer != NULL)
return ISC_R_SUCCESS;
result = isc_mem_create(0, 0, &lex_mctx);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "unexpected error creating lexer\n");
return result;
}
result = isc_lex_create(lex_mctx, 1500, &lexer);
if (result != ISC_R_SUCCESS)
fprintf(stderr, "unexpected error creating lexer\n");
isc_lex_setcomments(lexer, ISC_LEXCOMMENT_C |
ISC_LEXCOMMENT_CPLUSPLUS |
ISC_LEXCOMMENT_SHELL);
isc_buffer_init(&lex_buffer, &lex_data_buf, max_data_len);
return result;
}
void
close_lexer(void) {
if (lexer != NULL) {
isc_lex_close(lexer);
isc_lex_destroy(&lexer);
}
if (lex_mctx != NULL)
isc_mem_destroy(&lex_mctx);
}
void
operation_add(void) {
checkInvalidParam(key, "k", "for add operation");
checkInvalidParam(zone, "z", "for add operation");
checkInvalidParam(host, "h", "for add operation");
checkInvalidParam(c_zone, "c", "for add operation");
checkInvalidParam(c_ip, "i", "for add operation");
checkInvalidOption(list_everything, isc_boolean_true, "e",
"for add operation");
if (open_lexer() != ISC_R_SUCCESS) {
quit(4);
}
isc_buffer_putstr(&lex_buffer, a_data);
if (isc_lex_openbuffer(lexer, &lex_buffer) != ISC_R_SUCCESS) {
fprintf(stderr, "unexpected error opening lexer buffer");
quit(4);
}
insert_data();
}
void
operation_bulk(void) {
checkInvalidParam(key, "k", "for bulk load operation");
checkInvalidParam(zone, "z", "for bulk load operation");
checkInvalidParam(host, "h", "for bulk load operation");
checkInvalidParam(c_zone, "c", "for bulk load operation");
checkInvalidParam(c_ip, "i", "for bulk load operation");
checkInvalidOption(list_everything, isc_boolean_true, "e",
"for bulk load operation");
if (open_lexer() != ISC_R_SUCCESS) {
quit(4);
}
if (bulk_file == NULL) {
if (isc_lex_openstream(lexer, stdin) != ISC_R_SUCCESS) {
fprintf(stderr, "unexpected error opening stdin by lexer.");
quit(4);
}
} else if (isc_lex_openfile(lexer, bulk_file) != ISC_R_SUCCESS) {
fprintf(stderr, "unexpected error opening %s by lexer.", bulk_file);
quit(4);
}
insert_data();
}
isc_result_t
bulk_write(char type, DB *database, DBC *dbcursor, DBT *bdbkey, DBT *bdbdata) {
int bdbres;
db_recno_t recNum;
char *retkey = NULL, *retdata;
size_t retklen = 0, retdlen;
void *p;
int buffer_size = 5 * 1024 * 1024;
bdbdata->data = malloc(buffer_size);
if (bdbdata->data == NULL) {
fprintf(stderr,
"Unable to allocate 5 MB buffer for bulk database dump\n");
return ISC_R_FAILURE;
}
bdbdata->ulen = buffer_size;
bdbdata->flags = DB_DBT_USERMEM;
bdbres = database->cursor(database, NULL, &dbcursor, 0);
if (bdbres != 0) {
fprintf(stderr, "Unexpected error. BDB Error: %s\n",db_strerror(bdbres));
free(bdbdata->data);
return ISC_R_FAILURE;
}
for (;;) {
bdbres = dbcursor->c_get(dbcursor, bdbkey, bdbdata,
DB_MULTIPLE_KEY | DB_NEXT);
if (bdbres != 0) {
if (bdbres != DB_NOTFOUND) {
fprintf(stderr, "Unexpected error. BDB Error: %s\n",
db_strerror(bdbres));
free(bdbdata->data);
return ISC_R_FAILURE;
}
break;
}
for (DB_MULTIPLE_INIT(p, bdbdata);;) {
if (type == 'c')
DB_MULTIPLE_KEY_NEXT(p, bdbdata, retkey, retklen, retdata, retdlen);
else
DB_MULTIPLE_RECNO_NEXT(p, bdbdata, recNum, retdata, retdlen);
if (p == NULL)
break;
if (type == 'c')
printf("c %.*s %.*s\n",(int)retklen, retkey,(int)retdlen, retdata);
else
printf("d %.*s\n", (int)retdlen, retdata);
}
}
free(bdbdata->data);
return ISC_R_SUCCESS;
}
void
operation_listOrDelete(isc_boolean_t dlt) {
int bdbres = 0;
DBC *curList[3];
DBT bdbkey, bdbdata;
db_recno_t recno;
int curIndex = 0;
if (dlt == isc_boolean_true) {
checkInvalidParam(zone, "z", "for delete operation");
checkInvalidParam(host, "h", "for delete operation");
checkInvalidOption(list_everything, isc_boolean_true, "e",
"for delete operation");
checkInvalidOption(create_allowed, isc_boolean_true, "n",
"for delete operation");
} else if (key != NULL || zone != NULL || host != NULL) {
checkInvalidParam(c_zone, "c", "for list when k, z or h are specified");
checkInvalidParam(c_ip, "i", "for list when k, z, or h are specified");
checkInvalidOption(list_everything, isc_boolean_true, "e",
"for list when k, z, or h are specified");
checkInvalidOption(create_allowed, isc_boolean_true, "n",
"for list operation");
} else if (c_ip != NULL || c_zone != NULL) {
checkInvalidOption(list_everything, isc_boolean_true, "e",
"for list when c or i are specified");
checkInvalidOption(create_allowed, isc_boolean_true, "n",
"for list operation");
}
memset(&bdbkey, 0, sizeof(bdbkey));
memset(&bdbdata, 0, sizeof(bdbdata));
if (list_everything == isc_boolean_true) {
if (bulk_write('c', db.client, db.cursor, &bdbkey, &bdbdata)
!= ISC_R_SUCCESS)
return;
memset(&bdbkey, 0, sizeof(bdbkey));
memset(&bdbdata, 0, sizeof(bdbdata));
bulk_write('d', db.data, db.cursor2, &bdbkey, &bdbdata);
return;
}
curList[1] = curList[2] = NULL;
if (key != NULL) {
checkInvalidParam(zone, "z", "when k is specified");
checkInvalidParam(host, "h", "when k is specified");
recno = key_val;
bdbkey.data = &recno;
bdbkey.size = sizeof(recno);
if (dlt == isc_boolean_true) {
bdbres = db.data->del(db.data, NULL, &bdbkey, 0);
} else {
bdbdata.flags = DB_DBT_REALLOC;
bdbres = db.data->get(db.data, NULL, &bdbkey, &bdbdata, 0);
if (bdbres == 0) {
printf("KEY | DATA\n");
printf("%lu | %.*s\n", *(u_long *) bdbkey.data,
(int)bdbdata.size, (char *)bdbdata.data);
}
}
if (bdbres == DB_NOTFOUND) {
printf("Key not found in database");
}
}
if (zone != NULL) {
bdbres = db.zone->cursor(db.zone, NULL, &db.cursor2, 0);
if (bdbres != 0) {
fprintf(stderr, "Unexpected error. BDB Error: %s\n",
db_strerror(bdbres));
return;
}
bdbkey.data = zone;
bdbkey.size = strlen(zone);
bdbres = db.cursor2->c_get(db.cursor2, &bdbkey, &bdbdata, DB_SET);
if (bdbres != 0) {
if (bdbres != DB_NOTFOUND) {
fprintf(stderr, "Unexpected error. BDB Error: %s\n",
db_strerror(bdbres));
} else {
printf("Zone not found in database");
}
return;
}
curList[curIndex++] = db.cursor2;
}
if (host != NULL) {
bdbres = db.host->cursor(db.host, NULL, &db.cursor3, 0);
if (bdbres != 0) {
fprintf(stderr, "Unexpected error. BDB Error: %s\n",
db_strerror(bdbres));
return;
}
bdbkey.data = host;
bdbkey.size = strlen(host);
bdbres = db.cursor3->c_get(db.cursor3, &bdbkey, &bdbdata, DB_SET);
if (bdbres != 0) {
if (bdbres != DB_NOTFOUND) {
fprintf(stderr, "Unexpected error. BDB Error: %s\n",
db_strerror(bdbres));
} else {
printf("Host not found in database");
}
return;
}
curList[curIndex++] = db.cursor3;
}
if (zone != NULL || host != NULL) {
bdbres = db.data->join(db.data, curList, &db.cursor4, 0);
if (bdbres != 0) {
fprintf(stderr, "Unexpected error. BDB Error: %s\n",
db_strerror(bdbres));
return;
}
memset(&bdbkey, 0, sizeof(bdbkey));
bdbkey.flags = DB_DBT_REALLOC;
memset(&bdbdata, 0, sizeof(bdbdata));
bdbdata.flags = DB_DBT_REALLOC;
printf("KEY | DATA\n");
while (bdbres == 0) {
bdbres = db.cursor4->c_get(db.cursor4, &bdbkey, &bdbdata, 0);
if (bdbres != 0) {
break;
}
printf("%lu | %.*s\n", *(u_long *) bdbkey.data,
(int)bdbdata.size, (char *)bdbdata.data);
}
}
if (c_ip != NULL && c_zone == NULL) {
fprintf(stderr, "i may only be specified when c is also specified\n");
quit(2);
}
if (c_zone != NULL) {
if (dlt == isc_boolean_true) {
bdbres = db.client->cursor(db.client, NULL, &db.cursor,
DB_WRITECURSOR);
} else {
bdbres = db.client->cursor(db.client, NULL, &db.cursor, 0);
printf("CLIENT_ZONE | CLIENT_IP\n");
}
bdbkey.data = c_zone;
bdbkey.size = strlen(c_zone);
if (c_ip != NULL) {
bdbdata.data = c_ip;
bdbdata.size = strlen(c_ip);
bdbres = db.cursor->c_get(db.cursor, &bdbkey, &bdbdata, DB_GET_BOTH);
if (bdbres == DB_NOTFOUND) {
printf("Client zone & IP not found in database");
}
} else {
bdbdata.flags = DB_DBT_REALLOC;
bdbres = db.cursor->c_get(db.cursor, &bdbkey, &bdbdata, DB_SET);
if (bdbres == DB_NOTFOUND) {
printf("Client zone not found in database");
}
}
while (bdbres == 0) {
if (dlt == isc_boolean_false) {
printf("%.*s | %.*s\n", (int)bdbkey.size, (char *) bdbkey.data,
(int)bdbdata.size, (char *) bdbdata.data);
} else {
bdbres = db.cursor->c_del(db.cursor, 0);
if (bdbres != 0) {
fprintf(stderr, "Unexpected error. BDB Error: %s\n",
db_strerror(bdbres));
break;
}
}
if (c_ip != NULL) {
break;
}
bdbres = db.cursor->c_get(db.cursor, &bdbkey, &bdbdata, DB_NEXT_DUP);
if (bdbres != 0) {
break;
}
}
}
if (bdbres != 0 && bdbres != DB_NOTFOUND) {
fprintf(stderr, "Unexpected error during list operation " \
"BDB error: %s", db_strerror(bdbres));
}
if (bdbkey.flags == DB_DBT_REALLOC && bdbkey.data != NULL) {
free(bdbkey.data);
}
if (bdbdata.flags == DB_DBT_REALLOC && bdbdata.data != NULL) {
free(bdbdata.data);
}
}
int
main(int argc, char **argv) {
int ch;
char *endp;
if (argc < 2)
show_usage();
while ((ch= isc_commandline_parse(argc, argv, "ldesna:f:k:z:h:c:i:")) != -1) {
switch (ch) {
case 'n':
create_allowed = isc_boolean_true;
break;
case 'l':
checkOp(operation);
operation = list;
break;
case 'd':
checkOp(operation);
operation = dele;
break;
case 'a':
checkOp(operation);
operation = add;
a_data = isc_commandline_argument;
break;
case 'f':
checkOp(operation);
operation = bulk;
bulk_file = isc_commandline_argument;
break;
case 's':
checkOp(operation);
operation = bulk;
break;
case 'k':
checkParam(key, "k");
key = isc_commandline_argument;
key_val = strtoul(key, &endp, 10);
if (*endp != '\0' || key_val < 1) {
fprintf(stderr, "Error converting key to integer");
}
break;
case 'z':
checkParam(zone, "z");
zone = isc_commandline_argument;
break;
case 'h':
checkParam(host, "h");
host = isc_commandline_argument;
break;
case 'c':
checkParam(c_zone, "c");
c_zone = isc_commandline_argument;
break;
case 'i':
checkParam(c_ip, "i");
c_ip = isc_commandline_argument;
break;
case 'e':
checkOp(operation);
operation = list;
list_everything = isc_boolean_true;
break;
case '?':
show_usage();
break;
default:
fprintf(stderr, "unexpected error parsing command arguments\n");
quit(1);
break;
}
}
argc -= isc_commandline_index;
argv += isc_commandline_index;
if (argc < 2) {
fprintf(stderr, "Both a Berkeley DB environment and file "\
"must be specified");
quit(2);
} else if (argc > 2) {
fprintf(stderr, "Too many parameters. Check command line for errors.");
quit(2);
}
db_envdir = argv[0];
db_file = argv[1];
if (openBDB() != ISC_R_SUCCESS) {
bdb_cleanup();
quit(3);
}
switch(operation) {
case list:
operation_listOrDelete(isc_boolean_false);
break;
case dele:
operation_listOrDelete(isc_boolean_true);
break;
case add:
operation_add();
break;
case bulk:
operation_bulk();
break;
default:
fprintf(stderr, "\nNo operation was selected. "\
"Select an operation (l d a f)");
quit(2);
break;
}
quit(0);
}
#endif