1cb5caa9djl/*
2cb5caa9djl * CDDL HEADER START
3cb5caa9djl *
4cb5caa9djl * The contents of this file are subject to the terms of the
5cb5caa9djl * Common Development and Distribution License (the "License").
6cb5caa9djl * You may not use this file except in compliance with the License.
7cb5caa9djl *
8cb5caa9djl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9cb5caa9djl * or http://www.opensolaris.org/os/licensing.
10cb5caa9djl * See the License for the specific language governing permissions
11cb5caa9djl * and limitations under the License.
12cb5caa9djl *
13cb5caa9djl * When distributing Covered Code, include this CDDL HEADER in each
14cb5caa9djl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15cb5caa9djl * If applicable, add the following below this CDDL HEADER, with the
16cb5caa9djl * fields enclosed by brackets "[]" replaced with your own identifying
17cb5caa9djl * information: Portions Copyright [yyyy] [name of copyright owner]
18cb5caa9djl *
19cb5caa9djl * CDDL HEADER END
20cb5caa9djl */
21cb5caa9djl/*
2218bdb8amichen * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23cb5caa9djl * Use is subject to license terms.
24cb5caa9djl */
25cb5caa9djl
26cb5caa9djl#pragma ident	"%Z%%M%	%I%	%E% SMI"
27cb5caa9djl
28cb5caa9djl#include <stdlib.h>
29cb5caa9djl#include <locale.h>
30cb5caa9djl#include <limits.h>
31cb5caa9djl#include <fcntl.h>
32cb5caa9djl#include <sys/stat.h>
33cb5caa9djl#include <sys/varargs.h>
34cb5caa9djl#include <synch.h>
35cb5caa9djl#include <thread.h>
36cb5caa9djl#include <string.h>
37cb5caa9djl#include <unistd.h>
38cb5caa9djl#include "nscd_log.h"
39cb5caa9djl#include "nscd_config.h"
40cb5caa9djl#include "nscd_switch.h"
41cb5caa9djl#include "cache.h"
42cb5caa9djl
43cb5caa9djl/*
44cb5caa9djl * old nscd debug levels
45cb5caa9djl */
46cb5caa9djl#define	DBG_OFF		0
47cb5caa9djl#define	DBG_CANT_FIND	2
48cb5caa9djl#define	DBG_NETLOOKUPS	4
49cb5caa9djl#define	DBG_ALL		6
50cb5caa9djl
51cb5caa9djl/* max. chars in a nscd log entry */
52cb5caa9djl#define	LOGBUFLEN	1024
53cb5caa9djl
54cb5caa9djl/* configuration for the nscd log component */
5518bdb8amichenint		_nscd_log_comp = 0x0;
5618bdb8amichenint		_nscd_log_level = 0x0;
5718bdb8amichenstatic char	_nscd_logfile[PATH_MAX] = { 0 };
5818bdb8amichen
5918bdb8amichen#define	NSCD_DEBUG_NONE		'0'
6018bdb8amichen#define	NSCD_DEBUG_OPEN		'1'
6118bdb8amichen#define	NSCD_DEBUG_CLOSE	'2'
6218bdb8amichen
6318bdb8amichenstatic char	_nscd_debug = NSCD_DEBUG_NONE;
6418bdb8amichenstatic char	_nscd_logfile_d[PATH_MAX] = { 0 };
6518bdb8amichenstatic char	_nscd_logfile_s[PATH_MAX] = { 0 };
66cb5caa9djl
67cb5caa9djl/* statistics data */
68cb5caa9djlstatic nscd_cfg_stat_global_log_t logstats = {
69cb5caa9djl	NSCD_CFG_STAT_GROUP_INFO_GLOBAL_LOG, 0 };
70cb5caa9djl
71cb5caa9djl/* if no log file specified, log entry goes to stderr */
72cb5caa9djlint _logfd = 2;
73cb5caa9djl
7418bdb8amichen
75cb5caa9djl/* close old log file and open a new one */
76cb5caa9djlstatic nscd_rc_t
77cb5caa9djl_nscd_set_lf(
78cb5caa9djl	char	*lf)
79cb5caa9djl{
80cb5caa9djl	int	newlogfd;
81cb5caa9djl	char	*me = "_nscd_set_lf";
82cb5caa9djl
83cb5caa9djl	/*
84cb5caa9djl	 *  don't try and open the log file /dev/null
85cb5caa9djl	 */
86cb5caa9djl	if (lf == NULL || *lf == 0) {
87cb5caa9djl		/* ignore empty log file specs */
88cb5caa9djl		return (NSCD_SUCCESS);
89cb5caa9djl	} else if (strcmp(lf, "/dev/null") == 0) {
9018bdb8amichen		(void) strlcpy(_nscd_logfile, lf, PATH_MAX);
91cb5caa9djl		if (_logfd >= 0)
92cb5caa9djl			(void) close(_logfd);
93cb5caa9djl		_logfd = -1;
94cb5caa9djl		return (NSCD_SUCCESS);
95cb5caa9djl	} else if (strcmp(lf, "stderr") == 0) {
9618bdb8amichen		(void) strlcpy(_nscd_logfile, lf, PATH_MAX);
97cb5caa9djl		if (_logfd != -1 && _logfd != 2)
98cb5caa9djl			(void) close(_logfd);
99cb5caa9djl		_logfd = 2;
100cb5caa9djl		return (NSCD_SUCCESS);
101cb5caa9djl	} else {
102cb5caa9djl
103cb5caa9djl		/*
104cb5caa9djl		 * In order to open this file securely, we'll try a few tricks
105cb5caa9djl		 */
106cb5caa9djl
107cb5caa9djl		if ((newlogfd = open(lf, O_EXCL|O_WRONLY|O_CREAT, 0644)) < 0) {
108cb5caa9djl			/*
109cb5caa9djl			 * File already exists... now we need to get cute
110cb5caa9djl			 * since opening a file in a world-writeable directory
111cb5caa9djl			 * safely is hard = it could be a hard link or a
112cb5caa9djl			 * symbolic link to a system file.
113cb5caa9djl			 */
114cb5caa9djl			struct stat before;
115cb5caa9djl
116cb5caa9djl			if (lstat(lf, &before) < 0) {
11718bdb8amichen				if (_nscd_debug == NSCD_DEBUG_NONE)
11818bdb8amichen					_nscd_logit(me, "Cannot open new "
11918bdb8amichen					    "logfile \"%s\": %sn",
12018bdb8amichen					    lf, strerror(errno));
121cb5caa9djl				return (NSCD_CFG_FILE_OPEN_ERROR);
122cb5caa9djl			}
123cb5caa9djl
124cb5caa9djl			if (S_ISREG(before.st_mode) && /* no symbolic links */
12518bdb8amichen			    (before.st_nlink == 1) && /* no hard links */
12618bdb8amichen			    (before.st_uid == 0)) {   /* owned by root */
127cb5caa9djl				if ((newlogfd =
128cb5caa9djl				    open(lf, O_APPEND|O_WRONLY, 0644)) < 0) {
12918bdb8amichen					if (_nscd_debug == NSCD_DEBUG_NONE)
13018bdb8amichen						_nscd_logit(me,
13118bdb8amichen						    "Cannot open new "\
13218bdb8amichen						    "logfile \"%s\": %s\n", lf,
13318bdb8amichen						    strerror(errno));
134cb5caa9djl					return (NSCD_CFG_FILE_OPEN_ERROR);
135cb5caa9djl				}
136cb5caa9djl			} else {
13718bdb8amichen				if (_nscd_debug == NSCD_DEBUG_NONE)
13818bdb8amichen					_nscd_logit(me, "Cannot use specified "
13918bdb8amichen					    "logfile \"%s\": "\
14018bdb8amichen					    "file is/has links or isn't "
14118bdb8amichen					    "owned by root\n", lf);
142cb5caa9djl				return (NSCD_CFG_FILE_OPEN_ERROR);
143cb5caa9djl			}
144cb5caa9djl		}
145cb5caa9djl
146cb5caa9djl		(void) close(_logfd);
14718bdb8amichen		(void) strlcpy(_nscd_logfile, lf, PATH_MAX);
148cb5caa9djl		_logfd = newlogfd;
14918bdb8amichen		if (_nscd_debug == NSCD_DEBUG_NONE)
15018bdb8amichen			_nscd_logit(me, "Start of new logfile %s\n", lf);
151cb5caa9djl	}
152cb5caa9djl	return (NSCD_SUCCESS);
153cb5caa9djl}
154cb5caa9djl
155cb5caa9djl
156cb5caa9djl/* log an entry to the configured nscd log file */
157cb5caa9djlvoid
158cb5caa9djl_nscd_logit(
159cb5caa9djl	char		*funcname,
160cb5caa9djl	char		*format,
161cb5caa9djl	...)
162cb5caa9djl{
163cb5caa9djl	static mutex_t	loglock = DEFAULTMUTEX;
164cb5caa9djl	struct timeval	tv;
165cb5caa9djl	char		tid_buf[32];
166cb5caa9djl	char		pid_buf[32];
167cb5caa9djl	char		buffer[LOGBUFLEN];
168cb5caa9djl	int		safechars, offset;
169cb5caa9djl	va_list		ap;
170cb5caa9djl
171cb5caa9djl	if (_logfd < 0)
172cb5caa9djl		return;
173cb5caa9djl
17418bdb8amichen	if (_nscd_debug == NSCD_DEBUG_OPEN) {
17518bdb8amichen		(void) mutex_lock(&loglock);
17618bdb8amichen		if (_nscd_debug == NSCD_DEBUG_OPEN &&
17718bdb8amichen		    *_nscd_logfile_d != '\0' &&
17818bdb8amichen		    (strcmp(_nscd_logfile, "/dev/null") == 0 ||
17918bdb8amichen		    strcmp(_nscd_logfile, "stderr") == 0)) {
18018bdb8amichen			(void) strlcpy(_nscd_logfile_s,
18118bdb8amichen			    _nscd_logfile, PATH_MAX);
18218bdb8amichen			(void) _nscd_set_lf(_nscd_logfile_d);
18318bdb8amichen		}
18418bdb8amichen		_nscd_debug = NSCD_DEBUG_NONE;
18518bdb8amichen		(void) mutex_unlock(&loglock);
18618bdb8amichen	} else if (_nscd_debug == NSCD_DEBUG_CLOSE) {
18718bdb8amichen		(void) mutex_lock(&loglock);
18818bdb8amichen		if (_nscd_debug == NSCD_DEBUG_CLOSE)
18918bdb8amichen			(void) _nscd_set_lf(_nscd_logfile_s);
19018bdb8amichen		_nscd_debug = NSCD_DEBUG_NONE;
19118bdb8amichen		(void) mutex_unlock(&loglock);
19218bdb8amichen	}
19318bdb8amichen
194cb5caa9djl	va_start(ap, format);
195cb5caa9djl
196cb5caa9djl	if (gettimeofday(&tv, NULL) != 0 ||
197cb5caa9djl	    ctime_r(&tv.tv_sec, buffer, LOGBUFLEN) == NULL) {
198cb5caa9djl		(void) snprintf(buffer, LOGBUFLEN,
199cb5caa9djl		    "<time conversion failed>\t");
200cb5caa9djl	} else {
201cb5caa9djl		(void) sprintf(tid_buf, "--%d", thr_self());
202cb5caa9djl		(void) sprintf(pid_buf, "--%ld", getpid());
203cb5caa9djl		/*
204cb5caa9djl		 * ctime_r() includes some stuff we don't want;
205cb5caa9djl		 * adjust length to overwrite " YYYY\n" and
206cb5caa9djl		 * include tid string length.
207cb5caa9djl		 */
208cb5caa9djl		offset = strlen(buffer) - 6;
209cb5caa9djl		safechars = LOGBUFLEN - (offset - 1);
210cb5caa9djl		(void) snprintf(buffer + offset,
21118bdb8amichen		    safechars, ".%.4ld%s%s\t%s:\n\t\t",
21218bdb8amichen		    tv.tv_usec/100, tid_buf, pid_buf,
21318bdb8amichen		    funcname);
214cb5caa9djl	}
215cb5caa9djl	offset = strlen(buffer);
216cb5caa9djl	safechars = LOGBUFLEN - (offset - 1);
217cb5caa9djl	/*LINTED: E_SEC_PRINTF_VAR_FMT*/
218cb5caa9djl	if (vsnprintf(buffer + offset, safechars, format, ap) >
219cb5caa9djl	    safechars) {
220cb5caa9djl		(void) strncat(buffer, "...\n", LOGBUFLEN);
221cb5caa9djl	}
222cb5caa9djl
223cb5caa9djl	(void) mutex_lock(&loglock);
224cb5caa9djl	(void) write(_logfd, buffer, strlen(buffer));
225cb5caa9djl	logstats.entries_logged++;
226cb5caa9djl	(void) mutex_unlock(&loglock);
227cb5caa9djl
228cb5caa9djl	va_end(ap);
229cb5caa9djl}
230cb5caa9djl
23118bdb8amichen/*
23218bdb8amichen * Map old nscd debug level (0 -10) to log level:
23318bdb8amichen *      -- >= 6: DBG_ALL 		--> NSCD_LOG_LEVEL_ALL
23418bdb8amichen *      -- >= 4: DBG_DBG_NETLOOKUPS 	--> NSCD_LOG_LEVEL_CANT_FIND
23518bdb8amichen *      -- >= 2: DBG_CANT_FIND 		--> NSCD_LOG_LEVEL_CANT_FIND
23618bdb8amichen *      -- >= 0: DBG_OFF 		--> NSCD_LOG_LEVEL_NONE
23718bdb8amichen */
23818bdb8amichenstatic int
23918bdb8amichendebug_to_log_level(
24018bdb8amichen	int	level)
24118bdb8amichen{
24218bdb8amichen	if (level >= 0 && level <= 10) {
24318bdb8amichen		if (level >= DBG_ALL)
24418bdb8amichen			return (NSCD_LOG_LEVEL_ALL);
24518bdb8amichen		else if (level >= DBG_NETLOOKUPS)
24618bdb8amichen			return (NSCD_LOG_LEVEL_CANT_FIND);
24718bdb8amichen		else if (level >= DBG_CANT_FIND)
24818bdb8amichen			return (NSCD_LOG_LEVEL_CANT_FIND);
24918bdb8amichen		else if (level >= DBG_OFF)
25018bdb8amichen			return (NSCD_LOG_LEVEL_NONE);
25118bdb8amichen	}
25218bdb8amichen	return (level);
25318bdb8amichen}
254cb5caa9djl
255cb5caa9djl/* ARGSUSED */
256cb5caa9djlnscd_rc_t
257cb5caa9djl_nscd_cfg_log_notify(
258cb5caa9djl	void				*data,
259cb5caa9djl	struct nscd_cfg_param_desc	*pdesc,
260cb5caa9djl	nscd_cfg_id_t			*nswdb,
261cb5caa9djl	nscd_cfg_flag_t			dflag,
262cb5caa9djl	nscd_cfg_error_t		**errorp,
263cb5caa9djl	void				*cookie)
264cb5caa9djl{
265cb5caa9djl
266cb5caa9djl	nscd_cfg_global_log_t		*logcfg;
267cb5caa9djl	int				off;
268cb5caa9djl
269cb5caa9djl	/*
270cb5caa9djl	 * At init time, the whole group of config params are received.
271cb5caa9djl	 * At update time, group or individual parameter value could
272cb5caa9djl	 * be received.
273cb5caa9djl	 */
274cb5caa9djl
275cb5caa9djl	if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
276cb5caa9djl
277cb5caa9djl		logcfg = (nscd_cfg_global_log_t *)data;
278cb5caa9djl
279cb5caa9djl		_nscd_log_comp = logcfg->debug_comp;
280cb5caa9djl		_nscd_log_level = logcfg->debug_level;
281cb5caa9djl
282cb5caa9djl		/*
283cb5caa9djl		 * logcfg->logfile should have been opened
284cb5caa9djl		 * by _nscd_cfg_log_verify()
285cb5caa9djl		 */
286cb5caa9djl
287cb5caa9djl		return (NSCD_SUCCESS);
288cb5caa9djl	}
289cb5caa9djl
290cb5caa9djl	/*
291cb5caa9djl	 * individual config parameter
292cb5caa9djl	 */
293cb5caa9djl	off = offsetof(nscd_cfg_global_log_t, debug_comp);
294cb5caa9djl	if (pdesc->p_offset == off) {
295cb5caa9djl		_nscd_log_comp = *(nscd_cfg_bitmap_t *)data;
296cb5caa9djl		return (NSCD_SUCCESS);
297cb5caa9djl	}
298cb5caa9djl
299cb5caa9djl	off = offsetof(nscd_cfg_global_log_t, debug_level);
300cb5caa9djl	if (pdesc->p_offset == off)
301cb5caa9djl		_nscd_log_level = *(nscd_cfg_bitmap_t *)data;
302cb5caa9djl
303cb5caa9djl	/*
304cb5caa9djl	 * logcfg->logfile should have been opened
305cb5caa9djl	 * by _nscd_cfg_log_verify()
306cb5caa9djl	 */
307cb5caa9djl
308cb5caa9djl	return (NSCD_SUCCESS);
309cb5caa9djl}
310cb5caa9djl
311cb5caa9djl/* ARGSUSED */
312cb5caa9djlnscd_rc_t
313cb5caa9djl_nscd_cfg_log_verify(
314cb5caa9djl	void				*data,
315cb5caa9djl	struct	nscd_cfg_param_desc	*pdesc,
316cb5caa9djl	nscd_cfg_id_t			*nswdb,
317cb5caa9djl	nscd_cfg_flag_t			dflag,
318cb5caa9djl	nscd_cfg_error_t		**errorp,
319cb5caa9djl	void				**cookie)
320cb5caa9djl{
321cb5caa9djl	nscd_cfg_global_log_t		*logcfg;
322cb5caa9djl	nscd_cfg_bitmap_t		bt;
323cb5caa9djl	int				off;
324cb5caa9djl
325cb5caa9djl	/*
326cb5caa9djl	 * There is no switch db specific config params
327cb5caa9djl	 * for the nscd log component. It is a bug if
328cb5caa9djl	 * the input param description is global.
329cb5caa9djl	 */
330cb5caa9djl	if (_nscd_cfg_flag_is_not_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL))
331cb5caa9djl		return (NSCD_CFG_PARAM_DESC_ERROR);
332cb5caa9djl
333cb5caa9djl	/*
334cb5caa9djl	 * At init time, the whole group of config params are received.
335cb5caa9djl	 * At update time, group or individual parameter value could
336cb5caa9djl	 * be received.
337cb5caa9djl	 */
338cb5caa9djl
339cb5caa9djl	if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
340cb5caa9djl
341cb5caa9djl		logcfg = (nscd_cfg_global_log_t *)data;
342cb5caa9djl
343cb5caa9djl		if (_nscd_cfg_bitmap_valid(logcfg->debug_comp,
34418bdb8amichen		    NSCD_LOG_ALL) == 0)
345cb5caa9djl			return (NSCD_CFG_SYNTAX_ERROR);
346cb5caa9djl
347cb5caa9djl		if (_nscd_cfg_bitmap_valid(logcfg->debug_level,
34818bdb8amichen		    NSCD_LOG_LEVEL_ALL) == 0)
349cb5caa9djl			return (NSCD_CFG_SYNTAX_ERROR);
350cb5caa9djl
351cb5caa9djl		if (logcfg->logfile != NULL)
352cb5caa9djl			return (_nscd_set_lf(logcfg->logfile));
353cb5caa9djl
354cb5caa9djl		return (NSCD_SUCCESS);
355cb5caa9djl	}
356cb5caa9djl
357cb5caa9djl	/*
358cb5caa9djl	 * individual config parameter
359cb5caa9djl	 */
360cb5caa9djl
361cb5caa9djl	off = offsetof(nscd_cfg_global_log_t, debug_comp);
362cb5caa9djl	if (pdesc->p_offset == off) {
363cb5caa9djl
364cb5caa9djl		bt = *(nscd_cfg_bitmap_t *)data;
365cb5caa9djl		if (_nscd_cfg_bitmap_valid(bt, NSCD_LOG_ALL) == 0)
366cb5caa9djl			return (NSCD_CFG_SYNTAX_ERROR);
367cb5caa9djl
368cb5caa9djl		return (NSCD_SUCCESS);
369cb5caa9djl	}
370cb5caa9djl
371cb5caa9djl	off = offsetof(nscd_cfg_global_log_t, debug_level);
372cb5caa9djl	if (pdesc->p_offset == off) {
373cb5caa9djl
374cb5caa9djl		bt = *(nscd_cfg_bitmap_t *)data;
375cb5caa9djl		if (_nscd_cfg_bitmap_valid(bt, NSCD_LOG_LEVEL_ALL) == 0)
376cb5caa9djl			return (NSCD_CFG_SYNTAX_ERROR);
377cb5caa9djl
378cb5caa9djl		return (NSCD_SUCCESS);
379cb5caa9djl	}
380cb5caa9djl
381cb5caa9djl	off = offsetof(nscd_cfg_global_log_t, logfile);
382cb5caa9djl	if (pdesc->p_offset == off) {
383cb5caa9djl		if (data != NULL)
384cb5caa9djl			return (_nscd_set_lf((char *)data));
385cb5caa9djl		else
386cb5caa9djl			return (NSCD_SUCCESS);
387cb5caa9djl	}
388cb5caa9djl
389cb5caa9djl	return (NSCD_CFG_PARAM_DESC_ERROR);
390cb5caa9djl}
391cb5caa9djl
392cb5caa9djl/* ARGSUSED */
393cb5caa9djlnscd_rc_t
394cb5caa9djl_nscd_cfg_log_get_stat(
395cb5caa9djl	void				**stat,
396cb5caa9djl	struct nscd_cfg_stat_desc	*sdesc,
397cb5caa9djl	nscd_cfg_id_t			*nswdb,
398cb5caa9djl	nscd_cfg_flag_t			*dflag,
399cb5caa9djl	void				(**free_stat)(void *stat),
400cb5caa9djl	nscd_cfg_error_t		**errorp)
401cb5caa9djl{
402cb5caa9djl
403cb5caa9djl	*(nscd_cfg_stat_global_log_t **)stat = &logstats;
404cb5caa9djl
405cb5caa9djl	/* indicate the statistics are static, i.e., do not free */
406cb5caa9djl	*dflag = _nscd_cfg_flag_set(*dflag, NSCD_CFG_DFLAG_STATIC_DATA);
407cb5caa9djl
408cb5caa9djl	return (NSCD_SUCCESS);
409cb5caa9djl}
410cb5caa9djl
411cb5caa9djl/*
412cb5caa9djl * set the name of the current log file and make it current.
413cb5caa9djl */
414cb5caa9djlnscd_rc_t
415cb5caa9djl_nscd_set_log_file(
416cb5caa9djl	char			*name)
417cb5caa9djl{
418cb5caa9djl	nscd_rc_t		rc;
419cb5caa9djl	nscd_cfg_handle_t	*h;
420cb5caa9djl
421cb5caa9djl	rc = _nscd_cfg_get_handle("logfile", NULL, &h, NULL);
422cb5caa9djl	if (rc != NSCD_SUCCESS)
423cb5caa9djl		return (rc);
424cb5caa9djl
425cb5caa9djl	rc = _nscd_cfg_set(h, name, NULL);
426cb5caa9djl	_nscd_cfg_free_handle(h);
427cb5caa9djl	if (rc != NSCD_SUCCESS)
428cb5caa9djl		exit(rc);
429cb5caa9djl
430cb5caa9djl	return (NSCD_SUCCESS);
431cb5caa9djl}
432cb5caa9djl
43318bdb8amichen/* Set debug level to the new one and make it current */
434cb5caa9djlnscd_rc_t
435cb5caa9djl_nscd_set_debug_level(
436cb5caa9djl	int			level)
437cb5caa9djl{
438cb5caa9djl	nscd_rc_t		rc;
439cb5caa9djl	nscd_cfg_handle_t	*h;
44018bdb8amichen	int			l = 0;
44118bdb8amichen	int			c = -1;
442cb5caa9djl
44318bdb8amichen	/* old nscd debug level is 1 to 10, map it to log_level and log_comp */
44418bdb8amichen	if (level >= 0 && level <= 10) {
44518bdb8amichen		l = debug_to_log_level(level);
44618bdb8amichen		c = NSCD_LOG_CACHE;
44718bdb8amichen	} else
44818bdb8amichen		l = level;
449cb5caa9djl
450cb5caa9djl	if (level < 0)
45118bdb8amichen		c = -1 * level / 1000000;
45218bdb8amichen
45318bdb8amichen	if (c != -1) {
45418bdb8amichen		rc = _nscd_cfg_get_handle("debug-components", NULL, &h, NULL);
45518bdb8amichen		if (rc != NSCD_SUCCESS)
45618bdb8amichen			return (rc);
45718bdb8amichen
45818bdb8amichen		rc = _nscd_cfg_set(h, &c, NULL);
45918bdb8amichen		_nscd_cfg_free_handle(h);
46018bdb8amichen		if (rc != NSCD_SUCCESS)
46118bdb8amichen			exit(rc);
46218bdb8amichen	}
463cb5caa9djl
464cb5caa9djl	rc = _nscd_cfg_get_handle("debug-level", NULL, &h, NULL);
465cb5caa9djl	if (rc != NSCD_SUCCESS)
466cb5caa9djl		return (rc);
467cb5caa9djl
468cb5caa9djl	if (level < 0)
46918bdb8amichen		l = -1 * level % 1000000;
470cb5caa9djl
471cb5caa9djl	rc = _nscd_cfg_set(h, &l, NULL);
472cb5caa9djl	_nscd_cfg_free_handle(h);
473cb5caa9djl	if (rc != NSCD_SUCCESS)
474cb5caa9djl		exit(rc);
475cb5caa9djl
476cb5caa9djl	return (NSCD_SUCCESS);
477cb5caa9djl}
47818bdb8amichen
47918bdb8amichenvoid
48018bdb8amichen_nscd_get_log_info(
48118bdb8amichen	char	*level,
48218bdb8amichen	int	llen,
48318bdb8amichen	char	*file,
48418bdb8amichen	int	flen)
48518bdb8amichen{
48618bdb8amichen	if (_nscd_log_level != 0)
48718bdb8amichen		(void) snprintf(level, llen, "%d", _nscd_log_level);
48818bdb8amichen	if (*_nscd_logfile != '\0')
48918bdb8amichen		(void) strlcpy(file, _nscd_logfile, flen);
49018bdb8amichen}
491