Files
bind9/lib/dns/config/conflog.c

1396 lines
28 KiB
C

/*
* Copyright (C) 1999 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.
*/
#include <config.h>
#include <string.h>
#include <isc/assertions.h>
#include <dns/conflog.h>
#include <dns/confcommon.h>
#include <dns/log.h>
#include "confpvt.h"
#define UNLIM_VERSIONS (-1) /* XXX check this is right? */
/*
* Bit positions in the dns_c_logchan_t structure setflags field.
*/
#define CHAN_VERSIONS_BIT 0
#define CHAN_SIZE_BIT 1
#define CHAN_SEVERITY_BIT 2
#define CHAN_DEBUG_LEVEL_BIT 3
#define CHAN_PCAT_BIT 4
#define CHAN_PSEV_BIT 5
#define CHAN_PTIME_BIT 6
#define CHAN_FACILITY_BIT 7
static void print_log_facility(isc_log_t *lctx, FILE *fp, int value);
static void print_log_severity(isc_log_t *lctx, FILE *fp,
dns_c_logseverity_t severity);
static void print_log_category(isc_log_t *lctx, FILE *fp,
dns_c_category_t category);
isc_result_t
dns_c_logginglist_new(isc_log_t *lctx,
isc_mem_t *mem,
dns_c_logginglist_t **list)
{
dns_c_logginglist_t *newl;
(void) lctx;
REQUIRE(list != NULL);
newl = isc_mem_get(mem, sizeof *newl);
if (newl == NULL) {
return (ISC_R_NOMEMORY);
}
newl->mem = mem;
ISC_LIST_INIT(newl->channels);
ISC_LIST_INIT(newl->categories);
*list = newl;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logginglist_delete(isc_log_t *lctx,
dns_c_logginglist_t **list)
{
dns_c_logginglist_t *l;
dns_c_logchan_t *chan, *tmpchan;
dns_c_logcat_t *cat, *tmpcat;
isc_result_t res;
REQUIRE(list != NULL);
l = *list;
if (l == NULL) {
return (ISC_R_SUCCESS);
}
chan = ISC_LIST_HEAD(l->channels);
while (chan != NULL) {
tmpchan = ISC_LIST_NEXT(chan, next);
ISC_LIST_UNLINK(l->channels, chan, next);
res = dns_c_logchan_delete(lctx, &chan);
if (res != ISC_R_SUCCESS) {
return (res);
}
chan = tmpchan;
}
cat = ISC_LIST_HEAD(l->categories);
while (cat != NULL) {
tmpcat = ISC_LIST_NEXT(cat, next);
ISC_LIST_UNLINK(l->categories, cat, next);
res = dns_c_logcat_delete(lctx, &cat);
if (res != ISC_R_SUCCESS) {
return (res);
}
cat = tmpcat;
}
isc_mem_put(l->mem, l, sizeof *l);
*list = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logginglist_copy(isc_log_t *lctx,
isc_mem_t *mem,
dns_c_logginglist_t **dest,
dns_c_logginglist_t *src)
{
dns_c_logginglist_t *newl;
dns_c_logchan_t *logchan, *tmplogchan;
dns_c_logcat_t *logcat, *tmplogcat;
isc_result_t res;
REQUIRE(dest != NULL);
REQUIRE(src != NULL);
res = dns_c_logginglist_new(lctx, mem, &newl);
if (res != ISC_R_SUCCESS) {
return (res);
}
logchan = ISC_LIST_HEAD(src->channels);
while (logchan != NULL) {
res = dns_c_logchan_copy(lctx, mem, &tmplogchan, logchan);
if (res != ISC_R_SUCCESS) {
dns_c_logginglist_delete(lctx, &newl);
return (res);
}
ISC_LIST_APPEND(newl->channels, tmplogchan, next);
logchan = ISC_LIST_NEXT(logchan, next);
}
logcat = ISC_LIST_HEAD(src->categories);
while (logcat != NULL) {
res = dns_c_logcat_copy(lctx, mem, &tmplogcat, logcat);
if (res != ISC_R_SUCCESS) {
dns_c_logginglist_delete(lctx, &newl);
return (res);
}
ISC_LIST_APPEND(newl->categories, tmplogcat, next);
logcat = ISC_LIST_NEXT(logcat, next);
}
return (ISC_R_SUCCESS);
}
void
dns_c_logginglist_print(isc_log_t *lctx,
FILE *fp, int indent, dns_c_logginglist_t *ll,
isc_boolean_t if_predef_too)
{
dns_c_logchan_t *logchan;
dns_c_logcat_t *logcat;
REQUIRE(fp != NULL);
if (ll == NULL) {
return;
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "logging {\n");
logchan = ISC_LIST_HEAD(ll->channels);
while (logchan != NULL) {
dns_c_logchan_print(lctx, fp, indent + 1, logchan,
if_predef_too);
logchan = ISC_LIST_NEXT(logchan, next);
}
logcat = ISC_LIST_HEAD(ll->categories);
while (logcat != NULL) {
dns_c_logcat_print(lctx, fp, indent + 1, logcat,
if_predef_too);
logcat = ISC_LIST_NEXT(logcat, next);
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "};\n");
}
isc_result_t
dns_c_logginglist_addchannel(isc_log_t *lctx,
dns_c_logginglist_t *list,
dns_c_logchan_t *newchan,
isc_boolean_t deepcopy)
{
dns_c_logchan_t *newc, *tmpchan;
isc_result_t res;
isc_boolean_t existed = ISC_FALSE;
isc_boolean_t predefined = ISC_FALSE;
REQUIRE(list != NULL);
REQUIRE(newchan != NULL);
if (deepcopy) {
res = dns_c_logchan_copy(lctx, list->mem, &newc, newchan);
if (res != ISC_R_SUCCESS) {
return (res);
}
} else {
newc = newchan;
}
tmpchan = ISC_LIST_HEAD(list->channels);
while (tmpchan != NULL) {
if (strcmp(newchan->name, tmpchan->name) == 0) {
existed = ISC_TRUE;
predefined = tmpchan->predefined;
ISC_LIST_UNLINK(list->channels, tmpchan, next);
res = dns_c_logchan_delete(lctx, &tmpchan);
if (res != ISC_R_SUCCESS) {
if (deepcopy) {
dns_c_logchan_delete(lctx, &newc);
}
return (res);
}
break;
}
tmpchan = ISC_LIST_NEXT(tmpchan, next);
}
ISC_LIST_APPEND(list->channels, newc, next);
/* replacing a predefined channel is a plain success. */
return (existed && !predefined ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logginglist_addcategory(isc_log_t *lctx,
dns_c_logginglist_t *list,
dns_c_logcat_t *newcat,
isc_boolean_t deepcopy)
{
dns_c_logcat_t *newc, *tmpcat;
isc_result_t res;
isc_boolean_t existed = ISC_FALSE;
isc_boolean_t predefined = ISC_FALSE;
REQUIRE(list != NULL);
REQUIRE(newcat != NULL);
if (deepcopy) {
res = dns_c_logcat_copy(lctx, list->mem, &newc, newcat);
if (res != ISC_R_SUCCESS) {
return (res);
}
} else {
newc = newcat;
}
/* Remove old category defintion if there. */
tmpcat = ISC_LIST_HEAD(list->categories);
while (tmpcat != NULL) {
if (newcat->category == tmpcat->category) {
existed = ISC_TRUE;
predefined = tmpcat->predefined;
ISC_LIST_UNLINK(list->categories, tmpcat, next);
res = dns_c_logcat_delete(lctx, &tmpcat);
if (res != ISC_R_SUCCESS) {
if (deepcopy) {
dns_c_logcat_delete(lctx, &newc);
}
return (res);
}
break;
}
tmpcat = ISC_LIST_NEXT(tmpcat, next);
}
ISC_LIST_APPEND(list->categories, newc, next);
/* replacing a predefined category is a simple success. */
return (existed && !predefined ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logginglist_delchannel(isc_log_t *lctx,
dns_c_logginglist_t *list,
const char *name)
{
dns_c_logchan_t *logc;
isc_result_t res;
res = dns_c_logginglist_chanbyname(lctx, list, name, &logc);
if (res == ISC_R_SUCCESS) {
ISC_LIST_UNLINK(list->channels, logc, next);
res = dns_c_logchan_delete(lctx, &logc);
}
return (res);
}
isc_result_t
dns_c_logginglist_delcategory(isc_log_t *lctx,
dns_c_logginglist_t *list,
const char *name)
{
dns_c_logcat_t *logc;
isc_result_t res;
res = dns_c_logginglist_catbyname(lctx, list, name, &logc);
if (res == ISC_R_SUCCESS) {
ISC_LIST_UNLINK(list->categories, logc, next);
res = dns_c_logcat_delete(lctx, &logc);
}
return (res);
}
isc_result_t
dns_c_logginglist_chanbyname(isc_log_t *lctx,
dns_c_logginglist_t *list,
const char *name,
dns_c_logchan_t **chan)
{
dns_c_logchan_t *logc;
(void) lctx;
REQUIRE(list != NULL);
REQUIRE(name != NULL);
REQUIRE(chan != NULL);
logc = ISC_LIST_HEAD(list->channels);
while (logc != NULL) {
if (strcmp(logc->name, name) == 0) {
break;
}
logc = ISC_LIST_NEXT(logc, next);
}
if (logc == NULL) {
return (ISC_R_NOTFOUND);
} else {
*chan = logc;
return (ISC_R_SUCCESS);
}
}
isc_result_t
dns_c_logginglist_catbyname(isc_log_t *lctx,
dns_c_logginglist_t *list,
const char *name,
dns_c_logcat_t **cat)
{
dns_c_category_t cattype;
isc_result_t res;
REQUIRE(list != NULL);
REQUIRE(name != NULL);
REQUIRE(cat != NULL);
res = dns_c_string2category(lctx, name, &cattype);
if (res != ISC_R_SUCCESS) {
return (ISC_R_FAILURE);
}
return (dns_c_logginglist_catbytype(lctx, list, cattype, cat));
}
isc_result_t
dns_c_logginglist_catbytype(isc_log_t *lctx,
dns_c_logginglist_t *list,
dns_c_category_t cattype,
dns_c_logcat_t **cat)
{
dns_c_logcat_t *logc;
(void) lctx;
logc = ISC_LIST_HEAD(list->categories);
while (logc != NULL) {
if (logc->category == cattype) {
break;
}
logc = ISC_LIST_NEXT(logc, next);
}
if (logc == NULL) {
return (ISC_R_NOTFOUND);
} else {
*cat = logc;
return (ISC_R_SUCCESS);
}
}
/* ************************************************************************ */
/* **************************** LOGGING CHANNELS ************************** */
/* ************************************************************************ */
isc_result_t
dns_c_logchan_new(isc_log_t *lctx,
isc_mem_t *mem, const char *name,
dns_c_logchantype_t ctype,
dns_c_logchan_t **newchan)
{
dns_c_logchan_t *newc;
(void) lctx;
REQUIRE(name != NULL);
newc = isc_mem_get(mem, sizeof *newc);
if (newc == NULL) {
return (ISC_R_NOMEMORY);
}
newc->mem = mem;
newc->ctype = ctype;
newc->severity = dns_c_log_info;
newc->debug_level = 0;
newc->print_category = ISC_FALSE;
newc->print_severity = ISC_FALSE;
newc->print_time = ISC_FALSE;
newc->predefined = ISC_FALSE;
memset(&newc->setflags, 0x0, sizeof newc->setflags);
ISC_LINK_INIT(newc, next);
newc->name = isc_mem_strdup(mem, name);
if (newc->name == NULL) {
isc_mem_put(mem, newc, sizeof *newc);
return (ISC_R_NOMEMORY);
}
switch (ctype) {
case dns_c_logchan_file:
newc->u.filec.path = NULL;
break;
case dns_c_logchan_syslog:
case dns_c_logchan_null:
break;
}
*newchan = newc;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_delete(isc_log_t *lctx,
dns_c_logchan_t **channel)
{
dns_c_logchan_t *logc;
(void) lctx;
REQUIRE(channel != NULL);
logc = *channel;
if (logc == NULL) {
return (ISC_R_SUCCESS);
}
isc_mem_free(logc->mem, logc->name);
switch (logc->ctype) {
case dns_c_logchan_file:
if (logc->u.filec.path != NULL) {
isc_mem_free(logc->mem, logc->u.filec.path);
}
break;
case dns_c_logchan_syslog:
case dns_c_logchan_null:
break;
}
*channel = NULL;
isc_mem_put(logc->mem, logc, sizeof *logc);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_copy(isc_log_t *lctx,
isc_mem_t *mem, dns_c_logchan_t **dest,
dns_c_logchan_t *src)
{
dns_c_logchan_t *logc;
isc_result_t res;
REQUIRE(dest != NULL);
REQUIRE(src != NULL);
res = dns_c_logchan_new(lctx, mem, src->name, src->ctype, &logc);
if (res != ISC_R_SUCCESS) {
return (res);
}
logc->severity = src->severity;
logc->debug_level = src->debug_level;
logc->print_category = src->print_category;
logc->print_severity = src->print_severity;
logc->print_time = src->print_time;
logc->setflags = src->setflags;
switch (logc->ctype) {
case dns_c_logchan_file:
logc->u.filec.path = isc_mem_strdup(mem, src->u.filec.path);
logc->u.filec.versions = src->u.filec.versions;
logc->u.filec.size = src->u.filec.size;
break;
case dns_c_logchan_syslog:
logc->u.syslogc.facility = src->u.syslogc.facility;
break;
case dns_c_logchan_null:
break;
}
*dest = logc;
return (ISC_R_SUCCESS);
}
void
dns_c_logchan_print(isc_log_t *lctx,
FILE *fp, int indent, dns_c_logchan_t *logchan,
isc_boolean_t if_predef_too)
{
REQUIRE(fp != NULL);
REQUIRE(logchan != NULL);
if (logchan->predefined && !if_predef_too) {
return;
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "channel %s {\n", logchan->name) ;
dns_c_printtabs(lctx, fp, indent + 1) ;
switch (logchan->ctype) {
case dns_c_logchan_file:
fprintf(fp, "file \"%s\"",
(logchan->u.filec.path == NULL ?
"No path defined" : logchan->u.filec.path));
if (DNS_C_CHECKBIT(CHAN_VERSIONS_BIT, &logchan->setflags)) {
fprintf(fp, " versions ");
if (logchan->u.filec.versions == DNS_C_UNLIM_VERSIONS){
fprintf(fp, "unlimited");
} else {
fprintf(fp, "%u", logchan->u.filec.versions);
}
}
if (DNS_C_CHECKBIT(CHAN_SIZE_BIT, &logchan->setflags)) {
fprintf(fp, " size ");
dns_c_printinunits(lctx, fp, logchan->u.filec.size);
}
break;
case dns_c_logchan_syslog:
fprintf(fp, "syslog ");
print_log_facility(lctx, fp, logchan->u.syslogc.facility);
break;
case dns_c_logchan_null:
fputs("null", fp);
break;
}
fprintf(fp, ";\n");
if (DNS_C_CHECKBIT(CHAN_SEVERITY_BIT, &logchan->setflags)) {
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "severity ");
print_log_severity(lctx, fp, logchan->severity);
if (logchan->severity == dns_c_log_debug &&
DNS_C_CHECKBIT(CHAN_DEBUG_LEVEL_BIT, &logchan->setflags)) {
fprintf(fp, " %d", logchan->debug_level);
}
fprintf(fp, ";\n");
}
if (DNS_C_CHECKBIT(CHAN_PSEV_BIT, &logchan->setflags)) {
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "print-severity %s;\n",
(logchan->print_severity ? "true" : "false"));
}
if (DNS_C_CHECKBIT(CHAN_PCAT_BIT, &logchan->setflags)) {
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "print-category %s;\n",
(logchan->print_category ? "true" : "false"));
}
if (DNS_C_CHECKBIT(CHAN_PTIME_BIT, &logchan->setflags)) {
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "print-time %s;\n",
(logchan->print_time ? "true" : "false"));
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "};\n");
}
isc_result_t
dns_c_logchan_setpath(isc_log_t *lctx,
dns_c_logchan_t *channel, const char *path)
{
isc_boolean_t existed = ISC_FALSE;
REQUIRE(channel != NULL);
REQUIRE(path != NULL);
REQUIRE(strlen(path) > 0);
if (channel->ctype != dns_c_logchan_file) {
isc_log_write(lctx, DNS_LOGCATEGORY_CONFIG,
DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
"This type of channel doesn't have a "
"path field");
return (ISC_R_FAILURE);
}
if (channel->u.filec.path != NULL) {
existed = ISC_TRUE;
isc_mem_free(channel->mem, channel->u.filec.path);
}
channel->u.filec.path = isc_mem_strdup(channel->mem, path);
if (channel->u.filec.path == NULL) {
return (ISC_R_NOMEMORY);
} else {
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
}
isc_result_t
dns_c_logchan_setversions(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_uint32_t versions)
{
isc_boolean_t existed;
REQUIRE(channel != NULL);
existed = DNS_C_CHECKBIT(CHAN_VERSIONS_BIT, &channel->setflags);
if (channel->ctype != dns_c_logchan_file) {
isc_log_write(lctx, DNS_LOGCATEGORY_CONFIG,
DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
"This type of channel doesn't have a "
"version field");
return (ISC_R_FAILURE);
}
DNS_C_SETBIT(CHAN_VERSIONS_BIT, &channel->setflags);
channel->u.filec.versions = versions;
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_setsize(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_uint32_t size)
{
isc_boolean_t existed;
REQUIRE(channel != NULL);
if (channel->ctype != dns_c_logchan_file) {
isc_log_write(lctx, DNS_LOGCATEGORY_CONFIG,
DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
"This type of channel doesn't have a "
"size field");
return (ISC_R_FAILURE);
}
existed = DNS_C_CHECKBIT(CHAN_SIZE_BIT, &channel->setflags);
DNS_C_SETBIT(CHAN_SIZE_BIT, &channel->setflags);
channel->u.filec.size = size;
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_setfacility(isc_log_t *lctx,
dns_c_logchan_t *channel, int facility)
{
isc_boolean_t existed;
REQUIRE(channel != NULL);
if (channel->ctype != dns_c_logchan_syslog) {
isc_log_write(lctx, DNS_LOGCATEGORY_CONFIG,
DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
"This type of channel doesn't have a "
"facility field");
return (ISC_R_FAILURE);
}
if (dns_c_facility2string(lctx, facility, ISC_FALSE) == NULL) {
isc_log_write(lctx, DNS_LOGCATEGORY_CONFIG,
DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
"Not a legal facility for a syslog channel: %d",
facility);
return (ISC_R_FAILURE);
}
existed = DNS_C_CHECKBIT(CHAN_FACILITY_BIT, &channel->setflags);
DNS_C_SETBIT(CHAN_FACILITY_BIT, &channel->setflags);
channel->u.syslogc.facility = facility;
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_setseverity(isc_log_t *lctx,
dns_c_logchan_t *channel,
dns_c_logseverity_t severity)
{
isc_boolean_t existed;
(void) lctx;
REQUIRE(channel != NULL);
existed = DNS_C_CHECKBIT(CHAN_SEVERITY_BIT, &channel->setflags);
DNS_C_SETBIT(CHAN_SEVERITY_BIT, &channel->setflags);
channel->severity = severity;
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_setdebuglevel(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_int32_t level)
{
isc_boolean_t existed;
(void) lctx;
REQUIRE(channel != NULL);
if (channel->severity == dns_c_log_debug) {
existed = DNS_C_CHECKBIT(CHAN_DEBUG_LEVEL_BIT,
&channel->setflags);
DNS_C_SETBIT(CHAN_DEBUG_LEVEL_BIT, &channel->setflags);
channel->debug_level = level;
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
} else {
return (ISC_R_FAILURE);
}
}
isc_result_t
dns_c_logchan_setprintcat(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_boolean_t newval)
{
isc_boolean_t existed;
(void) lctx;
REQUIRE(channel != NULL);
existed = DNS_C_CHECKBIT(CHAN_PCAT_BIT, &channel->setflags);
DNS_C_SETBIT(CHAN_PCAT_BIT, &channel->setflags);
channel->print_category = newval;
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_setprintsev(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_boolean_t newval)
{
isc_boolean_t existed;
(void) lctx;
REQUIRE(channel != NULL);
existed = DNS_C_CHECKBIT(CHAN_PSEV_BIT, &channel->setflags);
DNS_C_SETBIT(CHAN_PSEV_BIT, &channel->setflags);
channel->print_severity = newval;
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_setprinttime(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_boolean_t newval)
{
isc_boolean_t existed;
(void) lctx;
REQUIRE(channel != NULL);
existed = DNS_C_CHECKBIT(CHAN_PTIME_BIT, &channel->setflags);
DNS_C_SETBIT(CHAN_PTIME_BIT, &channel->setflags);
channel->print_time = newval;
return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_setpredef(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_boolean_t newval)
{
(void) lctx;
REQUIRE(channel != NULL);
channel->predefined = newval;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_getpath(isc_log_t *lctx,
dns_c_logchan_t *channel, const char **path)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(path != NULL);
if (channel->ctype == dns_c_logchan_file &&
channel->u.filec.path != NULL) {
*path = channel->u.filec.path;
res = ISC_R_SUCCESS;
} else if (channel->ctype == dns_c_logchan_file) {
res = ISC_R_NOTFOUND;
} else {
res = ISC_R_FAILURE;
}
return (res);
}
isc_result_t
dns_c_logchan_getversions(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_uint32_t *retval)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
if (channel->ctype == dns_c_logchan_file &&
DNS_C_CHECKBIT(CHAN_VERSIONS_BIT, &channel->setflags)) {
*retval = channel->u.filec.versions;
res = ISC_R_SUCCESS;
} else if (channel->ctype == dns_c_logchan_file) {
res = ISC_R_NOTFOUND;
} else {
res = ISC_R_FAILURE;
}
return (res);
}
isc_result_t
dns_c_logchan_getsize(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_uint32_t *retval)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
if (channel->ctype == dns_c_logchan_file &&
DNS_C_CHECKBIT(CHAN_SIZE_BIT, &channel->setflags)) {
*retval = channel->u.filec.size;
res = ISC_R_SUCCESS;
} else if (channel->ctype == dns_c_logchan_file) {
res = ISC_R_NOTFOUND;
} else {
res = ISC_R_FAILURE;
}
return (res);
}
isc_result_t
dns_c_logchan_getfacility(isc_log_t *lctx,
dns_c_logchan_t *channel, int *retval)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
if (channel->ctype == dns_c_logchan_syslog &&
DNS_C_CHECKBIT(CHAN_FACILITY_BIT, &channel->setflags)) {
*retval = channel->u.syslogc.facility;
res = ISC_R_SUCCESS;
} else if (channel->ctype == dns_c_logchan_syslog) {
res = ISC_R_NOTFOUND;
} else {
res = ISC_R_FAILURE;
}
return (res);
}
isc_result_t
dns_c_logchan_getseverity(isc_log_t *lctx,
dns_c_logchan_t *channel,
dns_c_logseverity_t *retval)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
if (DNS_C_CHECKBIT(CHAN_SEVERITY_BIT, &channel->setflags)) {
*retval = channel->severity;
res = ISC_R_SUCCESS;
} else {
res = ISC_R_NOTFOUND;
}
return (res);
}
isc_result_t
dns_c_logchan_getdebuglevel(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_int32_t *retval)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
if (DNS_C_CHECKBIT(CHAN_DEBUG_LEVEL_BIT, &channel->setflags)) {
*retval = channel->debug_level;
res = ISC_R_SUCCESS;
} else {
res = ISC_R_NOTFOUND;
}
return (res);
}
isc_result_t
dns_c_logchan_getprintcat(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_boolean_t *retval)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
if (DNS_C_CHECKBIT(CHAN_PCAT_BIT, &channel->setflags)) {
*retval = channel->print_category;
res = ISC_R_SUCCESS;
} else {
res = ISC_R_NOTFOUND;
}
return (res);
}
isc_result_t
dns_c_logchan_getprintsev(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_boolean_t *retval)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
if (DNS_C_CHECKBIT(CHAN_PSEV_BIT, &channel->setflags)) {
*retval = channel->print_severity;
res = ISC_R_SUCCESS;
} else {
res = ISC_R_NOTFOUND;
}
return (res);
}
isc_result_t
dns_c_logchan_getprinttime(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_boolean_t *retval)
{
isc_result_t res;
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
if (DNS_C_CHECKBIT(CHAN_PTIME_BIT, &channel->setflags)) {
*retval = channel->print_time;
res = ISC_R_SUCCESS;
} else {
res = ISC_R_NOTFOUND;
}
return (res);
}
isc_result_t
dns_c_logchan_getpredef(isc_log_t *lctx,
dns_c_logchan_t *channel, isc_boolean_t *retval)
{
(void) lctx;
REQUIRE(channel != NULL);
REQUIRE(retval != NULL);
*retval = channel->predefined;
return (ISC_R_SUCCESS);
}
/*
* Logging category
*/
isc_result_t
dns_c_logcat_new(isc_log_t *lctx,
isc_mem_t *mem, dns_c_category_t cat, dns_c_logcat_t **newlc)
{
dns_c_logcat_t *newc;
unsigned int i;
(void) lctx;
REQUIRE(newlc != NULL);
newc = isc_mem_get(mem, sizeof *newc);
if (newc == NULL) {
return (ISC_R_NOMEMORY);
}
newc->mem = mem;
newc->category = cat;
newc->cnames_len = 2;
newc->nextcname = 0;
newc->predefined = ISC_FALSE;
newc->channel_names = isc_mem_get(mem,
sizeof (char *) * newc->cnames_len);
if (newc->channel_names == NULL) {
isc_mem_put(mem, newc, sizeof *newc);
return (ISC_R_NOMEMORY);
}
for (i = 0 ; i < newc->cnames_len ; i++) {
newc->channel_names[i] = NULL;
}
*newlc = newc;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logcat_delete(isc_log_t *lctx,
dns_c_logcat_t **logcat)
{
dns_c_logcat_t *logc;
unsigned int i;
(void) lctx;
REQUIRE(logcat != NULL);
logc = *logcat;
if (logc == NULL) {
return (ISC_R_SUCCESS);
}
for (i = 0 ; i < logc->nextcname ; i++) {
REQUIRE(logc->channel_names[i] != NULL);
isc_mem_free(logc->mem, logc->channel_names[i]);
}
isc_mem_put(logc->mem, logc->channel_names,
sizeof (char *) * logc->cnames_len);
isc_mem_put(logc->mem, logc, sizeof *logc);
*logcat = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logcat_copy(isc_log_t *lctx,
isc_mem_t *mem, dns_c_logcat_t **dest, dns_c_logcat_t *src)
{
unsigned int i;
dns_c_logcat_t *newc;
isc_result_t res;
REQUIRE(dest != NULL);
REQUIRE(src != NULL);
res = dns_c_logcat_new(lctx, mem, src->category, &newc);
if (res != ISC_R_SUCCESS) {
return (res);
}
for (i = 0 ; i < src->nextcname ; i++) {
res = dns_c_logcat_addname(lctx, newc, src->channel_names[i]);
if (res != ISC_R_SUCCESS) {
dns_c_logcat_delete(lctx, &newc);
return (res);
}
}
return (ISC_R_SUCCESS);
}
void
dns_c_logcat_print(isc_log_t *lctx,
FILE *fp, int indent, dns_c_logcat_t *logcat,
isc_boolean_t if_predef_too)
{
unsigned int i;
REQUIRE(fp != NULL);
REQUIRE(logcat != NULL);
if (logcat->predefined && !if_predef_too) {
return;
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "category ");
print_log_category(lctx, fp, logcat->category);
fprintf(fp, " {\n");
for (i = 0 ; i < logcat->nextcname ; i++) {
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "%s;\n", logcat->channel_names[i]);
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "};\n");
}
isc_result_t
dns_c_logcat_addname(isc_log_t *lctx,
dns_c_logcat_t *logcat, const char *name)
{
unsigned int i;
(void) lctx;
REQUIRE(logcat != NULL);
REQUIRE(name != NULL);
REQUIRE(strlen(name) > 0);
if (logcat->cnames_len == logcat->nextcname) {
size_t newsize = logcat->cnames_len + 5;
char **newarr = isc_mem_get(logcat->mem,
newsize * sizeof (char *));
if (newarr == NULL) {
return (ISC_R_NOMEMORY);
}
for (i = 0 ; i < newsize ; i++) {
if (i < logcat->cnames_len) {
newarr[i] = logcat->channel_names[i];
} else {
newarr[i] = NULL;
}
}
isc_mem_put(logcat->mem, logcat->channel_names,
sizeof (char *) * logcat->cnames_len);
logcat->channel_names = newarr;
logcat->cnames_len = newsize;
}
logcat->channel_names[logcat->nextcname] =
isc_mem_strdup(logcat->mem, name);
if (logcat->channel_names[logcat->nextcname] == NULL) {
return (ISC_R_NOMEMORY);
}
logcat->nextcname++;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logcat_delname(isc_log_t *lctx,
dns_c_logcat_t *logcat, const char *name)
{
unsigned int i ;
isc_result_t res;
(void) lctx;
REQUIRE(logcat != NULL);
REQUIRE(name != NULL);
REQUIRE(strlen(name) > 0);
for (i = 0 ; i < logcat->nextcname ; i++) {
INSIST(logcat->channel_names[i] != NULL);
if (strcmp(logcat->channel_names[i], name) == 0) {
break;
}
}
if (i < logcat->nextcname) {
res = ISC_R_SUCCESS;
isc_mem_free(logcat->mem, logcat->channel_names[i]);
while (i < (logcat->nextcname - 1)) {
logcat->channel_names[i] = logcat->channel_names[i+1];
i++;
}
} else {
res = ISC_R_NOTFOUND;
}
return (res);
}
isc_result_t
dns_c_logcat_setpredef(isc_log_t *lctx,
dns_c_logcat_t *logcat,isc_boolean_t newval)
{
(void) lctx;
REQUIRE(logcat != NULL);
logcat->predefined = newval;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logcat_getpredef(isc_log_t *lctx,
dns_c_logcat_t *logcat, isc_boolean_t *retval)
{
(void) lctx;
REQUIRE(logcat != NULL);
REQUIRE(retval != NULL);
*retval = logcat->predefined;
return (ISC_R_SUCCESS);
}
/***************************************************************************/
static void
print_log_facility(isc_log_t *lctx,
FILE *fp, int value)
{
REQUIRE(fp != NULL);
fputs(dns_c_facility2string(lctx, value, ISC_TRUE), fp);
}
static void
print_log_severity(isc_log_t *lctx,
FILE *fp, dns_c_logseverity_t severity)
{
REQUIRE(fp != NULL);
fputs(dns_c_logseverity2string(lctx, severity, ISC_TRUE), fp);
}
static void
print_log_category(isc_log_t *lctx,
FILE *fp, dns_c_category_t category)
{
REQUIRE(fp != NULL);
fputs(dns_c_category2string(lctx, category, ISC_TRUE), fp);
}