dlzbdb.c
来自「非常好的dns解析软件」· C语言 代码 · 共 1,274 行 · 第 1/3 页
C
1,274 行
/* * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. * * 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 STICHTING NLNET * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * STICHTING NLNET 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. * * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was * conceived and contributed by Rob Butler. * * 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 ROB BUTLER * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * ROB BUTLER 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. *//* * Copyright (C) 1999-2001 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 INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM 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. */#ifdef DLZ_BDB/* * exit codes * 0 everything ok * 1 error parsing command line * 2 Missing, too many or invalid combination of command line parameters * 3 Unable to open BDB database. * 4 Unable to allocate memory for, or create lexer. * 5 unable to perform BDB cursor operation */#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>/* shut up compiler warnings about no previous prototype */static voidshow_usage(void);intgetzone(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);intgethost(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);voidbdb_cleanup(void);isc_result_tbdb_opendb(DBTYPE db_type, DB **db_out, const char *db_name, int flags);voidput_data(isc_boolean_t dns_data, char *input_key, char *input_data);voidinsert_data(void);isc_result_topenBDB(void);isc_result_topen_lexer(void);voidclose_lexer(void);isc_result_tbulk_write(char type, DB *database, DBC *dbcursor, DBT *bdbkey, DBT *bdbdata);voidoperation_add(void);voidoperation_bulk(void);voidoperation_listOrDelete(isc_boolean_t dlt); /*% * Maximum length of a single data line that * may be inserted into database by this program. * If you need to insert a line of data that is more * than 10,000 characters change this definition. */#define max_data_len 10000/*% * BDB database names. If you want to use different * database names change them here. */#define dlz_data "dns_data"#define dlz_zone "dns_zone"#define dlz_host "dns_host"#define dlz_client "dns_client"/*% * Error code returned by BDB secondary index callback functions. * This error is returned if the callback function could not create * the secondary index for any reason. */#define BDBparseErr 1/* A struct to hold all the relevant info about the database */typedef struct bdb_instance { DB_ENV *dbenv; /* BDB environment */ DB *data; /* dns_data database handle */ DBC *cursor; /* database cursor */ DBC *cursor2; /* second cursor used during list operation. */ DBC *cursor3; /* third cursor used during list operation */ DBC *cursor4; /* fourth cursor used during list operation */ DB *zone; /* zone database handle */ DB *host; /* host database handle */ DB *client; /* client database handle */} bdb_instance_t;/* Possible operations */#define list 1 /* list data */#define dele 2 /* delete data */#define add 3 /* add a single piece of data */#define bulk 4 /* bulk load data *//*% * quit macro is used instead of exit. quit always trys to close the lexer * and the BDB database before exiting. */#define quit(i) close_lexer(); bdb_cleanup(); exit(i);/*% * checkOp is used to verify that only one operation (list, del, add, * bulk from file, bulk from stdin) is specified on the command line. * This prevents a user from specifying two operations on the command * line, which would make no sense anyway. */#define checkOp(x) if (x != 0) {fprintf(stderr, "\nonly one operation "\ "(l e d a f s) may be specified\n"); quit(2);}/*% * checkParam is used to only allow a parameter to be specified once. * I.E. the parameter key can only be used on the command line once. * any attempt to use it twice causes an error. */#define checkParam(x, y) if (x != NULL) {fprintf(stderr, "\n%s may only "\ "be specified once\n", y); quit(2);}/*% * checkInvalidParam is used to only allow paramters which make sense for * the operation selected. I.E. passing the key parameter makes no sense * for the add operation, and thus it isn't allowed. */#define checkInvalidParam(x, y, z) if (x != NULL) {fprintf(stderr, "\n%s "\ "may not be specified %s\n", y, z); quit(2);}/*% * checkInvalidOption is used to only allow paramters which make sense for * the operation selected - but checks boolean options. * I.E. passing the "b" bare_list parameter makes no sense for the add * operation, and thus it isn't allowed. * if w == x then output error message "flag", "message" */#define checkInvalidOption(w, x, y, z) if (w == x) {fprintf(stderr, "\n%s "\ "may not be specified %s\n", y, z); quit(2);}/* Global Variables */int operation = 0; /*%< operation to perform. *//*% allow new lock files or DB to be created. */isc_boolean_t create_allowed = isc_boolean_false;char *key = NULL; /*%< key to use in list & del operations *//*% dump DB in DLZBDB bulk format */isc_boolean_t list_everything = isc_boolean_false; unsigned int key_val; /*%< key as unsigned int used in list & del operations */char *zone = NULL; /*%< zone to use in list operations */char *host = NULL; /*%< host to use in list operations */char *c_zone = NULL; /*%< client zone to use in list operations */char *c_ip = NULL; /*%< client IP to use in list operations */char *a_data = NULL; /*%< data in add operation */char *bulk_file = NULL; /*%< bulk data file to load */char *db_envdir = NULL; /*%< BDB environment location */char *db_file = NULL; /*%< BDB database file location. */bdb_instance_t db; /* BDB instance we are operating on */isc_lex_t *lexer = NULL; /*%< lexer for use to use in parsing input */isc_mem_t *lex_mctx = NULL; /*%< memory context for lexer */char lex_data_buf[max_data_len]; /*%< data array to use for lex_buffer below */isc_buffer_t lex_buffer; /*%< buffer for lexer during add operation */ /*% * Displays usage message */static voidshow_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);}/*% BDB callback to create zone secondary index */intgetzone(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey) { char *tmp; char *left; char *right; int result=0; UNUSED(dbp); UNUSED(pkey); /* Allocate memory to use in parsing the string */ tmp = right = malloc(pdata->size + 1); /* verify memory was allocated */ if (right == NULL) { result = BDBparseErr; goto getzone_cleanup; } /* copy data string into newly allocated memory */ strncpy(right, pdata->data, pdata->size); right[pdata->size] = '\0'; /* split string at the first space */ left = isc_string_separate(&right, " "); /* copy string for "zone" secondary index */ skey->data = strdup(left); if (skey->data == NULL) { result = BDBparseErr; goto getzone_cleanup; } /* set required values for BDB */ skey->size = strlen(skey->data); skey->flags = DB_DBT_APPMALLOC; getzone_cleanup: /* cleanup memory */ if (tmp != NULL) free(tmp); return result;}/*% * BDB callback to create host secondary index */intgethost(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey) { char *tmp; char *left; char *right; int result=0; UNUSED(dbp); UNUSED(pkey); /* allocate memory to use in parsing the string */ tmp = right = malloc(pdata->size + 1); /* verify memory was allocated */ if (tmp == NULL) { result = BDBparseErr; goto gethost_cleanup; } /* copy data string into newly allocated memory */ strncpy(right, pdata->data, pdata->size); right[pdata->size] = '\0'; /* we don't care about left string. */ /* memory of left string will be freed when tmp is freed. */ isc_string_separate(&right, " "); /* verify right still has some characters left */ if (right == NULL) { result = BDBparseErr; goto gethost_cleanup; } /* get "host" from data string */ left = isc_string_separate(&right, " "); /* copy string for "host" secondary index */ skey->data = strdup(left); if (skey->data == NULL) { result = BDBparseErr; goto gethost_cleanup; } /* set required values for BDB */ skey->size = strlen(skey->data); skey->flags = DB_DBT_APPMALLOC; gethost_cleanup: /* cleanup memory */ if (tmp != NULL) free(tmp); return result;}/*% * Performs BDB cleanup. Close each database that we opened. * Close environment. Set each var to NULL so we know they * were closed and don't accidentally try to close them twice. */voidbdb_cleanup(void) { /* close cursors */ 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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?