diff --git a/lib/isc/include/isc/log.h b/lib/isc/include/isc/log.h index 7a5e74fda9..2b25979cff 100644 --- a/lib/isc/include/isc/log.h +++ b/lib/isc/include/isc/log.h @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: log.h,v 1.11 2000/03/01 21:30:49 tale Exp $ */ +/* $Id: log.h,v 1.12 2000/03/04 00:43:40 tale Exp $ */ #ifndef ISC_LOG_H #define ISC_LOG_H 1 @@ -296,18 +296,32 @@ isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]); * Identify logging categories a library will use. * * Notes: + * A category should only be registered once, but no mechanism enforces + * this rule. + * * The end of the categories array is identified by a NULL name. * * Because the name is used by ISC_LOG_PRINTCATEGORY, it should not * be altered or destroyed after isc_log_registercategories(). * + * Because each element of the categories array is used by + * isc_log_categorybyname, it should not be altered or destroyed + * after registration. + * * The value of the id integer in each structure is overwritten * by this function, and so id need not be initalized to any particular * value prior to the function call. * + * A subsequent call to isc_log_registercategories with the same + * logging context (but new categories) will cause the last + * element of the categories array from the prior call to have + * its "name" member changed from NULL to point to the new + * categories array, and its "id" member set to UINT_MAX. + * * Requires: * lctx is a valid logging context. * categories != NULL. + * categories[0].name != NULL. * * Ensures: * There are references to each category in the logging context, @@ -320,18 +334,32 @@ isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]); * Identify logging categories a library will use. * * Notes: + * A module should only be registered once, but no mechanism enforces + * this rule. + * * The end of the modules array is identified by a NULL name. * * Because the name is used by ISC_LOG_PRINTMODULE, it should not * be altered or destroyed after isc_log_registermodules(). * + * Because each element of the modules array is used by + * isc_log_modulebyname, it should not be altered or destroyed + * after registration. + * * The value of the id integer in each structure is overwritten * by this function, and so id need not be initalized to any particular * value prior to the function call. * + * A subsequent call to isc_log_registermodules with the same + * logging context (but new modules) will cause the last + * element of the modules array from the prior call to have + * its "name" member changed from NULL to point to the new + * modules array, and its "id" member set to UINT_MAX. + * * Requires: * lctx is a valid logging context. * modules != NULL. + * modules[0].name != NULL; * * Ensures: * Each module has a reference in the logging context, so they can be @@ -691,6 +719,34 @@ isc_log_closefilelogs(isc_log_t *lctx); * next needed. */ +isc_logcategory_t * +isc_log_categorybyname(isc_log_t *lctx, const char *name); +/* + * Find a category by its name. + * + * Notes: + * The string name of a category is not required to be unique. + * + * Returns: + * A pointer to the _first_ isc_logcategory_t structure used by "name". + * + * NULL if no category exists by that name. + */ + +isc_logmodule_t * +isc_log_modulebyname(isc_log_t *lctx, const char *name); +/* + * Find a module by its name. + * + * Notes: + * The string name of a module is not required to be unique. + * + * Returns: + * A pointer to the _first_ isc_logmodule_t structure used by "name". + * + * NULL if no module exists by that name. + */ + ISC_LANG_ENDDECLS #endif /* ISC_LOG_H */ diff --git a/lib/isc/log.c b/lib/isc/log.c index 580c5f6191..7b5e5309de 100644 --- a/lib/isc/log.c +++ b/lib/isc/log.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: log.c,v 1.18 2000/03/01 20:38:58 gson Exp $ */ +/* $Id: log.c,v 1.19 2000/03/04 00:43:38 tale Exp $ */ /* Principal Authors: DCL */ @@ -133,7 +133,9 @@ struct isc_log { /* Not locked. */ unsigned int magic; isc_mem_t * mctx; + isc_logcategory_t * categories; unsigned int category_count; + isc_logmodule_t * modules; unsigned int module_count; int debug_level; isc_mutex_t lock; @@ -228,7 +230,9 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp) { lctx = isc_mem_get(mctx, sizeof(*lctx)); if (lctx != NULL) { lctx->mctx = mctx; + lctx->categories = NULL; lctx->category_count = 0; + lctx->modules = NULL; lctx->module_count = 0; lctx->debug_level = 0; @@ -420,7 +424,9 @@ isc_log_destroy(isc_log_t **lctxp) { lctx->buffer[0] = '\0'; lctx->debug_level = 0; + lctx->categories = NULL; lctx->category_count = 0; + lctx->modules = NULL; lctx->module_count = 0; lctx->mctx = NULL; lctx->magic = 0; @@ -485,41 +491,109 @@ isc_logconfig_destroy(isc_logconfig_t **lcfgp) { void isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) { isc_logcategory_t *catp; - unsigned int old_count, new_count; REQUIRE(VALID_CONTEXT(lctx)); - REQUIRE(categories != NULL); - - old_count = lctx->category_count; + REQUIRE(categories != NULL && categories[0].name != NULL); + + /* + * XXXDCL This somewhat sleazy situation of using the last pointer + * in one category array to point to the next array exists because + * this registration function returns void and I didn't want to have + * change everything that used it by making it return an isc_result_t. + * It would need to do that if it had to allocate memory to store + * pointers to each array passed in. + */ + if (lctx->categories == NULL) + lctx->categories = categories; + + else { + /* + * Adjust the last (NULL) pointer of the already registered + * categories to point to the incoming array. + */ + for (catp = lctx->categories; catp->name != NULL; catp++) + if (catp->id == UINT_MAX) + catp = (isc_logcategory_t *)catp->name; + + catp->name = (void *)categories; + catp->id = UINT_MAX; + } /* - * Total the number of categories that will exist when these are added. * Update the id number of the category with its new global id. */ - for (new_count = old_count, catp = categories; catp->name != NULL; ) - catp++->id = new_count++; + for (catp = categories; catp->name != NULL; catp++) + catp->id = lctx->category_count++; +} - lctx->category_count = new_count; +isc_logcategory_t * +isc_log_categorybyname(isc_log_t *lctx, const char *name) { + isc_logcategory_t *catp; + + REQUIRE(VALID_CONTEXT(lctx)); + + for (catp = lctx->categories; catp->name != NULL; catp++) + if (catp->id == UINT_MAX) + catp = (isc_logcategory_t *)catp->name; + else + if (strcmp(catp->name, name) == 0) + return catp; + + return (NULL); } void isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]) { isc_logmodule_t *modp; - unsigned int old_count, new_count; REQUIRE(VALID_CONTEXT(lctx)); - REQUIRE(modules != NULL); - - old_count = lctx->module_count; + REQUIRE(modules != NULL && modules[0].name != NULL); + + /* + * XXXDCL This somewhat sleazy situation of using the last pointer + * in one category array to point to the next array exists because + * this registration function returns void and I didn't want to have + * change everything that used it by making it return an isc_result_t. + * It would need to do that if it had to allocate memory to store + * pointers to each array passed in. + */ + if (lctx->modules == NULL) + lctx->modules = modules; + + else { + /* + * Adjust the last (NULL) pointer of the already registered + * modules to point to the incoming array. + */ + for (modp = lctx->modules; modp->name != NULL; modp++) + if (modp->id == UINT_MAX) + modp = (isc_logmodule_t *)modp->name; + + modp->name = (void *)modules; + modp->id = UINT_MAX; + } /* - * Total the number of modules that will exist when these are added. * Update the id number of the module with its new global id. */ - for (new_count = old_count, modp = modules; modp->name != NULL; ) - modp++->id = new_count++; + for (modp = modules; modp->name != NULL; modp++) + modp->id = lctx->module_count++; +} - lctx->module_count = new_count; +isc_logmodule_t * +isc_log_modulebyname(isc_log_t *lctx, const char *name) { + isc_logmodule_t *modp; + + REQUIRE(VALID_CONTEXT(lctx)); + + for (modp = lctx->modules; modp->name != NULL; modp++) + if (modp->id == UINT_MAX) + modp = (isc_logmodule_t *)modp->name; + else + if (strcmp(modp->name, name) == 0) + return modp; + + return (NULL); } isc_result_t