1cb5caa98Sdjl /*
2cb5caa98Sdjl * CDDL HEADER START
3cb5caa98Sdjl *
4cb5caa98Sdjl * The contents of this file are subject to the terms of the
5cb5caa98Sdjl * Common Development and Distribution License (the "License").
6cb5caa98Sdjl * You may not use this file except in compliance with the License.
7cb5caa98Sdjl *
8cb5caa98Sdjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9cb5caa98Sdjl * or http://www.opensolaris.org/os/licensing.
10cb5caa98Sdjl * See the License for the specific language governing permissions
11cb5caa98Sdjl * and limitations under the License.
12cb5caa98Sdjl *
13cb5caa98Sdjl * When distributing Covered Code, include this CDDL HEADER in each
14cb5caa98Sdjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15cb5caa98Sdjl * If applicable, add the following below this CDDL HEADER, with the
16cb5caa98Sdjl * fields enclosed by brackets "[]" replaced with your own identifying
17cb5caa98Sdjl * information: Portions Copyright [yyyy] [name of copyright owner]
18cb5caa98Sdjl *
19cb5caa98Sdjl * CDDL HEADER END
20cb5caa98Sdjl */
21cb5caa98Sdjl /*
22*18bdb8a7Smichen * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23cb5caa98Sdjl * Use is subject to license terms.
24cb5caa98Sdjl */
25cb5caa98Sdjl
26cb5caa98Sdjl #include <stdlib.h>
27cb5caa98Sdjl #include <locale.h>
28cb5caa98Sdjl #include <limits.h>
29cb5caa98Sdjl #include <fcntl.h>
30cb5caa98Sdjl #include <sys/stat.h>
31cb5caa98Sdjl #include <sys/varargs.h>
32cb5caa98Sdjl #include <synch.h>
33cb5caa98Sdjl #include <thread.h>
34cb5caa98Sdjl #include <string.h>
35cb5caa98Sdjl #include <unistd.h>
36cb5caa98Sdjl #include "nscd_log.h"
37cb5caa98Sdjl #include "nscd_config.h"
38cb5caa98Sdjl #include "nscd_switch.h"
39cb5caa98Sdjl #include "cache.h"
40cb5caa98Sdjl
41cb5caa98Sdjl /*
42cb5caa98Sdjl * old nscd debug levels
43cb5caa98Sdjl */
44cb5caa98Sdjl #define DBG_OFF 0
45cb5caa98Sdjl #define DBG_CANT_FIND 2
46cb5caa98Sdjl #define DBG_NETLOOKUPS 4
47cb5caa98Sdjl #define DBG_ALL 6
48cb5caa98Sdjl
49cb5caa98Sdjl /* max. chars in a nscd log entry */
50cb5caa98Sdjl #define LOGBUFLEN 1024
51cb5caa98Sdjl
52cb5caa98Sdjl /* configuration for the nscd log component */
53*18bdb8a7Smichen int _nscd_log_comp = 0x0;
54*18bdb8a7Smichen int _nscd_log_level = 0x0;
55*18bdb8a7Smichen static char _nscd_logfile[PATH_MAX] = { 0 };
56*18bdb8a7Smichen
57*18bdb8a7Smichen #define NSCD_DEBUG_NONE '0'
58*18bdb8a7Smichen #define NSCD_DEBUG_OPEN '1'
59*18bdb8a7Smichen #define NSCD_DEBUG_CLOSE '2'
60*18bdb8a7Smichen
61*18bdb8a7Smichen static char _nscd_debug = NSCD_DEBUG_NONE;
62*18bdb8a7Smichen static char _nscd_logfile_d[PATH_MAX] = { 0 };
63*18bdb8a7Smichen static char _nscd_logfile_s[PATH_MAX] = { 0 };
64cb5caa98Sdjl
65cb5caa98Sdjl /* statistics data */
66cb5caa98Sdjl static nscd_cfg_stat_global_log_t logstats = {
67cb5caa98Sdjl NSCD_CFG_STAT_GROUP_INFO_GLOBAL_LOG, 0 };
68cb5caa98Sdjl
69cb5caa98Sdjl /* if no log file specified, log entry goes to stderr */
70cb5caa98Sdjl int _logfd = 2;
71cb5caa98Sdjl
72*18bdb8a7Smichen
73cb5caa98Sdjl /* close old log file and open a new one */
74cb5caa98Sdjl static nscd_rc_t
_nscd_set_lf(char * lf)75cb5caa98Sdjl _nscd_set_lf(
76cb5caa98Sdjl char *lf)
77cb5caa98Sdjl {
78cb5caa98Sdjl int newlogfd;
79cb5caa98Sdjl char *me = "_nscd_set_lf";
80cb5caa98Sdjl
81cb5caa98Sdjl /*
82cb5caa98Sdjl * don't try and open the log file /dev/null
83cb5caa98Sdjl */
84cb5caa98Sdjl if (lf == NULL || *lf == 0) {
85cb5caa98Sdjl /* ignore empty log file specs */
86cb5caa98Sdjl return (NSCD_SUCCESS);
87cb5caa98Sdjl } else if (strcmp(lf, "/dev/null") == 0) {
88*18bdb8a7Smichen (void) strlcpy(_nscd_logfile, lf, PATH_MAX);
89cb5caa98Sdjl if (_logfd >= 0)
90cb5caa98Sdjl (void) close(_logfd);
91cb5caa98Sdjl _logfd = -1;
92cb5caa98Sdjl return (NSCD_SUCCESS);
93cb5caa98Sdjl } else if (strcmp(lf, "stderr") == 0) {
94*18bdb8a7Smichen (void) strlcpy(_nscd_logfile, lf, PATH_MAX);
95cb5caa98Sdjl if (_logfd != -1 && _logfd != 2)
96cb5caa98Sdjl (void) close(_logfd);
97cb5caa98Sdjl _logfd = 2;
98cb5caa98Sdjl return (NSCD_SUCCESS);
99cb5caa98Sdjl } else {
100cb5caa98Sdjl
101cb5caa98Sdjl /*
102cb5caa98Sdjl * In order to open this file securely, we'll try a few tricks
103cb5caa98Sdjl */
104cb5caa98Sdjl
105cb5caa98Sdjl if ((newlogfd = open(lf, O_EXCL|O_WRONLY|O_CREAT, 0644)) < 0) {
106cb5caa98Sdjl /*
107cb5caa98Sdjl * File already exists... now we need to get cute
108cb5caa98Sdjl * since opening a file in a world-writeable directory
109cb5caa98Sdjl * safely is hard = it could be a hard link or a
110cb5caa98Sdjl * symbolic link to a system file.
111cb5caa98Sdjl */
112cb5caa98Sdjl struct stat before;
113cb5caa98Sdjl
114cb5caa98Sdjl if (lstat(lf, &before) < 0) {
115*18bdb8a7Smichen if (_nscd_debug == NSCD_DEBUG_NONE)
116*18bdb8a7Smichen _nscd_logit(me, "Cannot open new "
117*18bdb8a7Smichen "logfile \"%s\": %sn",
118*18bdb8a7Smichen lf, strerror(errno));
119cb5caa98Sdjl return (NSCD_CFG_FILE_OPEN_ERROR);
120cb5caa98Sdjl }
121cb5caa98Sdjl
122cb5caa98Sdjl if (S_ISREG(before.st_mode) && /* no symbolic links */
123*18bdb8a7Smichen (before.st_nlink == 1) && /* no hard links */
124*18bdb8a7Smichen (before.st_uid == 0)) { /* owned by root */
125cb5caa98Sdjl if ((newlogfd =
126cb5caa98Sdjl open(lf, O_APPEND|O_WRONLY, 0644)) < 0) {
127*18bdb8a7Smichen if (_nscd_debug == NSCD_DEBUG_NONE)
128*18bdb8a7Smichen _nscd_logit(me,
129*18bdb8a7Smichen "Cannot open new "\
130*18bdb8a7Smichen "logfile \"%s\": %s\n", lf,
131*18bdb8a7Smichen strerror(errno));
132cb5caa98Sdjl return (NSCD_CFG_FILE_OPEN_ERROR);
133cb5caa98Sdjl }
134cb5caa98Sdjl } else {
135*18bdb8a7Smichen if (_nscd_debug == NSCD_DEBUG_NONE)
136*18bdb8a7Smichen _nscd_logit(me, "Cannot use specified "
137*18bdb8a7Smichen "logfile \"%s\": "\
138*18bdb8a7Smichen "file is/has links or isn't "
139*18bdb8a7Smichen "owned by root\n", lf);
140cb5caa98Sdjl return (NSCD_CFG_FILE_OPEN_ERROR);
141cb5caa98Sdjl }
142cb5caa98Sdjl }
143cb5caa98Sdjl
144cb5caa98Sdjl (void) close(_logfd);
145*18bdb8a7Smichen (void) strlcpy(_nscd_logfile, lf, PATH_MAX);
146cb5caa98Sdjl _logfd = newlogfd;
147*18bdb8a7Smichen if (_nscd_debug == NSCD_DEBUG_NONE)
148*18bdb8a7Smichen _nscd_logit(me, "Start of new logfile %s\n", lf);
149cb5caa98Sdjl }
150cb5caa98Sdjl return (NSCD_SUCCESS);
151cb5caa98Sdjl }
152cb5caa98Sdjl
153cb5caa98Sdjl
154cb5caa98Sdjl /* log an entry to the configured nscd log file */
155cb5caa98Sdjl void
_nscd_logit(char * funcname,char * format,...)156cb5caa98Sdjl _nscd_logit(
157cb5caa98Sdjl char *funcname,
158cb5caa98Sdjl char *format,
159cb5caa98Sdjl ...)
160cb5caa98Sdjl {
161cb5caa98Sdjl static mutex_t loglock = DEFAULTMUTEX;
162cb5caa98Sdjl struct timeval tv;
163cb5caa98Sdjl char tid_buf[32];
164cb5caa98Sdjl char pid_buf[32];
165cb5caa98Sdjl char buffer[LOGBUFLEN];
166cb5caa98Sdjl int safechars, offset;
167cb5caa98Sdjl va_list ap;
168cb5caa98Sdjl
169cb5caa98Sdjl if (_logfd < 0)
170cb5caa98Sdjl return;
171cb5caa98Sdjl
172*18bdb8a7Smichen if (_nscd_debug == NSCD_DEBUG_OPEN) {
173*18bdb8a7Smichen (void) mutex_lock(&loglock);
174*18bdb8a7Smichen if (_nscd_debug == NSCD_DEBUG_OPEN &&
175*18bdb8a7Smichen *_nscd_logfile_d != '\0' &&
176*18bdb8a7Smichen (strcmp(_nscd_logfile, "/dev/null") == 0 ||
177*18bdb8a7Smichen strcmp(_nscd_logfile, "stderr") == 0)) {
178*18bdb8a7Smichen (void) strlcpy(_nscd_logfile_s,
179*18bdb8a7Smichen _nscd_logfile, PATH_MAX);
180*18bdb8a7Smichen (void) _nscd_set_lf(_nscd_logfile_d);
181*18bdb8a7Smichen }
182*18bdb8a7Smichen _nscd_debug = NSCD_DEBUG_NONE;
183*18bdb8a7Smichen (void) mutex_unlock(&loglock);
184*18bdb8a7Smichen } else if (_nscd_debug == NSCD_DEBUG_CLOSE) {
185*18bdb8a7Smichen (void) mutex_lock(&loglock);
186*18bdb8a7Smichen if (_nscd_debug == NSCD_DEBUG_CLOSE)
187*18bdb8a7Smichen (void) _nscd_set_lf(_nscd_logfile_s);
188*18bdb8a7Smichen _nscd_debug = NSCD_DEBUG_NONE;
189*18bdb8a7Smichen (void) mutex_unlock(&loglock);
190*18bdb8a7Smichen }
191*18bdb8a7Smichen
192cb5caa98Sdjl va_start(ap, format);
193cb5caa98Sdjl
194cb5caa98Sdjl if (gettimeofday(&tv, NULL) != 0 ||
195cb5caa98Sdjl ctime_r(&tv.tv_sec, buffer, LOGBUFLEN) == NULL) {
196cb5caa98Sdjl (void) snprintf(buffer, LOGBUFLEN,
197cb5caa98Sdjl "<time conversion failed>\t");
198cb5caa98Sdjl } else {
199cb5caa98Sdjl (void) sprintf(tid_buf, "--%d", thr_self());
200cb5caa98Sdjl (void) sprintf(pid_buf, "--%ld", getpid());
201cb5caa98Sdjl /*
202cb5caa98Sdjl * ctime_r() includes some stuff we don't want;
203cb5caa98Sdjl * adjust length to overwrite " YYYY\n" and
204cb5caa98Sdjl * include tid string length.
205cb5caa98Sdjl */
206cb5caa98Sdjl offset = strlen(buffer) - 6;
207cb5caa98Sdjl safechars = LOGBUFLEN - (offset - 1);
208cb5caa98Sdjl (void) snprintf(buffer + offset,
209*18bdb8a7Smichen safechars, ".%.4ld%s%s\t%s:\n\t\t",
210*18bdb8a7Smichen tv.tv_usec/100, tid_buf, pid_buf,
211*18bdb8a7Smichen funcname);
212cb5caa98Sdjl }
213cb5caa98Sdjl offset = strlen(buffer);
214cb5caa98Sdjl safechars = LOGBUFLEN - (offset - 1);
215cb5caa98Sdjl /*LINTED: E_SEC_PRINTF_VAR_FMT*/
216cb5caa98Sdjl if (vsnprintf(buffer + offset, safechars, format, ap) >
217cb5caa98Sdjl safechars) {
218cb5caa98Sdjl (void) strncat(buffer, "...\n", LOGBUFLEN);
219cb5caa98Sdjl }
220cb5caa98Sdjl
221cb5caa98Sdjl (void) mutex_lock(&loglock);
222cb5caa98Sdjl (void) write(_logfd, buffer, strlen(buffer));
223cb5caa98Sdjl logstats.entries_logged++;
224cb5caa98Sdjl (void) mutex_unlock(&loglock);
225cb5caa98Sdjl
226cb5caa98Sdjl va_end(ap);
227cb5caa98Sdjl }
228cb5caa98Sdjl
229*18bdb8a7Smichen /*
230*18bdb8a7Smichen * Map old nscd debug level (0 -10) to log level:
231*18bdb8a7Smichen * -- >= 6: DBG_ALL --> NSCD_LOG_LEVEL_ALL
232*18bdb8a7Smichen * -- >= 4: DBG_DBG_NETLOOKUPS --> NSCD_LOG_LEVEL_CANT_FIND
233*18bdb8a7Smichen * -- >= 2: DBG_CANT_FIND --> NSCD_LOG_LEVEL_CANT_FIND
234*18bdb8a7Smichen * -- >= 0: DBG_OFF --> NSCD_LOG_LEVEL_NONE
235*18bdb8a7Smichen */
236*18bdb8a7Smichen static int
debug_to_log_level(int level)237*18bdb8a7Smichen debug_to_log_level(
238*18bdb8a7Smichen int level)
239*18bdb8a7Smichen {
240*18bdb8a7Smichen if (level >= 0 && level <= 10) {
241*18bdb8a7Smichen if (level >= DBG_ALL)
242*18bdb8a7Smichen return (NSCD_LOG_LEVEL_ALL);
243*18bdb8a7Smichen else if (level >= DBG_NETLOOKUPS)
244*18bdb8a7Smichen return (NSCD_LOG_LEVEL_CANT_FIND);
245*18bdb8a7Smichen else if (level >= DBG_CANT_FIND)
246*18bdb8a7Smichen return (NSCD_LOG_LEVEL_CANT_FIND);
247*18bdb8a7Smichen else if (level >= DBG_OFF)
248*18bdb8a7Smichen return (NSCD_LOG_LEVEL_NONE);
249*18bdb8a7Smichen }
250*18bdb8a7Smichen return (level);
251*18bdb8a7Smichen }
252cb5caa98Sdjl
253cb5caa98Sdjl /* ARGSUSED */
254cb5caa98Sdjl nscd_rc_t
_nscd_cfg_log_notify(void * data,struct nscd_cfg_param_desc * pdesc,nscd_cfg_id_t * nswdb,nscd_cfg_flag_t dflag,nscd_cfg_error_t ** errorp,void * cookie)255cb5caa98Sdjl _nscd_cfg_log_notify(
256cb5caa98Sdjl void *data,
257cb5caa98Sdjl struct nscd_cfg_param_desc *pdesc,
258cb5caa98Sdjl nscd_cfg_id_t *nswdb,
259cb5caa98Sdjl nscd_cfg_flag_t dflag,
260cb5caa98Sdjl nscd_cfg_error_t **errorp,
261cb5caa98Sdjl void *cookie)
262cb5caa98Sdjl {
263cb5caa98Sdjl
264cb5caa98Sdjl nscd_cfg_global_log_t *logcfg;
265cb5caa98Sdjl int off;
266cb5caa98Sdjl
267cb5caa98Sdjl /*
268cb5caa98Sdjl * At init time, the whole group of config params are received.
269cb5caa98Sdjl * At update time, group or individual parameter value could
270cb5caa98Sdjl * be received.
271cb5caa98Sdjl */
272cb5caa98Sdjl
273cb5caa98Sdjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
274cb5caa98Sdjl
275cb5caa98Sdjl logcfg = (nscd_cfg_global_log_t *)data;
276cb5caa98Sdjl
277cb5caa98Sdjl _nscd_log_comp = logcfg->debug_comp;
278cb5caa98Sdjl _nscd_log_level = logcfg->debug_level;
279cb5caa98Sdjl
280cb5caa98Sdjl /*
281cb5caa98Sdjl * logcfg->logfile should have been opened
282cb5caa98Sdjl * by _nscd_cfg_log_verify()
283cb5caa98Sdjl */
284cb5caa98Sdjl
285cb5caa98Sdjl return (NSCD_SUCCESS);
286cb5caa98Sdjl }
287cb5caa98Sdjl
288cb5caa98Sdjl /*
289cb5caa98Sdjl * individual config parameter
290cb5caa98Sdjl */
291cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, debug_comp);
292cb5caa98Sdjl if (pdesc->p_offset == off) {
293cb5caa98Sdjl _nscd_log_comp = *(nscd_cfg_bitmap_t *)data;
294cb5caa98Sdjl return (NSCD_SUCCESS);
295cb5caa98Sdjl }
296cb5caa98Sdjl
297cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, debug_level);
298cb5caa98Sdjl if (pdesc->p_offset == off)
299cb5caa98Sdjl _nscd_log_level = *(nscd_cfg_bitmap_t *)data;
300cb5caa98Sdjl
301cb5caa98Sdjl /*
302cb5caa98Sdjl * logcfg->logfile should have been opened
303cb5caa98Sdjl * by _nscd_cfg_log_verify()
304cb5caa98Sdjl */
305cb5caa98Sdjl
306cb5caa98Sdjl return (NSCD_SUCCESS);
307cb5caa98Sdjl }
308cb5caa98Sdjl
309cb5caa98Sdjl /* ARGSUSED */
310cb5caa98Sdjl nscd_rc_t
_nscd_cfg_log_verify(void * data,struct nscd_cfg_param_desc * pdesc,nscd_cfg_id_t * nswdb,nscd_cfg_flag_t dflag,nscd_cfg_error_t ** errorp,void ** cookie)311cb5caa98Sdjl _nscd_cfg_log_verify(
312cb5caa98Sdjl void *data,
313cb5caa98Sdjl struct nscd_cfg_param_desc *pdesc,
314cb5caa98Sdjl nscd_cfg_id_t *nswdb,
315cb5caa98Sdjl nscd_cfg_flag_t dflag,
316cb5caa98Sdjl nscd_cfg_error_t **errorp,
317cb5caa98Sdjl void **cookie)
318cb5caa98Sdjl {
319cb5caa98Sdjl nscd_cfg_global_log_t *logcfg;
320cb5caa98Sdjl nscd_cfg_bitmap_t bt;
321cb5caa98Sdjl int off;
322cb5caa98Sdjl
323cb5caa98Sdjl /*
324cb5caa98Sdjl * There is no switch db specific config params
325cb5caa98Sdjl * for the nscd log component. It is a bug if
326cb5caa98Sdjl * the input param description is global.
327cb5caa98Sdjl */
328cb5caa98Sdjl if (_nscd_cfg_flag_is_not_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL))
329cb5caa98Sdjl return (NSCD_CFG_PARAM_DESC_ERROR);
330cb5caa98Sdjl
331cb5caa98Sdjl /*
332cb5caa98Sdjl * At init time, the whole group of config params are received.
333cb5caa98Sdjl * At update time, group or individual parameter value could
334cb5caa98Sdjl * be received.
335cb5caa98Sdjl */
336cb5caa98Sdjl
337cb5caa98Sdjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
338cb5caa98Sdjl
339cb5caa98Sdjl logcfg = (nscd_cfg_global_log_t *)data;
340cb5caa98Sdjl
341cb5caa98Sdjl if (_nscd_cfg_bitmap_valid(logcfg->debug_comp,
342*18bdb8a7Smichen NSCD_LOG_ALL) == 0)
343cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR);
344cb5caa98Sdjl
345cb5caa98Sdjl if (_nscd_cfg_bitmap_valid(logcfg->debug_level,
346*18bdb8a7Smichen NSCD_LOG_LEVEL_ALL) == 0)
347cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR);
348cb5caa98Sdjl
349cb5caa98Sdjl if (logcfg->logfile != NULL)
350cb5caa98Sdjl return (_nscd_set_lf(logcfg->logfile));
351cb5caa98Sdjl
352cb5caa98Sdjl return (NSCD_SUCCESS);
353cb5caa98Sdjl }
354cb5caa98Sdjl
355cb5caa98Sdjl /*
356cb5caa98Sdjl * individual config parameter
357cb5caa98Sdjl */
358cb5caa98Sdjl
359cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, debug_comp);
360cb5caa98Sdjl if (pdesc->p_offset == off) {
361cb5caa98Sdjl
362cb5caa98Sdjl bt = *(nscd_cfg_bitmap_t *)data;
363cb5caa98Sdjl if (_nscd_cfg_bitmap_valid(bt, NSCD_LOG_ALL) == 0)
364cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR);
365cb5caa98Sdjl
366cb5caa98Sdjl return (NSCD_SUCCESS);
367cb5caa98Sdjl }
368cb5caa98Sdjl
369cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, debug_level);
370cb5caa98Sdjl if (pdesc->p_offset == off) {
371cb5caa98Sdjl
372cb5caa98Sdjl bt = *(nscd_cfg_bitmap_t *)data;
373cb5caa98Sdjl if (_nscd_cfg_bitmap_valid(bt, NSCD_LOG_LEVEL_ALL) == 0)
374cb5caa98Sdjl return (NSCD_CFG_SYNTAX_ERROR);
375cb5caa98Sdjl
376cb5caa98Sdjl return (NSCD_SUCCESS);
377cb5caa98Sdjl }
378cb5caa98Sdjl
379cb5caa98Sdjl off = offsetof(nscd_cfg_global_log_t, logfile);
380cb5caa98Sdjl if (pdesc->p_offset == off) {
381cb5caa98Sdjl if (data != NULL)
382cb5caa98Sdjl return (_nscd_set_lf((char *)data));
383cb5caa98Sdjl else
384cb5caa98Sdjl return (NSCD_SUCCESS);
385cb5caa98Sdjl }
386cb5caa98Sdjl
387cb5caa98Sdjl return (NSCD_CFG_PARAM_DESC_ERROR);
388cb5caa98Sdjl }
389cb5caa98Sdjl
390cb5caa98Sdjl /* ARGSUSED */
391cb5caa98Sdjl nscd_rc_t
_nscd_cfg_log_get_stat(void ** stat,struct nscd_cfg_stat_desc * sdesc,nscd_cfg_id_t * nswdb,nscd_cfg_flag_t * dflag,void (** free_stat)(void * stat),nscd_cfg_error_t ** errorp)392cb5caa98Sdjl _nscd_cfg_log_get_stat(
393cb5caa98Sdjl void **stat,
394cb5caa98Sdjl struct nscd_cfg_stat_desc *sdesc,
395cb5caa98Sdjl nscd_cfg_id_t *nswdb,
396cb5caa98Sdjl nscd_cfg_flag_t *dflag,
397cb5caa98Sdjl void (**free_stat)(void *stat),
398cb5caa98Sdjl nscd_cfg_error_t **errorp)
399cb5caa98Sdjl {
400cb5caa98Sdjl
401cb5caa98Sdjl *(nscd_cfg_stat_global_log_t **)stat = &logstats;
402cb5caa98Sdjl
403cb5caa98Sdjl /* indicate the statistics are static, i.e., do not free */
404cb5caa98Sdjl *dflag = _nscd_cfg_flag_set(*dflag, NSCD_CFG_DFLAG_STATIC_DATA);
405cb5caa98Sdjl
406cb5caa98Sdjl return (NSCD_SUCCESS);
407cb5caa98Sdjl }
408cb5caa98Sdjl
409cb5caa98Sdjl /*
410cb5caa98Sdjl * set the name of the current log file and make it current.
411cb5caa98Sdjl */
412cb5caa98Sdjl nscd_rc_t
_nscd_set_log_file(char * name)413cb5caa98Sdjl _nscd_set_log_file(
414cb5caa98Sdjl char *name)
415cb5caa98Sdjl {
416cb5caa98Sdjl nscd_rc_t rc;
417cb5caa98Sdjl nscd_cfg_handle_t *h;
418cb5caa98Sdjl
419cb5caa98Sdjl rc = _nscd_cfg_get_handle("logfile", NULL, &h, NULL);
420cb5caa98Sdjl if (rc != NSCD_SUCCESS)
421cb5caa98Sdjl return (rc);
422cb5caa98Sdjl
423cb5caa98Sdjl rc = _nscd_cfg_set(h, name, NULL);
424cb5caa98Sdjl _nscd_cfg_free_handle(h);
425cb5caa98Sdjl if (rc != NSCD_SUCCESS)
426cb5caa98Sdjl exit(rc);
427cb5caa98Sdjl
428cb5caa98Sdjl return (NSCD_SUCCESS);
429cb5caa98Sdjl }
430cb5caa98Sdjl
431*18bdb8a7Smichen /* Set debug level to the new one and make it current */
432cb5caa98Sdjl nscd_rc_t
_nscd_set_debug_level(int level)433cb5caa98Sdjl _nscd_set_debug_level(
434cb5caa98Sdjl int level)
435cb5caa98Sdjl {
436cb5caa98Sdjl nscd_rc_t rc;
437cb5caa98Sdjl nscd_cfg_handle_t *h;
438*18bdb8a7Smichen int l = 0;
439*18bdb8a7Smichen int c = -1;
440cb5caa98Sdjl
441*18bdb8a7Smichen /* old nscd debug level is 1 to 10, map it to log_level and log_comp */
442*18bdb8a7Smichen if (level >= 0 && level <= 10) {
443*18bdb8a7Smichen l = debug_to_log_level(level);
444*18bdb8a7Smichen c = NSCD_LOG_CACHE;
445*18bdb8a7Smichen } else
446*18bdb8a7Smichen l = level;
447cb5caa98Sdjl
448cb5caa98Sdjl if (level < 0)
449*18bdb8a7Smichen c = -1 * level / 1000000;
450*18bdb8a7Smichen
451*18bdb8a7Smichen if (c != -1) {
452*18bdb8a7Smichen rc = _nscd_cfg_get_handle("debug-components", NULL, &h, NULL);
453*18bdb8a7Smichen if (rc != NSCD_SUCCESS)
454*18bdb8a7Smichen return (rc);
455*18bdb8a7Smichen
456*18bdb8a7Smichen rc = _nscd_cfg_set(h, &c, NULL);
457*18bdb8a7Smichen _nscd_cfg_free_handle(h);
458*18bdb8a7Smichen if (rc != NSCD_SUCCESS)
459*18bdb8a7Smichen exit(rc);
460*18bdb8a7Smichen }
461cb5caa98Sdjl
462cb5caa98Sdjl rc = _nscd_cfg_get_handle("debug-level", NULL, &h, NULL);
463cb5caa98Sdjl if (rc != NSCD_SUCCESS)
464cb5caa98Sdjl return (rc);
465cb5caa98Sdjl
466cb5caa98Sdjl if (level < 0)
467*18bdb8a7Smichen l = -1 * level % 1000000;
468cb5caa98Sdjl
469cb5caa98Sdjl rc = _nscd_cfg_set(h, &l, NULL);
470cb5caa98Sdjl _nscd_cfg_free_handle(h);
471cb5caa98Sdjl if (rc != NSCD_SUCCESS)
472cb5caa98Sdjl exit(rc);
473cb5caa98Sdjl
474cb5caa98Sdjl return (NSCD_SUCCESS);
475cb5caa98Sdjl }
476*18bdb8a7Smichen
477*18bdb8a7Smichen void
_nscd_get_log_info(char * level,int llen,char * file,int flen)478*18bdb8a7Smichen _nscd_get_log_info(
479*18bdb8a7Smichen char *level,
480*18bdb8a7Smichen int llen,
481*18bdb8a7Smichen char *file,
482*18bdb8a7Smichen int flen)
483*18bdb8a7Smichen {
484*18bdb8a7Smichen if (_nscd_log_level != 0)
485*18bdb8a7Smichen (void) snprintf(level, llen, "%d", _nscd_log_level);
486*18bdb8a7Smichen if (*_nscd_logfile != '\0')
487*18bdb8a7Smichen (void) strlcpy(file, _nscd_logfile, flen);
488*18bdb8a7Smichen }
489