dlz_filesystem_driver.c
来自「非常好的dns解析软件」· C语言 代码 · 共 1,049 行 · 第 1/2 页
C
1,049 行
data = strchr(ttlStr, cd->separator); if (data == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Filesystem driver: " "%s could not be parsed properly", tmp); return ISC_R_FAILURE; } /* replace separator char with NULL to split string */ data[0] = '\0'; /* start string after NULL of previous string */ data = (char *) &data[1]; /* replace all cd->separator chars with a space. */ len = strlen(data); for (i=0; i < len; i++) { if (data[i] == cd->separator) data[i] = ' '; } /* convert text to int, make sure it worked right */ ttl = strtol(ttlStr, &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Filesystem driver " "ttl must be a postive number"); } /* pass data back to Bind */ if (dir_list == NULL) result = dns_sdlz_putrr((dns_sdlzlookup_t *) passback, type, ttl, data); else result = dns_sdlz_putnamedrr((dns_sdlzallnodes_t *) passback, (char *) host, type, ttl, data); /* if error, return error right away */ if (result != ISC_R_SUCCESS) return result; } /* end of while loop */ return result;}/* * SDLZ interface methods */static isc_result_tfs_allowzonexfr(void *driverarg, void *dbdata, const char *name, const char *client){ isc_result_t result; char *path; struct stat sb; config_data_t *cd; path = NULL; UNUSED(driverarg); cd = (config_data_t *) dbdata; if (create_path(name, NULL, client, cd, &path) != ISC_R_SUCCESS) { return (ISC_R_NOTFOUND); } if (stat(path, &sb) != 0) { result = ISC_R_NOTFOUND; goto complete_AXFR; } if ((sb.st_mode & S_IFREG) != 0) { result = ISC_R_SUCCESS; goto complete_AXFR; } result = ISC_R_NOTFOUND; complete_AXFR: isc_mem_free(ns_g_mctx, path); return result;}static isc_result_tfs_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes){ isc_result_t result; dlist_t *dir_list; config_data_t *cd; char *basepath; unsigned int basepathlen; struct stat sb; isc_dir_t dir; dir_entry_t *dir_entry; dir_entry_t *next_de; basepath = NULL; dir_list = NULL; UNUSED(driverarg); UNUSED(allnodes); cd = (config_data_t *) dbdata; /* allocate memory for list */ dir_list = isc_mem_get(ns_g_mctx, sizeof(dlist_t)); if (dir_list == NULL) { result = ISC_R_NOTFOUND; goto complete_allnds; } /* initialize list */ ISC_LIST_INIT(*dir_list); if (create_path(zone, NULL, NULL, cd, &basepath) != ISC_R_SUCCESS) { return (ISC_R_NOTFOUND); } /* remove path separator at end of path so stat works properly */ basepathlen = strlen(basepath); if (stat(basepath, &sb) != 0) { result = ISC_R_NOTFOUND; goto complete_allnds; } if ((sb.st_mode & S_IFDIR) == 0) { result = ISC_R_NOTFOUND; goto complete_allnds; } /* initialize and open directory */ isc_dir_init(&dir); result = isc_dir_open(&dir, basepath); /* if directory open failed, return error. */ if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Unable to open %s directory to read entries.", basepath); result = ISC_R_FAILURE; goto complete_allnds; } /* process the directory */ result = process_dir(dir, allnodes, cd, dir_list, basepathlen); /* close the directory */ isc_dir_close(&dir); if (result != ISC_R_SUCCESS) goto complete_allnds; /* get first dir entry from list. */ dir_entry = ISC_LIST_HEAD(*dir_list); while (dir_entry != NULL) { result = isc_dir_open(&dir, dir_entry->dirpath); /* if directory open failed, return error. */ if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Unable to open %s " "directory to read entries.", basepath); result = ISC_R_FAILURE; goto complete_allnds; } /* process the directory */ result = process_dir(dir, allnodes, cd, dir_list, basepathlen); /* close the directory */ isc_dir_close(&dir); if (result != ISC_R_SUCCESS) goto complete_allnds; dir_entry = ISC_LIST_NEXT(dir_entry, link); } /* end while */ complete_allnds: if (dir_list != NULL) { /* clean up entries from list. */ dir_entry = ISC_LIST_HEAD(*dir_list); while (dir_entry != NULL) { next_de = ISC_LIST_NEXT(dir_entry, link); isc_mem_put(ns_g_mctx, dir_entry, sizeof(dir_entry_t)); dir_entry = next_de; } /* end while */ isc_mem_put(ns_g_mctx, dir_list, sizeof(dlist_t)); } if (basepath != NULL) isc_mem_free(ns_g_mctx, basepath); return result;}static isc_result_tfs_findzone(void *driverarg, void *dbdata, const char *name){ isc_result_t result; char *path; struct stat sb; path = NULL; UNUSED(driverarg); if (create_path(name, NULL, NULL, (config_data_t *) dbdata, &path) != ISC_R_SUCCESS) { return (ISC_R_NOTFOUND); } isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1), "Filesystem driver Findzone() Checking for path: '%s'\n", path); if (stat(path, &sb) != 0) { result = ISC_R_NOTFOUND; goto complete_FZ; } if ((sb.st_mode & S_IFDIR) != 0) { result = ISC_R_SUCCESS; goto complete_FZ; } result = ISC_R_NOTFOUND; complete_FZ: isc_mem_free(ns_g_mctx, path); return result;}static isc_result_tfs_lookup(const char *zone, const char *name, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup){ isc_result_t result; char *path; struct stat sb; isc_dir_t dir; path = NULL; UNUSED(driverarg); UNUSED(lookup); if (strcmp(name, "*") == 0) /* * handle filesystem's special wildcard "-" */ result = create_path(zone, "-", NULL, (config_data_t *) dbdata, &path); else result = create_path(zone, name, NULL, (config_data_t *) dbdata, &path); if ( result != ISC_R_SUCCESS) { return (ISC_R_NOTFOUND); } /* remove path separator at end of path so stat works properly */ path[strlen(path)-1] = '\0'; isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1), "Filesystem driver lookup() Checking for path: '%s'\n", path); if (stat(path, &sb) != 0) { result = ISC_R_NOTFOUND; goto complete_lkup; } if ((sb.st_mode & S_IFDIR) == 0) { result = ISC_R_NOTFOUND; goto complete_lkup; } /* initialize and open directory */ isc_dir_init(&dir); result = isc_dir_open(&dir, path); /* if directory open failed, return error. */ if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Unable to open %s directory to read entries.", path); result = ISC_R_FAILURE; goto complete_lkup; } /* process any records in the directory */ result = process_dir(dir, lookup, (config_data_t *) dbdata, NULL, 0); /* close the directory */ isc_dir_close(&dir); complete_lkup: isc_mem_free(ns_g_mctx, path); return result;}static isc_result_tfs_create(const char *dlzname, unsigned int argc, char *argv[], void *driverarg, void **dbdata){ config_data_t *cd; char *endp; int len; char pathsep; UNUSED(driverarg); UNUSED(dlzname); /* we require 5 command line args. */ if (argc != 6) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Filesystem driver requires " "6 command line args."); return (ISC_R_FAILURE); } if (strlen(argv[5]) > 1) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Filesystem driver can only " "accept a single character for separator."); return (ISC_R_FAILURE); } /* verify base dir ends with '/' or '\' */ len = strlen(argv[1]); if (argv[1][len-1] != '\\' && argv[1][len-1] != '/') { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Base dir parameter for filesystem driver " "should end with %s", "either '/' or '\\' "); return (ISC_R_FAILURE); } /* determine and save path separator for later */ if (argv[1][len-1] == '\\') pathsep = '\\'; else pathsep = '/'; /* allocate memory for our config data */ cd = isc_mem_get(ns_g_mctx, sizeof(config_data_t)); if (cd == NULL) goto no_mem; /* zero the memory */ memset(cd, 0, sizeof(config_data_t)); cd->pathsep = pathsep; /* get and store our base directory */ cd->basedir = isc_mem_strdup(ns_g_mctx, argv[1]); if (cd->basedir == NULL) goto no_mem; cd->basedirsize = strlen(cd->basedir); /* get and store our data sub-dir */ cd->datadir = isc_mem_strdup(ns_g_mctx, argv[2]); if (cd->datadir == NULL) goto no_mem; cd->datadirsize = strlen(cd->datadir); /* get and store our zone xfr sub-dir */ cd->xfrdir = isc_mem_strdup(ns_g_mctx, argv[3]); if (cd->xfrdir == NULL) goto no_mem; cd->xfrdirsize = strlen(cd->xfrdir); /* get and store our directory split count */ cd->splitcnt = strtol(argv[4], &endp, 10); if (*endp != '\0' || cd->splitcnt < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Directory split count must be zero (0) " "or a postive number"); } /* get and store our separator character */ cd->separator = *argv[5]; /* attach config data to memory context */ isc_mem_attach(ns_g_mctx, &cd->mctx); /* pass back config data */ *dbdata = cd; /* return success */ return(ISC_R_SUCCESS); /* handle no memory error */ no_mem: /* if we allocated a config data object clean it up */ if (cd != NULL) fs_destroy(NULL, cd); /* write error message */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Filesystem driver unable to " "allocate memory for config data."); /* return error */ return (ISC_R_NOMEMORY);}static voidfs_destroy(void *driverarg, void *dbdata){ isc_mem_t *mctx; config_data_t *cd; UNUSED(driverarg); cd = (config_data_t *) dbdata; /* * free memory for each section of config data that was * allocated */ if (cd->basedir != NULL) isc_mem_free(ns_g_mctx, cd->basedir); if (cd->datadir != NULL) isc_mem_free(ns_g_mctx, cd->datadir); if (cd->xfrdir != NULL) isc_mem_free(ns_g_mctx, cd->xfrdir); /* hold memory context to use later */ mctx = cd->mctx; /* free config data memory */ isc_mem_put(mctx, cd, sizeof(config_data_t)); /* detach memory from context */ isc_mem_detach(&mctx);}static dns_sdlzmethods_t dlz_fs_methods = { fs_create, fs_destroy, fs_findzone, fs_lookup, NULL, fs_allnodes, fs_allowzonexfr};/*% * Wrapper around dns_sdlzregister(). */isc_result_tdlz_fs_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 filesystem driver."); result = dns_sdlzregister("filesystem", &dlz_fs_methods, NULL, DNS_SDLZFLAG_RELATIVEOWNER | DNS_SDLZFLAG_RELATIVERDATA, ns_g_mctx, &dlz_fs); 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_fs_clear(void) { /* * Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Unregistering DLZ filesystem driver."); if (dlz_fs != NULL) dns_sdlzunregister(&dlz_fs);}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?