conflog.c revision 15a44745412679c30a6d022733925af70a38b715
/*
* Copyright (C) 1999, 2000 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.
*/
/* $Id: conflog.c,v 1.17 2000/07/27 09:47:05 tale Exp $ */
#include <config.h>
#include <isc/mem.h>
#include <isc/string.h>
#include <isc/util.h>
#include <dns/conflog.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(FILE *fp, int value);
static void
print_log_severity(FILE *fp, dns_c_logseverity_t severity);
static isc_boolean_t
logginglist_empty(dns_c_logginglist_t *ll);
isc_result_t
dns_c_logginglist_new(isc_mem_t *mem, dns_c_logginglist_t **list) {
dns_c_logginglist_t *newl;
REQUIRE(list != NULL);
newl = isc_mem_get(mem, sizeof *newl);
if (newl == NULL) {
return (ISC_R_NOMEMORY);
}
newl->magic = DNS_C_LOGLIST_MAGIC;
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(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);
REQUIRE(DNS_C_LOGLIST_VALID(*list));
l = *list;
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(&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(&cat);
if (res != ISC_R_SUCCESS) {
return (res);
}
cat = tmpcat;
}
l->magic = 0;
isc_mem_put(l->mem, l, sizeof *l);
*list = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logginglist_copy(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(DNS_C_LOGLIST_VALID(src));
res = dns_c_logginglist_new(mem, &newl);
if (res != ISC_R_SUCCESS) {
return (res);
}
logchan = ISC_LIST_HEAD(src->channels);
while (logchan != NULL) {
res = dns_c_logchan_copy(mem, &tmplogchan, logchan);
if (res != ISC_R_SUCCESS) {
dns_c_logginglist_delete(&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(mem, &tmplogcat, logcat);
if (res != ISC_R_SUCCESS) {
dns_c_logginglist_delete(&newl);
return (res);
}
ISC_LIST_APPEND(newl->categories, tmplogcat, next);
logcat = ISC_LIST_NEXT(logcat, next);
}
*dest = newl;
return (ISC_R_SUCCESS);
}
static isc_boolean_t
logginglist_empty(dns_c_logginglist_t *ll) {
dns_c_logchan_t *logchan;
dns_c_logcat_t *logcat;
REQUIRE(DNS_C_LOGLIST_VALID(ll));
logchan = ISC_LIST_HEAD(ll->channels);
while (logchan != NULL) {
if (!logchan->predefined) {
return ISC_FALSE;
}
logchan = ISC_LIST_NEXT(logchan, next);
}
logcat = ISC_LIST_HEAD(ll->categories);
while (logcat != NULL) {
if (!logcat->predefined) {
return ISC_FALSE;
}
logcat = ISC_LIST_NEXT(logcat, next);
}
return ISC_TRUE;
}
void
dns_c_logginglist_print(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);
REQUIRE(DNS_C_LOGLIST_VALID(ll));
if (logginglist_empty(ll)) {
return;
}
dns_c_printtabs(fp, indent);
fprintf(fp, "logging {\n");
logchan = ISC_LIST_HEAD(ll->channels);
while (logchan != NULL) {
dns_c_logchan_print(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(fp, indent + 1, logcat,
if_predef_too);
logcat = ISC_LIST_NEXT(logcat, next);
}
dns_c_printtabs(fp, indent);
fprintf(fp, "};\n");
}
isc_result_t
dns_c_logginglist_addchannel(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(DNS_C_LOGLIST_VALID(list));
REQUIRE(DNS_C_LOGCHAN_VALID(newchan));
if (deepcopy) {
res = dns_c_logchan_copy(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(&tmpchan);
if (res != ISC_R_SUCCESS) {
if (deepcopy) {
dns_c_logchan_delete(&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(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(DNS_C_LOGLIST_VALID(list));
REQUIRE(DNS_C_LOGCAT_VALID(newcat));
if (deepcopy) {
res = dns_c_logcat_copy(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 (strcmp(newcat->catname,tmpcat->catname) == 0) {
existed = ISC_TRUE;
predefined = tmpcat->predefined;
ISC_LIST_UNLINK(list->categories, tmpcat, next);
res = dns_c_logcat_delete(&tmpcat);
if (res != ISC_R_SUCCESS) {
if (deepcopy) {
dns_c_logcat_delete(&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(dns_c_logginglist_t *list,
const char *name)
{
dns_c_logchan_t *logc;
isc_result_t res;
REQUIRE(DNS_C_LOGLIST_VALID(list));
REQUIRE(name != NULL);
REQUIRE(*name != '\0');
res = dns_c_logginglist_chanbyname(list, name, &logc);
if (res == ISC_R_SUCCESS) {
ISC_LIST_UNLINK(list->channels, logc, next);
res = dns_c_logchan_delete(&logc);
}
return (res);
}
isc_result_t
dns_c_logginglist_delcategory(dns_c_logginglist_t *list,
const char *name)
{
dns_c_logcat_t *logc;
isc_result_t res;
REQUIRE(DNS_C_LOGLIST_VALID(list));
REQUIRE(name != NULL);
REQUIRE(*name != '\0');
res = dns_c_logginglist_catbyname(list, name, &logc);
if (res == ISC_R_SUCCESS) {
ISC_LIST_UNLINK(list->categories, logc, next);
res = dns_c_logcat_delete(&logc);
}
return (res);
}
isc_result_t
dns_c_logginglist_chanbyname(dns_c_logginglist_t *list,
const char *name,
dns_c_logchan_t **chan)
{
dns_c_logchan_t *logc;
REQUIRE(DNS_C_LOGLIST_VALID(list));
REQUIRE(name != NULL);
REQUIRE(*name != '\0');
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(dns_c_logginglist_t *list,
const char *name,
dns_c_logcat_t **cat)
{
dns_c_logcat_t *logc;
REQUIRE(DNS_C_LOGLIST_VALID(list));
REQUIRE(name != NULL);
REQUIRE(*name != '\0');
REQUIRE(cat != NULL);
logc = ISC_LIST_HEAD(list->categories);
while (logc != NULL) {
if (strcmp(logc->catname, name) == 0) {
break;
}
logc = ISC_LIST_NEXT(logc, next);
}
if (logc == NULL) {
return (ISC_R_NOTFOUND);
} else {
*cat = logc;
return (ISC_R_SUCCESS);
}
}
#if 0
isc_result_t
dns_c_logginglist_catbytype(dns_c_logginglist_t *list,
dns_c_category_t cattype,
dns_c_logcat_t **cat)
{
dns_c_logcat_t *logc;
REQUIRE(DNS_C_LOGLIST_VALID(list));
REQUIRE(cat != NULL);
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);
}
}
#endif
/* ************************************************************************ */
/* **************************** LOGGING CHANNELS ************************** */
/* ************************************************************************ */
isc_result_t
dns_c_logchan_new(isc_mem_t *mem, const char *name,
dns_c_logchantype_t ctype,
dns_c_logchan_t **newchan)
{
dns_c_logchan_t *newc;
REQUIRE(name != NULL);
REQUIRE(*name != '\0');
REQUIRE(newchan != NULL);
newc = isc_mem_get(mem, sizeof *newc);
if (newc == NULL) {
return (ISC_R_NOMEMORY);
}
newc->magic = DNS_C_LOGCHAN_MAGIC;
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:
case dns_c_logchan_stderr:
break;
}
*newchan = newc;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_delete(dns_c_logchan_t **channel) {
dns_c_logchan_t *logc;
REQUIRE(channel != NULL);
REQUIRE(DNS_C_LOGCHAN_VALID(*channel));
logc = *channel;
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:
case dns_c_logchan_stderr:
break;
}
*channel = NULL;
logc->magic = 0;
isc_mem_put(logc->mem, logc, sizeof *logc);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_copy(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(DNS_C_LOGCHAN_VALID(src));
res = dns_c_logchan_new(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:
case dns_c_logchan_stderr:
break;
}
*dest = logc;
return (ISC_R_SUCCESS);
}
void
dns_c_logchan_print(FILE *fp, int indent, dns_c_logchan_t *logchan,
isc_boolean_t if_predef_too)
{
REQUIRE(fp != NULL);
REQUIRE(DNS_C_LOGCHAN_VALID(logchan));
if (logchan->predefined && !if_predef_too) {
return;
}
dns_c_printtabs(fp, indent);
fprintf(fp, "channel %s {\n", logchan->name) ;
dns_c_printtabs(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(fp, logchan->u.filec.size);
}
break;
case dns_c_logchan_syslog:
fprintf(fp, "syslog ");
print_log_facility(fp, logchan->u.syslogc.facility);
break;
case dns_c_logchan_null:
fputs("null", fp);
break;
case dns_c_logchan_stderr:
fputs("stderr", fp);
break;
}
fprintf(fp, ";\n");
if (DNS_C_CHECKBIT(CHAN_SEVERITY_BIT, &logchan->setflags)) {
dns_c_printtabs(fp, indent + 1);
fprintf(fp, "severity ");
print_log_severity(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(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(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(fp, indent + 1);
fprintf(fp, "print-time %s;\n",
(logchan->print_time ? "true" : "false"));
}
dns_c_printtabs(fp, indent);
fprintf(fp, "};\n");
}
isc_result_t
dns_c_logchan_setpath(dns_c_logchan_t *channel, const char *path) {
isc_boolean_t existed = ISC_FALSE;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
REQUIRE(path != NULL);
REQUIRE(*path != '\0');
if (channel->ctype != dns_c_logchan_file) {
isc_log_write(dns_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(dns_c_logchan_t *channel, isc_uint32_t versions) {
isc_boolean_t existed;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
existed = DNS_C_CHECKBIT(CHAN_VERSIONS_BIT, &channel->setflags);
if (channel->ctype != dns_c_logchan_file) {
isc_log_write(dns_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(dns_c_logchan_t *channel, isc_uint32_t size) {
isc_boolean_t existed;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
if (channel->ctype != dns_c_logchan_file) {
isc_log_write(dns_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(dns_c_logchan_t *channel, int facility) {
isc_boolean_t existed;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
if (channel->ctype != dns_c_logchan_syslog) {
isc_log_write(dns_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(facility, ISC_FALSE) == NULL) {
isc_log_write(dns_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(dns_c_logchan_t *channel,
dns_c_logseverity_t severity)
{
isc_boolean_t existed;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_int32_t level) {
isc_boolean_t existed;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_boolean_t newval) {
isc_boolean_t existed;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_boolean_t newval) {
isc_boolean_t existed;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_boolean_t newval) {
isc_boolean_t existed;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_boolean_t newval) {
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
channel->predefined = newval;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logchan_getpath(dns_c_logchan_t *channel, const char **path) {
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_uint32_t *retval) {
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_uint32_t *retval) {
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, int *retval) {
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel,
dns_c_logseverity_t *retval)
{
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_int32_t *retval) {
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_boolean_t *retval) {
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_boolean_t *retval) {
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_boolean_t *retval) {
isc_result_t res;
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
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(dns_c_logchan_t *channel, isc_boolean_t *retval) {
REQUIRE(DNS_C_LOGCHAN_VALID(channel));
REQUIRE(retval != NULL);
*retval = channel->predefined;
return (ISC_R_SUCCESS);
}
/*
* Logging category
*/
isc_result_t
dns_c_logcat_new(isc_mem_t *mem, const char *name, dns_c_logcat_t **newlc) {
dns_c_logcat_t *newc;
unsigned int i;
REQUIRE(newlc != NULL);
newc = isc_mem_get(mem, sizeof *newc);
if (newc == NULL) {
return (ISC_R_NOMEMORY);
}
newc->magic = DNS_C_LOGCAT_MAGIC;
newc->mem = mem;
newc->catname = isc_mem_strdup(mem, name);
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(dns_c_logcat_t **logcat) {
dns_c_logcat_t *logc;
unsigned int i;
REQUIRE(logcat != NULL);
REQUIRE(DNS_C_LOGCAT_VALID(*logcat));
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]);
}
logc->magic = 0;
isc_mem_free(logc->mem, logc->catname);
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_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(DNS_C_LOGCAT_VALID(src));
res = dns_c_logcat_new(mem, src->catname, &newc);
if (res != ISC_R_SUCCESS) {
return (res);
}
for (i = 0 ; i < src->nextcname ; i++) {
res = dns_c_logcat_addname(newc, src->channel_names[i]);
if (res != ISC_R_SUCCESS) {
dns_c_logcat_delete(&newc);
return (res);
}
}
*dest = newc;
return (ISC_R_SUCCESS);
}
void
dns_c_logcat_print(FILE *fp, int indent, dns_c_logcat_t *logcat,
isc_boolean_t if_predef_too)
{
unsigned int i;
REQUIRE(fp != NULL);
REQUIRE(DNS_C_LOGCAT_VALID(logcat));
if (logcat->predefined && !if_predef_too) {
return;
}
dns_c_printtabs(fp, indent);
fprintf(fp, "category %s {\n", logcat->catname);
for (i = 0 ; i < logcat->nextcname ; i++) {
dns_c_printtabs(fp, indent + 1);
fprintf(fp, "%s;\n", logcat->channel_names[i]);
}
dns_c_printtabs(fp, indent);
fprintf(fp, "};\n");
}
isc_result_t
dns_c_logcat_addname(dns_c_logcat_t *logcat, const char *name) {
unsigned int i;
REQUIRE(DNS_C_LOGCAT_VALID(logcat));
REQUIRE(name != NULL);
REQUIRE(*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(dns_c_logcat_t *logcat, const char *name) {
unsigned int i ;
isc_result_t res;
REQUIRE(DNS_C_LOGCAT_VALID(logcat));
REQUIRE(name != NULL);
REQUIRE(*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(dns_c_logcat_t *logcat,isc_boolean_t newval) {
REQUIRE(DNS_C_LOGCAT_VALID(logcat));
logcat->predefined = newval;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_logcat_getpredef(dns_c_logcat_t *logcat, isc_boolean_t *retval) {
REQUIRE(DNS_C_LOGCAT_VALID(logcat));
REQUIRE(retval != NULL);
*retval = logcat->predefined;
return (ISC_R_SUCCESS);
}
/***************************************************************************/
static void
print_log_facility(FILE *fp, int value) {
REQUIRE(fp != NULL);
fputs(dns_c_facility2string(value, ISC_TRUE), fp);
}
static void
print_log_severity(FILE *fp, dns_c_logseverity_t severity) {
REQUIRE(fp != NULL);
fputs(dns_c_logseverity2string(severity, ISC_TRUE), fp);
}