xref: /minix3/external/bsd/bind/dist/bin/named/logconf.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: logconf.c,v 1.7 2014/12/10 04:37:51 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004-2007, 2011, 2013  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1999-2001  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: logconf.c,v 1.45 2011/03/05 23:52:29 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <isc/file.h>
27*00b67f09SDavid van Moolenbroek #include <isc/offset.h>
28*00b67f09SDavid van Moolenbroek #include <isc/result.h>
29*00b67f09SDavid van Moolenbroek #include <isc/stdio.h>
30*00b67f09SDavid van Moolenbroek #include <isc/string.h>
31*00b67f09SDavid van Moolenbroek #include <isc/syslog.h>
32*00b67f09SDavid van Moolenbroek 
33*00b67f09SDavid van Moolenbroek #include <isccfg/cfg.h>
34*00b67f09SDavid van Moolenbroek #include <isccfg/log.h>
35*00b67f09SDavid van Moolenbroek 
36*00b67f09SDavid van Moolenbroek #include <named/log.h>
37*00b67f09SDavid van Moolenbroek #include <named/logconf.h>
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek #define CHECK(op) \
40*00b67f09SDavid van Moolenbroek 	do { result = (op); 				  	 \
41*00b67f09SDavid van Moolenbroek 	       if (result != ISC_R_SUCCESS) goto cleanup; 	 \
42*00b67f09SDavid van Moolenbroek 	} while (/*CONSTCOND*/0)
43*00b67f09SDavid van Moolenbroek 
44*00b67f09SDavid van Moolenbroek /*%
45*00b67f09SDavid van Moolenbroek  * Set up a logging category according to the named.conf data
46*00b67f09SDavid van Moolenbroek  * in 'ccat' and add it to 'logconfig'.
47*00b67f09SDavid van Moolenbroek  */
48*00b67f09SDavid van Moolenbroek static isc_result_t
category_fromconf(const cfg_obj_t * ccat,isc_logconfig_t * logconfig)49*00b67f09SDavid van Moolenbroek category_fromconf(const cfg_obj_t *ccat, isc_logconfig_t *logconfig) {
50*00b67f09SDavid van Moolenbroek 	isc_result_t result;
51*00b67f09SDavid van Moolenbroek 	const char *catname;
52*00b67f09SDavid van Moolenbroek 	isc_logcategory_t *category;
53*00b67f09SDavid van Moolenbroek 	isc_logmodule_t *module;
54*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *destinations = NULL;
55*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *element = NULL;
56*00b67f09SDavid van Moolenbroek 
57*00b67f09SDavid van Moolenbroek 	catname = cfg_obj_asstring(cfg_tuple_get(ccat, "name"));
58*00b67f09SDavid van Moolenbroek 	category = isc_log_categorybyname(ns_g_lctx, catname);
59*00b67f09SDavid van Moolenbroek 	if (category == NULL) {
60*00b67f09SDavid van Moolenbroek 		cfg_obj_log(ccat, ns_g_lctx, ISC_LOG_ERROR,
61*00b67f09SDavid van Moolenbroek 			    "unknown logging category '%s' ignored",
62*00b67f09SDavid van Moolenbroek 			    catname);
63*00b67f09SDavid van Moolenbroek 		/*
64*00b67f09SDavid van Moolenbroek 		 * Allow further processing by returning success.
65*00b67f09SDavid van Moolenbroek 		 */
66*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
67*00b67f09SDavid van Moolenbroek 	}
68*00b67f09SDavid van Moolenbroek 
69*00b67f09SDavid van Moolenbroek 	if (logconfig == NULL)
70*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
71*00b67f09SDavid van Moolenbroek 
72*00b67f09SDavid van Moolenbroek 	module = NULL;
73*00b67f09SDavid van Moolenbroek 
74*00b67f09SDavid van Moolenbroek 	destinations = cfg_tuple_get(ccat, "destinations");
75*00b67f09SDavid van Moolenbroek 	for (element = cfg_list_first(destinations);
76*00b67f09SDavid van Moolenbroek 	     element != NULL;
77*00b67f09SDavid van Moolenbroek 	     element = cfg_list_next(element))
78*00b67f09SDavid van Moolenbroek 	{
79*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *channel = cfg_listelt_value(element);
80*00b67f09SDavid van Moolenbroek 		const char *channelname = cfg_obj_asstring(channel);
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek 		result = isc_log_usechannel(logconfig, channelname, category,
83*00b67f09SDavid van Moolenbroek 					    module);
84*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS) {
85*00b67f09SDavid van Moolenbroek 			isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG,
86*00b67f09SDavid van Moolenbroek 				      NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
87*00b67f09SDavid van Moolenbroek 				      "logging channel '%s': %s", channelname,
88*00b67f09SDavid van Moolenbroek 				      isc_result_totext(result));
89*00b67f09SDavid van Moolenbroek 			return (result);
90*00b67f09SDavid van Moolenbroek 		}
91*00b67f09SDavid van Moolenbroek 	}
92*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
93*00b67f09SDavid van Moolenbroek }
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek /*%
96*00b67f09SDavid van Moolenbroek  * Set up a logging channel according to the named.conf data
97*00b67f09SDavid van Moolenbroek  * in 'cchan' and add it to 'logconfig'.
98*00b67f09SDavid van Moolenbroek  */
99*00b67f09SDavid van Moolenbroek static isc_result_t
channel_fromconf(const cfg_obj_t * channel,isc_logconfig_t * logconfig)100*00b67f09SDavid van Moolenbroek channel_fromconf(const cfg_obj_t *channel, isc_logconfig_t *logconfig)
101*00b67f09SDavid van Moolenbroek {
102*00b67f09SDavid van Moolenbroek 	isc_result_t result;
103*00b67f09SDavid van Moolenbroek 	isc_logdestination_t dest;
104*00b67f09SDavid van Moolenbroek 	unsigned int type;
105*00b67f09SDavid van Moolenbroek 	unsigned int flags = 0;
106*00b67f09SDavid van Moolenbroek 	int level;
107*00b67f09SDavid van Moolenbroek 	const char *channelname;
108*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *fileobj = NULL;
109*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *syslogobj = NULL;
110*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *nullobj = NULL;
111*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *stderrobj = NULL;
112*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *severity = NULL;
113*00b67f09SDavid van Moolenbroek 	int i;
114*00b67f09SDavid van Moolenbroek 
115*00b67f09SDavid van Moolenbroek 	channelname = cfg_obj_asstring(cfg_map_getname(channel));
116*00b67f09SDavid van Moolenbroek 
117*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(channel, "file", &fileobj);
118*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(channel, "syslog", &syslogobj);
119*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(channel, "null", &nullobj);
120*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(channel, "stderr", &stderrobj);
121*00b67f09SDavid van Moolenbroek 
122*00b67f09SDavid van Moolenbroek 	i = 0;
123*00b67f09SDavid van Moolenbroek 	if (fileobj != NULL)
124*00b67f09SDavid van Moolenbroek 		i++;
125*00b67f09SDavid van Moolenbroek 	if (syslogobj != NULL)
126*00b67f09SDavid van Moolenbroek 		i++;
127*00b67f09SDavid van Moolenbroek 	if (nullobj != NULL)
128*00b67f09SDavid van Moolenbroek 		i++;
129*00b67f09SDavid van Moolenbroek 	if (stderrobj != NULL)
130*00b67f09SDavid van Moolenbroek 		i++;
131*00b67f09SDavid van Moolenbroek 
132*00b67f09SDavid van Moolenbroek 	if (i != 1) {
133*00b67f09SDavid van Moolenbroek 		cfg_obj_log(channel, ns_g_lctx, ISC_LOG_ERROR,
134*00b67f09SDavid van Moolenbroek 			      "channel '%s': exactly one of file, syslog, "
135*00b67f09SDavid van Moolenbroek 			      "null, and stderr must be present", channelname);
136*00b67f09SDavid van Moolenbroek 		return (ISC_R_FAILURE);
137*00b67f09SDavid van Moolenbroek 	}
138*00b67f09SDavid van Moolenbroek 
139*00b67f09SDavid van Moolenbroek 	type = ISC_LOG_TONULL;
140*00b67f09SDavid van Moolenbroek 
141*00b67f09SDavid van Moolenbroek 	if (fileobj != NULL) {
142*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file");
143*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size");
144*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *versionsobj =
145*00b67f09SDavid van Moolenbroek 				 cfg_tuple_get(fileobj, "versions");
146*00b67f09SDavid van Moolenbroek 		isc_int32_t versions = ISC_LOG_ROLLNEVER;
147*00b67f09SDavid van Moolenbroek 		isc_offset_t size = 0;
148*00b67f09SDavid van Moolenbroek 
149*00b67f09SDavid van Moolenbroek 		type = ISC_LOG_TOFILE;
150*00b67f09SDavid van Moolenbroek 
151*00b67f09SDavid van Moolenbroek 		if (versionsobj != NULL && cfg_obj_isuint32(versionsobj))
152*00b67f09SDavid van Moolenbroek 			versions = cfg_obj_asuint32(versionsobj);
153*00b67f09SDavid van Moolenbroek 		if (versionsobj != NULL && cfg_obj_isstring(versionsobj) &&
154*00b67f09SDavid van Moolenbroek 		    strcasecmp(cfg_obj_asstring(versionsobj), "unlimited") == 0)
155*00b67f09SDavid van Moolenbroek 			versions = ISC_LOG_ROLLINFINITE;
156*00b67f09SDavid van Moolenbroek 		if (sizeobj != NULL &&
157*00b67f09SDavid van Moolenbroek 		    cfg_obj_isuint64(sizeobj) &&
158*00b67f09SDavid van Moolenbroek 		    cfg_obj_asuint64(sizeobj) < ISC_OFFSET_MAXIMUM)
159*00b67f09SDavid van Moolenbroek 			size = (isc_offset_t)cfg_obj_asuint64(sizeobj);
160*00b67f09SDavid van Moolenbroek 		dest.file.stream = NULL;
161*00b67f09SDavid van Moolenbroek 		dest.file.name = cfg_obj_asstring(pathobj);
162*00b67f09SDavid van Moolenbroek 		dest.file.versions = versions;
163*00b67f09SDavid van Moolenbroek 		dest.file.maximum_size = size;
164*00b67f09SDavid van Moolenbroek 	} else if (syslogobj != NULL) {
165*00b67f09SDavid van Moolenbroek 		int facility = LOG_DAEMON;
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek 		type = ISC_LOG_TOSYSLOG;
168*00b67f09SDavid van Moolenbroek 
169*00b67f09SDavid van Moolenbroek 		if (cfg_obj_isstring(syslogobj)) {
170*00b67f09SDavid van Moolenbroek 			const char *facilitystr = cfg_obj_asstring(syslogobj);
171*00b67f09SDavid van Moolenbroek 			(void)isc_syslog_facilityfromstring(facilitystr,
172*00b67f09SDavid van Moolenbroek 							    &facility);
173*00b67f09SDavid van Moolenbroek 		}
174*00b67f09SDavid van Moolenbroek 		dest.facility = facility;
175*00b67f09SDavid van Moolenbroek 	} else if (stderrobj != NULL) {
176*00b67f09SDavid van Moolenbroek 		type = ISC_LOG_TOFILEDESC;
177*00b67f09SDavid van Moolenbroek 		dest.file.stream = stderr;
178*00b67f09SDavid van Moolenbroek 		dest.file.name = NULL;
179*00b67f09SDavid van Moolenbroek 		dest.file.versions = ISC_LOG_ROLLNEVER;
180*00b67f09SDavid van Moolenbroek 		dest.file.maximum_size = 0;
181*00b67f09SDavid van Moolenbroek 	}
182*00b67f09SDavid van Moolenbroek 
183*00b67f09SDavid van Moolenbroek 	/*
184*00b67f09SDavid van Moolenbroek 	 * Munge flags.
185*00b67f09SDavid van Moolenbroek 	 */
186*00b67f09SDavid van Moolenbroek 	{
187*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *printcat = NULL;
188*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *printsev = NULL;
189*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *printtime = NULL;
190*00b67f09SDavid van Moolenbroek 
191*00b67f09SDavid van Moolenbroek 		(void)cfg_map_get(channel, "print-category", &printcat);
192*00b67f09SDavid van Moolenbroek 		(void)cfg_map_get(channel, "print-severity", &printsev);
193*00b67f09SDavid van Moolenbroek 		(void)cfg_map_get(channel, "print-time", &printtime);
194*00b67f09SDavid van Moolenbroek 
195*00b67f09SDavid van Moolenbroek 		if (printcat != NULL && cfg_obj_asboolean(printcat))
196*00b67f09SDavid van Moolenbroek 			flags |= ISC_LOG_PRINTCATEGORY;
197*00b67f09SDavid van Moolenbroek 		if (printtime != NULL && cfg_obj_asboolean(printtime))
198*00b67f09SDavid van Moolenbroek 			flags |= ISC_LOG_PRINTTIME;
199*00b67f09SDavid van Moolenbroek 		if (printsev != NULL && cfg_obj_asboolean(printsev))
200*00b67f09SDavid van Moolenbroek 			flags |= ISC_LOG_PRINTLEVEL;
201*00b67f09SDavid van Moolenbroek 	}
202*00b67f09SDavid van Moolenbroek 
203*00b67f09SDavid van Moolenbroek 	level = ISC_LOG_INFO;
204*00b67f09SDavid van Moolenbroek 	if (cfg_map_get(channel, "severity", &severity) == ISC_R_SUCCESS) {
205*00b67f09SDavid van Moolenbroek 		if (cfg_obj_isstring(severity)) {
206*00b67f09SDavid van Moolenbroek 			const char *str = cfg_obj_asstring(severity);
207*00b67f09SDavid van Moolenbroek 			if (strcasecmp(str, "critical") == 0)
208*00b67f09SDavid van Moolenbroek 				level = ISC_LOG_CRITICAL;
209*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(str, "error") == 0)
210*00b67f09SDavid van Moolenbroek 				level = ISC_LOG_ERROR;
211*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(str, "warning") == 0)
212*00b67f09SDavid van Moolenbroek 				level = ISC_LOG_WARNING;
213*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(str, "notice") == 0)
214*00b67f09SDavid van Moolenbroek 				level = ISC_LOG_NOTICE;
215*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(str, "info") == 0)
216*00b67f09SDavid van Moolenbroek 				level = ISC_LOG_INFO;
217*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(str, "dynamic") == 0)
218*00b67f09SDavid van Moolenbroek 				level = ISC_LOG_DYNAMIC;
219*00b67f09SDavid van Moolenbroek 		} else
220*00b67f09SDavid van Moolenbroek 			/* debug */
221*00b67f09SDavid van Moolenbroek 			level = cfg_obj_asuint32(severity);
222*00b67f09SDavid van Moolenbroek 	}
223*00b67f09SDavid van Moolenbroek 
224*00b67f09SDavid van Moolenbroek 	if (logconfig == NULL)
225*00b67f09SDavid van Moolenbroek 		result = ISC_R_SUCCESS;
226*00b67f09SDavid van Moolenbroek 	else
227*00b67f09SDavid van Moolenbroek 		result = isc_log_createchannel(logconfig, channelname,
228*00b67f09SDavid van Moolenbroek 					       type, level, &dest, flags);
229*00b67f09SDavid van Moolenbroek 
230*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS && type == ISC_LOG_TOFILE) {
231*00b67f09SDavid van Moolenbroek 		FILE *fp;
232*00b67f09SDavid van Moolenbroek 
233*00b67f09SDavid van Moolenbroek 		/*
234*00b67f09SDavid van Moolenbroek 		 * Test to make sure that file is a plain file.
235*00b67f09SDavid van Moolenbroek 		 * Fix defect #22771
236*00b67f09SDavid van Moolenbroek 		*/
237*00b67f09SDavid van Moolenbroek 		result = isc_file_isplainfile(dest.file.name);
238*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS || result == ISC_R_FILENOTFOUND) {
239*00b67f09SDavid van Moolenbroek 			/*
240*00b67f09SDavid van Moolenbroek 			 * Test that the file can be opened, since
241*00b67f09SDavid van Moolenbroek 			 * isc_log_open() can't effectively report
242*00b67f09SDavid van Moolenbroek 			 * failures when called in isc_log_doit().
243*00b67f09SDavid van Moolenbroek 			 */
244*00b67f09SDavid van Moolenbroek 			result = isc_stdio_open(dest.file.name, "a", &fp);
245*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
246*00b67f09SDavid van Moolenbroek 				if (logconfig != NULL && !ns_g_nosyslog)
247*00b67f09SDavid van Moolenbroek 					syslog(LOG_ERR,
248*00b67f09SDavid van Moolenbroek 						"isc_stdio_open '%s' failed: "
249*00b67f09SDavid van Moolenbroek 						"%s", dest.file.name,
250*00b67f09SDavid van Moolenbroek 						isc_result_totext(result));
251*00b67f09SDavid van Moolenbroek 				fprintf(stderr,
252*00b67f09SDavid van Moolenbroek 					"isc_stdio_open '%s' failed: %s\n",
253*00b67f09SDavid van Moolenbroek 					dest.file.name,
254*00b67f09SDavid van Moolenbroek 					isc_result_totext(result));
255*00b67f09SDavid van Moolenbroek 			} else
256*00b67f09SDavid van Moolenbroek 				(void)isc_stdio_close(fp);
257*00b67f09SDavid van Moolenbroek 			goto done;
258*00b67f09SDavid van Moolenbroek 		}
259*00b67f09SDavid van Moolenbroek 		if (logconfig != NULL && !ns_g_nosyslog)
260*00b67f09SDavid van Moolenbroek 			syslog(LOG_ERR, "isc_file_isplainfile '%s' failed: %s",
261*00b67f09SDavid van Moolenbroek 			       dest.file.name, isc_result_totext(result));
262*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "isc_file_isplainfile '%s' failed: %s\n",
263*00b67f09SDavid van Moolenbroek 			dest.file.name, isc_result_totext(result));
264*00b67f09SDavid van Moolenbroek 	}
265*00b67f09SDavid van Moolenbroek 
266*00b67f09SDavid van Moolenbroek  done:
267*00b67f09SDavid van Moolenbroek 	return (result);
268*00b67f09SDavid van Moolenbroek }
269*00b67f09SDavid van Moolenbroek 
270*00b67f09SDavid van Moolenbroek isc_result_t
ns_log_configure(isc_logconfig_t * logconfig,const cfg_obj_t * logstmt)271*00b67f09SDavid van Moolenbroek ns_log_configure(isc_logconfig_t *logconfig, const cfg_obj_t *logstmt) {
272*00b67f09SDavid van Moolenbroek 	isc_result_t result;
273*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *channels = NULL;
274*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *categories = NULL;
275*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *element;
276*00b67f09SDavid van Moolenbroek 	isc_boolean_t default_set = ISC_FALSE;
277*00b67f09SDavid van Moolenbroek 	isc_boolean_t unmatched_set = ISC_FALSE;
278*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *catname;
279*00b67f09SDavid van Moolenbroek 
280*00b67f09SDavid van Moolenbroek 	if (logconfig != NULL)
281*00b67f09SDavid van Moolenbroek 		CHECK(ns_log_setdefaultchannels(logconfig));
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(logstmt, "channel", &channels);
284*00b67f09SDavid van Moolenbroek 	for (element = cfg_list_first(channels);
285*00b67f09SDavid van Moolenbroek 	     element != NULL;
286*00b67f09SDavid van Moolenbroek 	     element = cfg_list_next(element))
287*00b67f09SDavid van Moolenbroek 	{
288*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *channel = cfg_listelt_value(element);
289*00b67f09SDavid van Moolenbroek 		CHECK(channel_fromconf(channel, logconfig));
290*00b67f09SDavid van Moolenbroek 	}
291*00b67f09SDavid van Moolenbroek 
292*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(logstmt, "category", &categories);
293*00b67f09SDavid van Moolenbroek 	for (element = cfg_list_first(categories);
294*00b67f09SDavid van Moolenbroek 	     element != NULL;
295*00b67f09SDavid van Moolenbroek 	     element = cfg_list_next(element))
296*00b67f09SDavid van Moolenbroek 	{
297*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *category = cfg_listelt_value(element);
298*00b67f09SDavid van Moolenbroek 		CHECK(category_fromconf(category, logconfig));
299*00b67f09SDavid van Moolenbroek 		if (!default_set) {
300*00b67f09SDavid van Moolenbroek 			catname = cfg_tuple_get(category, "name");
301*00b67f09SDavid van Moolenbroek 			if (strcmp(cfg_obj_asstring(catname), "default") == 0)
302*00b67f09SDavid van Moolenbroek 				default_set = ISC_TRUE;
303*00b67f09SDavid van Moolenbroek 		}
304*00b67f09SDavid van Moolenbroek 		if (!unmatched_set) {
305*00b67f09SDavid van Moolenbroek 			catname = cfg_tuple_get(category, "name");
306*00b67f09SDavid van Moolenbroek 			if (strcmp(cfg_obj_asstring(catname), "unmatched") == 0)
307*00b67f09SDavid van Moolenbroek 				unmatched_set = ISC_TRUE;
308*00b67f09SDavid van Moolenbroek 		}
309*00b67f09SDavid van Moolenbroek 	}
310*00b67f09SDavid van Moolenbroek 
311*00b67f09SDavid van Moolenbroek 	if (logconfig != NULL && !default_set)
312*00b67f09SDavid van Moolenbroek 		CHECK(ns_log_setdefaultcategory(logconfig));
313*00b67f09SDavid van Moolenbroek 
314*00b67f09SDavid van Moolenbroek 	if (logconfig != NULL && !unmatched_set)
315*00b67f09SDavid van Moolenbroek 		CHECK(ns_log_setunmatchedcategory(logconfig));
316*00b67f09SDavid van Moolenbroek 
317*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
318*00b67f09SDavid van Moolenbroek 
319*00b67f09SDavid van Moolenbroek  cleanup:
320*00b67f09SDavid van Moolenbroek 	return (result);
321*00b67f09SDavid van Moolenbroek }
322