xref: /illumos-gate/usr/src/cmd/sendmail/libsm/debug.c (revision e9af4bc0)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright (c) 2000, 2001, 2003, 2004 Sendmail, Inc. and its suppliers.
37c478bd9Sstevel@tonic-gate  *	All rights reserved.
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
67c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
77c478bd9Sstevel@tonic-gate  * the sendmail distribution.
87c478bd9Sstevel@tonic-gate  */
97c478bd9Sstevel@tonic-gate 
107c478bd9Sstevel@tonic-gate #include <sm/gen.h>
11*e9af4bc0SJohn Beck SM_RCSID("@(#)$Id: debug.c,v 1.32 2009/09/20 05:38:46 ca Exp $")
127c478bd9Sstevel@tonic-gate 
137c478bd9Sstevel@tonic-gate /*
147c478bd9Sstevel@tonic-gate **  libsm debugging and tracing
157c478bd9Sstevel@tonic-gate **  For documentation, see debug.html.
167c478bd9Sstevel@tonic-gate */
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate #include <ctype.h>
197c478bd9Sstevel@tonic-gate #include <stdlib.h>
20*e9af4bc0SJohn Beck #if _FFR_DEBUG_PID_TIME
21*e9af4bc0SJohn Beck #include <unistd.h>
22*e9af4bc0SJohn Beck #include <time.h>
23*e9af4bc0SJohn Beck #endif /* _FFR_DEBUG_PID_TIME */
247c478bd9Sstevel@tonic-gate #include <setjmp.h>
257c478bd9Sstevel@tonic-gate #include <sm/io.h>
267c478bd9Sstevel@tonic-gate #include <sm/assert.h>
277c478bd9Sstevel@tonic-gate #include <sm/conf.h>
287c478bd9Sstevel@tonic-gate #include <sm/debug.h>
297c478bd9Sstevel@tonic-gate #include <sm/string.h>
307c478bd9Sstevel@tonic-gate #include <sm/varargs.h>
317c478bd9Sstevel@tonic-gate #include <sm/heap.h>
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate static void		 sm_debug_reset __P((void));
347c478bd9Sstevel@tonic-gate static const char	*parse_named_setting_x __P((const char *));
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate **  Abstractions for printing trace messages.
387c478bd9Sstevel@tonic-gate */
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate **  The output file to which trace output is directed.
427c478bd9Sstevel@tonic-gate **  There is a controversy over whether this variable
437c478bd9Sstevel@tonic-gate **  should be process global or thread local.
447c478bd9Sstevel@tonic-gate **  To make the interface more abstract, we've hidden the
457c478bd9Sstevel@tonic-gate **  variable behind access functions.
467c478bd9Sstevel@tonic-gate */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate static SM_FILE_T *SmDebugOutput = smioout;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate /*
517c478bd9Sstevel@tonic-gate **  SM_DEBUG_FILE -- Returns current debug file pointer.
527c478bd9Sstevel@tonic-gate **
537c478bd9Sstevel@tonic-gate **	Parameters:
547c478bd9Sstevel@tonic-gate **		none.
557c478bd9Sstevel@tonic-gate **
567c478bd9Sstevel@tonic-gate **	Returns:
577c478bd9Sstevel@tonic-gate **		current debug file pointer.
587c478bd9Sstevel@tonic-gate */
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate SM_FILE_T *
sm_debug_file()617c478bd9Sstevel@tonic-gate sm_debug_file()
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate 	return SmDebugOutput;
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /*
677c478bd9Sstevel@tonic-gate **  SM_DEBUG_SETFILE -- Sets debug file pointer.
687c478bd9Sstevel@tonic-gate **
697c478bd9Sstevel@tonic-gate **	Parameters:
707c478bd9Sstevel@tonic-gate **		fp -- new debug file pointer.
717c478bd9Sstevel@tonic-gate **
727c478bd9Sstevel@tonic-gate **	Returns:
737c478bd9Sstevel@tonic-gate **		none.
747c478bd9Sstevel@tonic-gate **
757c478bd9Sstevel@tonic-gate **	Side Effects:
767c478bd9Sstevel@tonic-gate **		Sets SmDebugOutput.
777c478bd9Sstevel@tonic-gate */
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate void
sm_debug_setfile(fp)807c478bd9Sstevel@tonic-gate sm_debug_setfile(fp)
817c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate 	SmDebugOutput = fp;
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate /*
877c478bd9Sstevel@tonic-gate **  SM_DEBUG_CLOSE -- Close debug file pointer.
887c478bd9Sstevel@tonic-gate **
897c478bd9Sstevel@tonic-gate **	Parameters:
907c478bd9Sstevel@tonic-gate **		none.
917c478bd9Sstevel@tonic-gate **
927c478bd9Sstevel@tonic-gate **	Returns:
937c478bd9Sstevel@tonic-gate **		none.
947c478bd9Sstevel@tonic-gate **
957c478bd9Sstevel@tonic-gate **	Side Effects:
967c478bd9Sstevel@tonic-gate **		Closes SmDebugOutput.
977c478bd9Sstevel@tonic-gate */
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate void
sm_debug_close()1007c478bd9Sstevel@tonic-gate sm_debug_close()
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate 	if (SmDebugOutput != NULL && SmDebugOutput != smioout)
1037c478bd9Sstevel@tonic-gate 	{
1047c478bd9Sstevel@tonic-gate 		sm_io_close(SmDebugOutput, SM_TIME_DEFAULT);
1057c478bd9Sstevel@tonic-gate 		SmDebugOutput = NULL;
1067c478bd9Sstevel@tonic-gate 	}
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /*
1107c478bd9Sstevel@tonic-gate **  SM_DPRINTF -- printf() for debug output.
1117c478bd9Sstevel@tonic-gate **
1127c478bd9Sstevel@tonic-gate **	Parameters:
1137c478bd9Sstevel@tonic-gate **		fmt -- format for printf()
1147c478bd9Sstevel@tonic-gate **
1157c478bd9Sstevel@tonic-gate **	Returns:
1167c478bd9Sstevel@tonic-gate **		none.
1177c478bd9Sstevel@tonic-gate */
1187c478bd9Sstevel@tonic-gate 
119*e9af4bc0SJohn Beck #if _FFR_DEBUG_PID_TIME
120*e9af4bc0SJohn Beck SM_DEBUG_T SmDBGPidTime = SM_DEBUG_INITIALIZER("sm_trace_pid_time",
121*e9af4bc0SJohn Beck 	"@(#)$Debug: sm_trace_pid_time - print pid and time in debug $");
122*e9af4bc0SJohn Beck #endif /* _FFR_DEBUG_PID_TIME */
123*e9af4bc0SJohn Beck 
1247c478bd9Sstevel@tonic-gate void
1257c478bd9Sstevel@tonic-gate #if SM_VA_STD
sm_dprintf(char * fmt,...)1267c478bd9Sstevel@tonic-gate sm_dprintf(char *fmt, ...)
1277c478bd9Sstevel@tonic-gate #else /* SM_VA_STD */
1287c478bd9Sstevel@tonic-gate sm_dprintf(fmt, va_alist)
1297c478bd9Sstevel@tonic-gate 	char *fmt;
1307c478bd9Sstevel@tonic-gate 	va_dcl
1317c478bd9Sstevel@tonic-gate #endif /* SM_VA_STD */
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate 	SM_VA_LOCAL_DECL
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	if (SmDebugOutput == NULL)
1367c478bd9Sstevel@tonic-gate 		return;
137*e9af4bc0SJohn Beck #if _FFR_DEBUG_PID_TIME
138*e9af4bc0SJohn Beck 	/* note: this is ugly if the output isn't a full line! */
139*e9af4bc0SJohn Beck 	if (sm_debug_active(&SmDBGPidTime, 1))
140*e9af4bc0SJohn Beck 	{
141*e9af4bc0SJohn Beck 		static char str[32] = "[1900-00-00/00:00:00] ";
142*e9af4bc0SJohn Beck 		struct tm *tmp;
143*e9af4bc0SJohn Beck 		time_t currt;
144*e9af4bc0SJohn Beck 
145*e9af4bc0SJohn Beck 		currt = time((time_t *)0);
146*e9af4bc0SJohn Beck 		tmp = localtime(&currt);
147*e9af4bc0SJohn Beck 		snprintf(str, sizeof(str), "[%d-%02d-%02d/%02d:%02d:%02d] ",
148*e9af4bc0SJohn Beck 			1900 + tmp->tm_year,	/* HACK */
149*e9af4bc0SJohn Beck 			tmp->tm_mon + 1,
150*e9af4bc0SJohn Beck 			tmp->tm_mday,
151*e9af4bc0SJohn Beck 			tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
152*e9af4bc0SJohn Beck 		sm_io_fprintf(SmDebugOutput, SmDebugOutput->f_timeout,
153*e9af4bc0SJohn Beck 			"%ld: %s ", (long) getpid(), str);
154*e9af4bc0SJohn Beck 	}
155*e9af4bc0SJohn Beck #endif /* _FFR_DEBUG_PID_TIME */
156*e9af4bc0SJohn Beck 
1577c478bd9Sstevel@tonic-gate 	SM_VA_START(ap, fmt);
1587c478bd9Sstevel@tonic-gate 	sm_io_vfprintf(SmDebugOutput, SmDebugOutput->f_timeout, fmt, ap);
1597c478bd9Sstevel@tonic-gate 	SM_VA_END(ap);
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate /*
1637c478bd9Sstevel@tonic-gate **  SM_DFLUSH -- Flush debug output.
1647c478bd9Sstevel@tonic-gate **
1657c478bd9Sstevel@tonic-gate **	Parameters:
1667c478bd9Sstevel@tonic-gate **		none.
1677c478bd9Sstevel@tonic-gate **
1687c478bd9Sstevel@tonic-gate **	Returns:
1697c478bd9Sstevel@tonic-gate **		none.
1707c478bd9Sstevel@tonic-gate */
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate void
sm_dflush()1737c478bd9Sstevel@tonic-gate sm_dflush()
1747c478bd9Sstevel@tonic-gate {
1757c478bd9Sstevel@tonic-gate 	sm_io_flush(SmDebugOutput, SM_TIME_DEFAULT);
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate /*
1797c478bd9Sstevel@tonic-gate **  This is the internal database of debug settings.
1807c478bd9Sstevel@tonic-gate **  The semantics of looking up a setting in the settings database
1817c478bd9Sstevel@tonic-gate **  are that the *last* setting specified in a -d option on the sendmail
1827c478bd9Sstevel@tonic-gate **  command line that matches a given SM_DEBUG structure is the one that is
1837c478bd9Sstevel@tonic-gate **  used.  That is necessary to conform to the existing semantics of
1847c478bd9Sstevel@tonic-gate **  the sendmail -d option.  We store the settings as a linked list in
1857c478bd9Sstevel@tonic-gate **  reverse order, so when we do a lookup, we take the *first* entry
1867c478bd9Sstevel@tonic-gate **  that matches.
1877c478bd9Sstevel@tonic-gate */
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate typedef struct sm_debug_setting SM_DEBUG_SETTING_T;
1907c478bd9Sstevel@tonic-gate struct sm_debug_setting
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate 	const char		*ds_pattern;
1937c478bd9Sstevel@tonic-gate 	unsigned int		ds_level;
1947c478bd9Sstevel@tonic-gate 	SM_DEBUG_SETTING_T	*ds_next;
1957c478bd9Sstevel@tonic-gate };
1967c478bd9Sstevel@tonic-gate SM_DEBUG_SETTING_T *SmDebugSettings = NULL;
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate /*
1997c478bd9Sstevel@tonic-gate **  We keep a linked list of SM_DEBUG structures that have been initialized,
2007c478bd9Sstevel@tonic-gate **  for use by sm_debug_reset.
2017c478bd9Sstevel@tonic-gate */
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate SM_DEBUG_T *SmDebugInitialized = NULL;
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate const char SmDebugMagic[] = "sm_debug";
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate /*
2087c478bd9Sstevel@tonic-gate **  SM_DEBUG_RESET -- Reset SM_DEBUG structures.
2097c478bd9Sstevel@tonic-gate **
2107c478bd9Sstevel@tonic-gate **	Reset all SM_DEBUG structures back to the uninitialized state.
2117c478bd9Sstevel@tonic-gate **	This is used by sm_debug_addsetting to ensure that references to
2127c478bd9Sstevel@tonic-gate **	SM_DEBUG structures that occur before sendmail processes its -d flags
2137c478bd9Sstevel@tonic-gate **	do not cause those structures to be permanently forced to level 0.
2147c478bd9Sstevel@tonic-gate **
2157c478bd9Sstevel@tonic-gate **	Parameters:
2167c478bd9Sstevel@tonic-gate **		none.
2177c478bd9Sstevel@tonic-gate **
2187c478bd9Sstevel@tonic-gate **	Returns:
2197c478bd9Sstevel@tonic-gate **		none.
2207c478bd9Sstevel@tonic-gate */
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate static void
sm_debug_reset()2237c478bd9Sstevel@tonic-gate sm_debug_reset()
2247c478bd9Sstevel@tonic-gate {
2257c478bd9Sstevel@tonic-gate 	SM_DEBUG_T *debug;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	for (debug = SmDebugInitialized;
2287c478bd9Sstevel@tonic-gate 	     debug != NULL;
2297c478bd9Sstevel@tonic-gate 	     debug = debug->debug_next)
2307c478bd9Sstevel@tonic-gate 	{
2317c478bd9Sstevel@tonic-gate 		debug->debug_level = SM_DEBUG_UNKNOWN;
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate 	SmDebugInitialized = NULL;
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate /*
2377c478bd9Sstevel@tonic-gate **  SM_DEBUG_ADDSETTING_X -- add an entry to the database of debug settings
2387c478bd9Sstevel@tonic-gate **
2397c478bd9Sstevel@tonic-gate **	Parameters:
2407c478bd9Sstevel@tonic-gate **		pattern -- a shell-style glob pattern (see sm_match).
2417c478bd9Sstevel@tonic-gate **			WARNING: the storage for 'pattern' will be owned by
2427c478bd9Sstevel@tonic-gate **			the debug package, so it should either be a string
2437c478bd9Sstevel@tonic-gate **			literal or the result of a call to sm_strdup_x.
2447c478bd9Sstevel@tonic-gate **		level -- a non-negative integer.
2457c478bd9Sstevel@tonic-gate **
2467c478bd9Sstevel@tonic-gate **	Returns:
2477c478bd9Sstevel@tonic-gate **		none.
2487c478bd9Sstevel@tonic-gate **
2497c478bd9Sstevel@tonic-gate **	Exceptions:
2507c478bd9Sstevel@tonic-gate **		F:sm_heap -- out of memory
2517c478bd9Sstevel@tonic-gate */
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate void
sm_debug_addsetting_x(pattern,level)2547c478bd9Sstevel@tonic-gate sm_debug_addsetting_x(pattern, level)
2557c478bd9Sstevel@tonic-gate 	const char *pattern;
2567c478bd9Sstevel@tonic-gate 	int level;
2577c478bd9Sstevel@tonic-gate {
2587c478bd9Sstevel@tonic-gate 	SM_DEBUG_SETTING_T *s;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 	SM_REQUIRE(pattern != NULL);
2617c478bd9Sstevel@tonic-gate 	SM_REQUIRE(level >= 0);
2627c478bd9Sstevel@tonic-gate 	s = sm_malloc_x(sizeof(SM_DEBUG_SETTING_T));
2637c478bd9Sstevel@tonic-gate 	s->ds_pattern = pattern;
2647c478bd9Sstevel@tonic-gate 	s->ds_level = (unsigned int) level;
2657c478bd9Sstevel@tonic-gate 	s->ds_next = SmDebugSettings;
2667c478bd9Sstevel@tonic-gate 	SmDebugSettings = s;
2677c478bd9Sstevel@tonic-gate 	sm_debug_reset();
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate /*
2717c478bd9Sstevel@tonic-gate **  PARSE_NAMED_SETTING_X -- process a symbolic debug setting
2727c478bd9Sstevel@tonic-gate **
2737c478bd9Sstevel@tonic-gate **	Parameters:
2747c478bd9Sstevel@tonic-gate **		s -- Points to a non-empty \0 or , terminated string,
2757c478bd9Sstevel@tonic-gate **		     of which the initial character is not a digit.
2767c478bd9Sstevel@tonic-gate **
2777c478bd9Sstevel@tonic-gate **	Returns:
2787c478bd9Sstevel@tonic-gate **		pointer to terminating \0 or , character.
2797c478bd9Sstevel@tonic-gate **
2807c478bd9Sstevel@tonic-gate **	Exceptions:
2817c478bd9Sstevel@tonic-gate **		F:sm.heap -- out of memory.
2827c478bd9Sstevel@tonic-gate **
2837c478bd9Sstevel@tonic-gate **	Side Effects:
2847c478bd9Sstevel@tonic-gate **		adds the setting to the database.
2857c478bd9Sstevel@tonic-gate */
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate static const char *
parse_named_setting_x(s)2887c478bd9Sstevel@tonic-gate parse_named_setting_x(s)
2897c478bd9Sstevel@tonic-gate 	const char *s;
2907c478bd9Sstevel@tonic-gate {
2917c478bd9Sstevel@tonic-gate 	const char *pat, *endpat;
2927c478bd9Sstevel@tonic-gate 	int level;
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	pat = s;
2957c478bd9Sstevel@tonic-gate 	while (*s != '\0' && *s != ',' && *s != '.')
2967c478bd9Sstevel@tonic-gate 		++s;
2977c478bd9Sstevel@tonic-gate 	endpat = s;
2987c478bd9Sstevel@tonic-gate 	if (*s == '.')
2997c478bd9Sstevel@tonic-gate 	{
3007c478bd9Sstevel@tonic-gate 		++s;
3017c478bd9Sstevel@tonic-gate 		level = 0;
3027c478bd9Sstevel@tonic-gate 		while (isascii(*s) && isdigit(*s))
3037c478bd9Sstevel@tonic-gate 		{
3047c478bd9Sstevel@tonic-gate 			level = level * 10 + (*s - '0');
3057c478bd9Sstevel@tonic-gate 			++s;
3067c478bd9Sstevel@tonic-gate 		}
3077c478bd9Sstevel@tonic-gate 		if (level < 0)
3087c478bd9Sstevel@tonic-gate 			level = 0;
3097c478bd9Sstevel@tonic-gate 	}
3107c478bd9Sstevel@tonic-gate 	else
3117c478bd9Sstevel@tonic-gate 		level = 1;
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	sm_debug_addsetting_x(sm_strndup_x(pat, endpat - pat), level);
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	/* skip trailing junk */
3167c478bd9Sstevel@tonic-gate 	while (*s != '\0' && *s != ',')
3177c478bd9Sstevel@tonic-gate 		++s;
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	return s;
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate /*
3237c478bd9Sstevel@tonic-gate **  SM_DEBUG_ADDSETTINGS_X -- process a list of debug options
3247c478bd9Sstevel@tonic-gate **
3257c478bd9Sstevel@tonic-gate **	Parameters:
3267c478bd9Sstevel@tonic-gate **		s -- a list of debug settings, eg the argument to the
3277c478bd9Sstevel@tonic-gate **		     sendmail -d option.
3287c478bd9Sstevel@tonic-gate **
3297c478bd9Sstevel@tonic-gate **		The syntax of the string s is as follows:
3307c478bd9Sstevel@tonic-gate **
3317c478bd9Sstevel@tonic-gate **		<settings> ::= <setting> | <settings> "," <setting>
3327c478bd9Sstevel@tonic-gate **		<setting> ::= <categories> | <categories> "." <level>
3337c478bd9Sstevel@tonic-gate **		<categories> ::= [a-zA-Z_*?][a-zA-Z0-9_*?]*
3347c478bd9Sstevel@tonic-gate **
3357c478bd9Sstevel@tonic-gate **		However, note that we skip over anything we don't
3367c478bd9Sstevel@tonic-gate **		understand, rather than report an error.
3377c478bd9Sstevel@tonic-gate **
3387c478bd9Sstevel@tonic-gate **	Returns:
3397c478bd9Sstevel@tonic-gate **		none.
3407c478bd9Sstevel@tonic-gate **
3417c478bd9Sstevel@tonic-gate **	Exceptions:
3427c478bd9Sstevel@tonic-gate **		F:sm.heap -- out of memory
3437c478bd9Sstevel@tonic-gate **
3447c478bd9Sstevel@tonic-gate **	Side Effects:
3457c478bd9Sstevel@tonic-gate **		updates the database of debug settings.
3467c478bd9Sstevel@tonic-gate */
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate void
sm_debug_addsettings_x(s)3497c478bd9Sstevel@tonic-gate sm_debug_addsettings_x(s)
3507c478bd9Sstevel@tonic-gate 	const char *s;
3517c478bd9Sstevel@tonic-gate {
3527c478bd9Sstevel@tonic-gate 	for (;;)
3537c478bd9Sstevel@tonic-gate 	{
3547c478bd9Sstevel@tonic-gate 		if (*s == '\0')
3557c478bd9Sstevel@tonic-gate 			return;
3567c478bd9Sstevel@tonic-gate 		if (*s == ',')
3577c478bd9Sstevel@tonic-gate 		{
3587c478bd9Sstevel@tonic-gate 			++s;
3597c478bd9Sstevel@tonic-gate 			continue;
3607c478bd9Sstevel@tonic-gate 		}
3617c478bd9Sstevel@tonic-gate 		s = parse_named_setting_x(s);
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate /*
3667c478bd9Sstevel@tonic-gate **  SM_DEBUG_LOADLEVEL -- Get activation level of the specified debug object.
3677c478bd9Sstevel@tonic-gate **
3687c478bd9Sstevel@tonic-gate **	Parameters:
3697c478bd9Sstevel@tonic-gate **		debug -- debug object.
3707c478bd9Sstevel@tonic-gate **
3717c478bd9Sstevel@tonic-gate **	Returns:
3727c478bd9Sstevel@tonic-gate **		Activation level of the specified debug object.
3737c478bd9Sstevel@tonic-gate **
3747c478bd9Sstevel@tonic-gate **	Side Effects:
3757c478bd9Sstevel@tonic-gate **		Ensures that the debug object is initialized.
3767c478bd9Sstevel@tonic-gate */
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate int
sm_debug_loadlevel(debug)3797c478bd9Sstevel@tonic-gate sm_debug_loadlevel(debug)
3807c478bd9Sstevel@tonic-gate 	SM_DEBUG_T *debug;
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate 	if (debug->debug_level == SM_DEBUG_UNKNOWN)
3837c478bd9Sstevel@tonic-gate 	{
3847c478bd9Sstevel@tonic-gate 		SM_DEBUG_SETTING_T *s;
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 		for (s = SmDebugSettings; s != NULL; s = s->ds_next)
3877c478bd9Sstevel@tonic-gate 		{
3887c478bd9Sstevel@tonic-gate 			if (sm_match(debug->debug_name, s->ds_pattern))
3897c478bd9Sstevel@tonic-gate 			{
3907c478bd9Sstevel@tonic-gate 				debug->debug_level = s->ds_level;
3917c478bd9Sstevel@tonic-gate 				goto initialized;
3927c478bd9Sstevel@tonic-gate 			}
3937c478bd9Sstevel@tonic-gate 		}
3947c478bd9Sstevel@tonic-gate 		debug->debug_level = 0;
3957c478bd9Sstevel@tonic-gate 	initialized:
3967c478bd9Sstevel@tonic-gate 		debug->debug_next = SmDebugInitialized;
3977c478bd9Sstevel@tonic-gate 		SmDebugInitialized = debug;
3987c478bd9Sstevel@tonic-gate 	}
3997c478bd9Sstevel@tonic-gate 	return (int) debug->debug_level;
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate /*
4037c478bd9Sstevel@tonic-gate **  SM_DEBUG_LOADACTIVE -- Activation level reached?
4047c478bd9Sstevel@tonic-gate **
4057c478bd9Sstevel@tonic-gate **	Parameters:
4067c478bd9Sstevel@tonic-gate **		debug -- debug object.
4077c478bd9Sstevel@tonic-gate **		level -- level to check.
4087c478bd9Sstevel@tonic-gate **
4097c478bd9Sstevel@tonic-gate **	Returns:
4107c478bd9Sstevel@tonic-gate **		true iff the activation level of the specified debug
4117c478bd9Sstevel@tonic-gate **			object >= level.
4127c478bd9Sstevel@tonic-gate **
4137c478bd9Sstevel@tonic-gate **	Side Effects:
4147c478bd9Sstevel@tonic-gate **		Ensures that the debug object is initialized.
4157c478bd9Sstevel@tonic-gate */
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate bool
sm_debug_loadactive(debug,level)4187c478bd9Sstevel@tonic-gate sm_debug_loadactive(debug, level)
4197c478bd9Sstevel@tonic-gate 	SM_DEBUG_T *debug;
4207c478bd9Sstevel@tonic-gate 	int level;
4217c478bd9Sstevel@tonic-gate {
4227c478bd9Sstevel@tonic-gate 	return sm_debug_loadlevel(debug) >= level;
4237c478bd9Sstevel@tonic-gate }
424