xref: /titanic_44/usr/src/cmd/sendmail/libsm/debug.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright (c) 2000, 2001, 2003, 2004 Sendmail, Inc. and its suppliers.
3*7c478bd9Sstevel@tonic-gate  *	All rights reserved.
4*7c478bd9Sstevel@tonic-gate  *
5*7c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
6*7c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
7*7c478bd9Sstevel@tonic-gate  * the sendmail distribution.
8*7c478bd9Sstevel@tonic-gate  */
9*7c478bd9Sstevel@tonic-gate 
10*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
11*7c478bd9Sstevel@tonic-gate 
12*7c478bd9Sstevel@tonic-gate #include <sm/gen.h>
13*7c478bd9Sstevel@tonic-gate SM_RCSID("@(#)$Id: debug.c,v 1.30 2004/08/03 20:10:26 ca Exp $")
14*7c478bd9Sstevel@tonic-gate 
15*7c478bd9Sstevel@tonic-gate /*
16*7c478bd9Sstevel@tonic-gate **  libsm debugging and tracing
17*7c478bd9Sstevel@tonic-gate **  For documentation, see debug.html.
18*7c478bd9Sstevel@tonic-gate */
19*7c478bd9Sstevel@tonic-gate 
20*7c478bd9Sstevel@tonic-gate #include <ctype.h>
21*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
22*7c478bd9Sstevel@tonic-gate #include <setjmp.h>
23*7c478bd9Sstevel@tonic-gate #include <sm/io.h>
24*7c478bd9Sstevel@tonic-gate #include <sm/assert.h>
25*7c478bd9Sstevel@tonic-gate #include <sm/conf.h>
26*7c478bd9Sstevel@tonic-gate #include <sm/debug.h>
27*7c478bd9Sstevel@tonic-gate #include <sm/string.h>
28*7c478bd9Sstevel@tonic-gate #include <sm/varargs.h>
29*7c478bd9Sstevel@tonic-gate #include <sm/heap.h>
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate static void		 sm_debug_reset __P((void));
32*7c478bd9Sstevel@tonic-gate static const char	*parse_named_setting_x __P((const char *));
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate /*
35*7c478bd9Sstevel@tonic-gate **  Abstractions for printing trace messages.
36*7c478bd9Sstevel@tonic-gate */
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate /*
39*7c478bd9Sstevel@tonic-gate **  The output file to which trace output is directed.
40*7c478bd9Sstevel@tonic-gate **  There is a controversy over whether this variable
41*7c478bd9Sstevel@tonic-gate **  should be process global or thread local.
42*7c478bd9Sstevel@tonic-gate **  To make the interface more abstract, we've hidden the
43*7c478bd9Sstevel@tonic-gate **  variable behind access functions.
44*7c478bd9Sstevel@tonic-gate */
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate static SM_FILE_T *SmDebugOutput = smioout;
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate /*
49*7c478bd9Sstevel@tonic-gate **  SM_DEBUG_FILE -- Returns current debug file pointer.
50*7c478bd9Sstevel@tonic-gate **
51*7c478bd9Sstevel@tonic-gate **	Parameters:
52*7c478bd9Sstevel@tonic-gate **		none.
53*7c478bd9Sstevel@tonic-gate **
54*7c478bd9Sstevel@tonic-gate **	Returns:
55*7c478bd9Sstevel@tonic-gate **		current debug file pointer.
56*7c478bd9Sstevel@tonic-gate */
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate SM_FILE_T *
59*7c478bd9Sstevel@tonic-gate sm_debug_file()
60*7c478bd9Sstevel@tonic-gate {
61*7c478bd9Sstevel@tonic-gate 	return SmDebugOutput;
62*7c478bd9Sstevel@tonic-gate }
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate /*
65*7c478bd9Sstevel@tonic-gate **  SM_DEBUG_SETFILE -- Sets debug file pointer.
66*7c478bd9Sstevel@tonic-gate **
67*7c478bd9Sstevel@tonic-gate **	Parameters:
68*7c478bd9Sstevel@tonic-gate **		fp -- new debug file pointer.
69*7c478bd9Sstevel@tonic-gate **
70*7c478bd9Sstevel@tonic-gate **	Returns:
71*7c478bd9Sstevel@tonic-gate **		none.
72*7c478bd9Sstevel@tonic-gate **
73*7c478bd9Sstevel@tonic-gate **	Side Effects:
74*7c478bd9Sstevel@tonic-gate **		Sets SmDebugOutput.
75*7c478bd9Sstevel@tonic-gate */
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate void
78*7c478bd9Sstevel@tonic-gate sm_debug_setfile(fp)
79*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
80*7c478bd9Sstevel@tonic-gate {
81*7c478bd9Sstevel@tonic-gate 	SmDebugOutput = fp;
82*7c478bd9Sstevel@tonic-gate }
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate /*
85*7c478bd9Sstevel@tonic-gate **  SM_DEBUG_CLOSE -- Close debug file pointer.
86*7c478bd9Sstevel@tonic-gate **
87*7c478bd9Sstevel@tonic-gate **	Parameters:
88*7c478bd9Sstevel@tonic-gate **		none.
89*7c478bd9Sstevel@tonic-gate **
90*7c478bd9Sstevel@tonic-gate **	Returns:
91*7c478bd9Sstevel@tonic-gate **		none.
92*7c478bd9Sstevel@tonic-gate **
93*7c478bd9Sstevel@tonic-gate **	Side Effects:
94*7c478bd9Sstevel@tonic-gate **		Closes SmDebugOutput.
95*7c478bd9Sstevel@tonic-gate */
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate void
98*7c478bd9Sstevel@tonic-gate sm_debug_close()
99*7c478bd9Sstevel@tonic-gate {
100*7c478bd9Sstevel@tonic-gate 	if (SmDebugOutput != NULL && SmDebugOutput != smioout)
101*7c478bd9Sstevel@tonic-gate 	{
102*7c478bd9Sstevel@tonic-gate 		sm_io_close(SmDebugOutput, SM_TIME_DEFAULT);
103*7c478bd9Sstevel@tonic-gate 		SmDebugOutput = NULL;
104*7c478bd9Sstevel@tonic-gate 	}
105*7c478bd9Sstevel@tonic-gate }
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate /*
108*7c478bd9Sstevel@tonic-gate **  SM_DPRINTF -- printf() for debug output.
109*7c478bd9Sstevel@tonic-gate **
110*7c478bd9Sstevel@tonic-gate **	Parameters:
111*7c478bd9Sstevel@tonic-gate **		fmt -- format for printf()
112*7c478bd9Sstevel@tonic-gate **
113*7c478bd9Sstevel@tonic-gate **	Returns:
114*7c478bd9Sstevel@tonic-gate **		none.
115*7c478bd9Sstevel@tonic-gate */
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate void
118*7c478bd9Sstevel@tonic-gate #if SM_VA_STD
119*7c478bd9Sstevel@tonic-gate sm_dprintf(char *fmt, ...)
120*7c478bd9Sstevel@tonic-gate #else /* SM_VA_STD */
121*7c478bd9Sstevel@tonic-gate sm_dprintf(fmt, va_alist)
122*7c478bd9Sstevel@tonic-gate 	char *fmt;
123*7c478bd9Sstevel@tonic-gate 	va_dcl
124*7c478bd9Sstevel@tonic-gate #endif /* SM_VA_STD */
125*7c478bd9Sstevel@tonic-gate {
126*7c478bd9Sstevel@tonic-gate 	SM_VA_LOCAL_DECL
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 	if (SmDebugOutput == NULL)
129*7c478bd9Sstevel@tonic-gate 		return;
130*7c478bd9Sstevel@tonic-gate 	SM_VA_START(ap, fmt);
131*7c478bd9Sstevel@tonic-gate 	sm_io_vfprintf(SmDebugOutput, SmDebugOutput->f_timeout, fmt, ap);
132*7c478bd9Sstevel@tonic-gate 	SM_VA_END(ap);
133*7c478bd9Sstevel@tonic-gate }
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate /*
136*7c478bd9Sstevel@tonic-gate **  SM_DFLUSH -- Flush debug output.
137*7c478bd9Sstevel@tonic-gate **
138*7c478bd9Sstevel@tonic-gate **	Parameters:
139*7c478bd9Sstevel@tonic-gate **		none.
140*7c478bd9Sstevel@tonic-gate **
141*7c478bd9Sstevel@tonic-gate **	Returns:
142*7c478bd9Sstevel@tonic-gate **		none.
143*7c478bd9Sstevel@tonic-gate */
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate void
146*7c478bd9Sstevel@tonic-gate sm_dflush()
147*7c478bd9Sstevel@tonic-gate {
148*7c478bd9Sstevel@tonic-gate 	sm_io_flush(SmDebugOutput, SM_TIME_DEFAULT);
149*7c478bd9Sstevel@tonic-gate }
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate /*
152*7c478bd9Sstevel@tonic-gate **  This is the internal database of debug settings.
153*7c478bd9Sstevel@tonic-gate **  The semantics of looking up a setting in the settings database
154*7c478bd9Sstevel@tonic-gate **  are that the *last* setting specified in a -d option on the sendmail
155*7c478bd9Sstevel@tonic-gate **  command line that matches a given SM_DEBUG structure is the one that is
156*7c478bd9Sstevel@tonic-gate **  used.  That is necessary to conform to the existing semantics of
157*7c478bd9Sstevel@tonic-gate **  the sendmail -d option.  We store the settings as a linked list in
158*7c478bd9Sstevel@tonic-gate **  reverse order, so when we do a lookup, we take the *first* entry
159*7c478bd9Sstevel@tonic-gate **  that matches.
160*7c478bd9Sstevel@tonic-gate */
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate typedef struct sm_debug_setting SM_DEBUG_SETTING_T;
163*7c478bd9Sstevel@tonic-gate struct sm_debug_setting
164*7c478bd9Sstevel@tonic-gate {
165*7c478bd9Sstevel@tonic-gate 	const char		*ds_pattern;
166*7c478bd9Sstevel@tonic-gate 	unsigned int		ds_level;
167*7c478bd9Sstevel@tonic-gate 	SM_DEBUG_SETTING_T	*ds_next;
168*7c478bd9Sstevel@tonic-gate };
169*7c478bd9Sstevel@tonic-gate SM_DEBUG_SETTING_T *SmDebugSettings = NULL;
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate /*
172*7c478bd9Sstevel@tonic-gate **  We keep a linked list of SM_DEBUG structures that have been initialized,
173*7c478bd9Sstevel@tonic-gate **  for use by sm_debug_reset.
174*7c478bd9Sstevel@tonic-gate */
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate SM_DEBUG_T *SmDebugInitialized = NULL;
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate const char SmDebugMagic[] = "sm_debug";
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate /*
181*7c478bd9Sstevel@tonic-gate **  SM_DEBUG_RESET -- Reset SM_DEBUG structures.
182*7c478bd9Sstevel@tonic-gate **
183*7c478bd9Sstevel@tonic-gate **	Reset all SM_DEBUG structures back to the uninitialized state.
184*7c478bd9Sstevel@tonic-gate **	This is used by sm_debug_addsetting to ensure that references to
185*7c478bd9Sstevel@tonic-gate **	SM_DEBUG structures that occur before sendmail processes its -d flags
186*7c478bd9Sstevel@tonic-gate **	do not cause those structures to be permanently forced to level 0.
187*7c478bd9Sstevel@tonic-gate **
188*7c478bd9Sstevel@tonic-gate **	Parameters:
189*7c478bd9Sstevel@tonic-gate **		none.
190*7c478bd9Sstevel@tonic-gate **
191*7c478bd9Sstevel@tonic-gate **	Returns:
192*7c478bd9Sstevel@tonic-gate **		none.
193*7c478bd9Sstevel@tonic-gate */
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate static void
196*7c478bd9Sstevel@tonic-gate sm_debug_reset()
197*7c478bd9Sstevel@tonic-gate {
198*7c478bd9Sstevel@tonic-gate 	SM_DEBUG_T *debug;
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 	for (debug = SmDebugInitialized;
201*7c478bd9Sstevel@tonic-gate 	     debug != NULL;
202*7c478bd9Sstevel@tonic-gate 	     debug = debug->debug_next)
203*7c478bd9Sstevel@tonic-gate 	{
204*7c478bd9Sstevel@tonic-gate 		debug->debug_level = SM_DEBUG_UNKNOWN;
205*7c478bd9Sstevel@tonic-gate 	}
206*7c478bd9Sstevel@tonic-gate 	SmDebugInitialized = NULL;
207*7c478bd9Sstevel@tonic-gate }
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate /*
210*7c478bd9Sstevel@tonic-gate **  SM_DEBUG_ADDSETTING_X -- add an entry to the database of debug settings
211*7c478bd9Sstevel@tonic-gate **
212*7c478bd9Sstevel@tonic-gate **	Parameters:
213*7c478bd9Sstevel@tonic-gate **		pattern -- a shell-style glob pattern (see sm_match).
214*7c478bd9Sstevel@tonic-gate **			WARNING: the storage for 'pattern' will be owned by
215*7c478bd9Sstevel@tonic-gate **			the debug package, so it should either be a string
216*7c478bd9Sstevel@tonic-gate **			literal or the result of a call to sm_strdup_x.
217*7c478bd9Sstevel@tonic-gate **		level -- a non-negative integer.
218*7c478bd9Sstevel@tonic-gate **
219*7c478bd9Sstevel@tonic-gate **	Returns:
220*7c478bd9Sstevel@tonic-gate **		none.
221*7c478bd9Sstevel@tonic-gate **
222*7c478bd9Sstevel@tonic-gate **	Exceptions:
223*7c478bd9Sstevel@tonic-gate **		F:sm_heap -- out of memory
224*7c478bd9Sstevel@tonic-gate */
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate void
227*7c478bd9Sstevel@tonic-gate sm_debug_addsetting_x(pattern, level)
228*7c478bd9Sstevel@tonic-gate 	const char *pattern;
229*7c478bd9Sstevel@tonic-gate 	int level;
230*7c478bd9Sstevel@tonic-gate {
231*7c478bd9Sstevel@tonic-gate 	SM_DEBUG_SETTING_T *s;
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 	SM_REQUIRE(pattern != NULL);
234*7c478bd9Sstevel@tonic-gate 	SM_REQUIRE(level >= 0);
235*7c478bd9Sstevel@tonic-gate 	s = sm_malloc_x(sizeof(SM_DEBUG_SETTING_T));
236*7c478bd9Sstevel@tonic-gate 	s->ds_pattern = pattern;
237*7c478bd9Sstevel@tonic-gate 	s->ds_level = (unsigned int) level;
238*7c478bd9Sstevel@tonic-gate 	s->ds_next = SmDebugSettings;
239*7c478bd9Sstevel@tonic-gate 	SmDebugSettings = s;
240*7c478bd9Sstevel@tonic-gate 	sm_debug_reset();
241*7c478bd9Sstevel@tonic-gate }
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate /*
244*7c478bd9Sstevel@tonic-gate **  PARSE_NAMED_SETTING_X -- process a symbolic debug setting
245*7c478bd9Sstevel@tonic-gate **
246*7c478bd9Sstevel@tonic-gate **	Parameters:
247*7c478bd9Sstevel@tonic-gate **		s -- Points to a non-empty \0 or , terminated string,
248*7c478bd9Sstevel@tonic-gate **		     of which the initial character is not a digit.
249*7c478bd9Sstevel@tonic-gate **
250*7c478bd9Sstevel@tonic-gate **	Returns:
251*7c478bd9Sstevel@tonic-gate **		pointer to terminating \0 or , character.
252*7c478bd9Sstevel@tonic-gate **
253*7c478bd9Sstevel@tonic-gate **	Exceptions:
254*7c478bd9Sstevel@tonic-gate **		F:sm.heap -- out of memory.
255*7c478bd9Sstevel@tonic-gate **
256*7c478bd9Sstevel@tonic-gate **	Side Effects:
257*7c478bd9Sstevel@tonic-gate **		adds the setting to the database.
258*7c478bd9Sstevel@tonic-gate */
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate static const char *
261*7c478bd9Sstevel@tonic-gate parse_named_setting_x(s)
262*7c478bd9Sstevel@tonic-gate 	const char *s;
263*7c478bd9Sstevel@tonic-gate {
264*7c478bd9Sstevel@tonic-gate 	const char *pat, *endpat;
265*7c478bd9Sstevel@tonic-gate 	int level;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 	pat = s;
268*7c478bd9Sstevel@tonic-gate 	while (*s != '\0' && *s != ',' && *s != '.')
269*7c478bd9Sstevel@tonic-gate 		++s;
270*7c478bd9Sstevel@tonic-gate 	endpat = s;
271*7c478bd9Sstevel@tonic-gate 	if (*s == '.')
272*7c478bd9Sstevel@tonic-gate 	{
273*7c478bd9Sstevel@tonic-gate 		++s;
274*7c478bd9Sstevel@tonic-gate 		level = 0;
275*7c478bd9Sstevel@tonic-gate 		while (isascii(*s) && isdigit(*s))
276*7c478bd9Sstevel@tonic-gate 		{
277*7c478bd9Sstevel@tonic-gate 			level = level * 10 + (*s - '0');
278*7c478bd9Sstevel@tonic-gate 			++s;
279*7c478bd9Sstevel@tonic-gate 		}
280*7c478bd9Sstevel@tonic-gate 		if (level < 0)
281*7c478bd9Sstevel@tonic-gate 			level = 0;
282*7c478bd9Sstevel@tonic-gate 	}
283*7c478bd9Sstevel@tonic-gate 	else
284*7c478bd9Sstevel@tonic-gate 		level = 1;
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate 	sm_debug_addsetting_x(sm_strndup_x(pat, endpat - pat), level);
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 	/* skip trailing junk */
289*7c478bd9Sstevel@tonic-gate 	while (*s != '\0' && *s != ',')
290*7c478bd9Sstevel@tonic-gate 		++s;
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 	return s;
293*7c478bd9Sstevel@tonic-gate }
294*7c478bd9Sstevel@tonic-gate 
295*7c478bd9Sstevel@tonic-gate /*
296*7c478bd9Sstevel@tonic-gate **  SM_DEBUG_ADDSETTINGS_X -- process a list of debug options
297*7c478bd9Sstevel@tonic-gate **
298*7c478bd9Sstevel@tonic-gate **	Parameters:
299*7c478bd9Sstevel@tonic-gate **		s -- a list of debug settings, eg the argument to the
300*7c478bd9Sstevel@tonic-gate **		     sendmail -d option.
301*7c478bd9Sstevel@tonic-gate **
302*7c478bd9Sstevel@tonic-gate **		The syntax of the string s is as follows:
303*7c478bd9Sstevel@tonic-gate **
304*7c478bd9Sstevel@tonic-gate **		<settings> ::= <setting> | <settings> "," <setting>
305*7c478bd9Sstevel@tonic-gate **		<setting> ::= <categories> | <categories> "." <level>
306*7c478bd9Sstevel@tonic-gate **		<categories> ::= [a-zA-Z_*?][a-zA-Z0-9_*?]*
307*7c478bd9Sstevel@tonic-gate **
308*7c478bd9Sstevel@tonic-gate **		However, note that we skip over anything we don't
309*7c478bd9Sstevel@tonic-gate **		understand, rather than report an error.
310*7c478bd9Sstevel@tonic-gate **
311*7c478bd9Sstevel@tonic-gate **	Returns:
312*7c478bd9Sstevel@tonic-gate **		none.
313*7c478bd9Sstevel@tonic-gate **
314*7c478bd9Sstevel@tonic-gate **	Exceptions:
315*7c478bd9Sstevel@tonic-gate **		F:sm.heap -- out of memory
316*7c478bd9Sstevel@tonic-gate **
317*7c478bd9Sstevel@tonic-gate **	Side Effects:
318*7c478bd9Sstevel@tonic-gate **		updates the database of debug settings.
319*7c478bd9Sstevel@tonic-gate */
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate void
322*7c478bd9Sstevel@tonic-gate sm_debug_addsettings_x(s)
323*7c478bd9Sstevel@tonic-gate 	const char *s;
324*7c478bd9Sstevel@tonic-gate {
325*7c478bd9Sstevel@tonic-gate 	for (;;)
326*7c478bd9Sstevel@tonic-gate 	{
327*7c478bd9Sstevel@tonic-gate 		if (*s == '\0')
328*7c478bd9Sstevel@tonic-gate 			return;
329*7c478bd9Sstevel@tonic-gate 		if (*s == ',')
330*7c478bd9Sstevel@tonic-gate 		{
331*7c478bd9Sstevel@tonic-gate 			++s;
332*7c478bd9Sstevel@tonic-gate 			continue;
333*7c478bd9Sstevel@tonic-gate 		}
334*7c478bd9Sstevel@tonic-gate 		s = parse_named_setting_x(s);
335*7c478bd9Sstevel@tonic-gate 	}
336*7c478bd9Sstevel@tonic-gate }
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate /*
339*7c478bd9Sstevel@tonic-gate **  SM_DEBUG_LOADLEVEL -- Get activation level of the specified debug object.
340*7c478bd9Sstevel@tonic-gate **
341*7c478bd9Sstevel@tonic-gate **	Parameters:
342*7c478bd9Sstevel@tonic-gate **		debug -- debug object.
343*7c478bd9Sstevel@tonic-gate **
344*7c478bd9Sstevel@tonic-gate **	Returns:
345*7c478bd9Sstevel@tonic-gate **		Activation level of the specified debug object.
346*7c478bd9Sstevel@tonic-gate **
347*7c478bd9Sstevel@tonic-gate **	Side Effects:
348*7c478bd9Sstevel@tonic-gate **		Ensures that the debug object is initialized.
349*7c478bd9Sstevel@tonic-gate */
350*7c478bd9Sstevel@tonic-gate 
351*7c478bd9Sstevel@tonic-gate int
352*7c478bd9Sstevel@tonic-gate sm_debug_loadlevel(debug)
353*7c478bd9Sstevel@tonic-gate 	SM_DEBUG_T *debug;
354*7c478bd9Sstevel@tonic-gate {
355*7c478bd9Sstevel@tonic-gate 	if (debug->debug_level == SM_DEBUG_UNKNOWN)
356*7c478bd9Sstevel@tonic-gate 	{
357*7c478bd9Sstevel@tonic-gate 		SM_DEBUG_SETTING_T *s;
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate 		for (s = SmDebugSettings; s != NULL; s = s->ds_next)
360*7c478bd9Sstevel@tonic-gate 		{
361*7c478bd9Sstevel@tonic-gate 			if (sm_match(debug->debug_name, s->ds_pattern))
362*7c478bd9Sstevel@tonic-gate 			{
363*7c478bd9Sstevel@tonic-gate 				debug->debug_level = s->ds_level;
364*7c478bd9Sstevel@tonic-gate 				goto initialized;
365*7c478bd9Sstevel@tonic-gate 			}
366*7c478bd9Sstevel@tonic-gate 		}
367*7c478bd9Sstevel@tonic-gate 		debug->debug_level = 0;
368*7c478bd9Sstevel@tonic-gate 	initialized:
369*7c478bd9Sstevel@tonic-gate 		debug->debug_next = SmDebugInitialized;
370*7c478bd9Sstevel@tonic-gate 		SmDebugInitialized = debug;
371*7c478bd9Sstevel@tonic-gate 	}
372*7c478bd9Sstevel@tonic-gate 	return (int) debug->debug_level;
373*7c478bd9Sstevel@tonic-gate }
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate /*
376*7c478bd9Sstevel@tonic-gate **  SM_DEBUG_LOADACTIVE -- Activation level reached?
377*7c478bd9Sstevel@tonic-gate **
378*7c478bd9Sstevel@tonic-gate **	Parameters:
379*7c478bd9Sstevel@tonic-gate **		debug -- debug object.
380*7c478bd9Sstevel@tonic-gate **		level -- level to check.
381*7c478bd9Sstevel@tonic-gate **
382*7c478bd9Sstevel@tonic-gate **	Returns:
383*7c478bd9Sstevel@tonic-gate **		true iff the activation level of the specified debug
384*7c478bd9Sstevel@tonic-gate **			object >= level.
385*7c478bd9Sstevel@tonic-gate **
386*7c478bd9Sstevel@tonic-gate **	Side Effects:
387*7c478bd9Sstevel@tonic-gate **		Ensures that the debug object is initialized.
388*7c478bd9Sstevel@tonic-gate */
389*7c478bd9Sstevel@tonic-gate 
390*7c478bd9Sstevel@tonic-gate bool
391*7c478bd9Sstevel@tonic-gate sm_debug_loadactive(debug, level)
392*7c478bd9Sstevel@tonic-gate 	SM_DEBUG_T *debug;
393*7c478bd9Sstevel@tonic-gate 	int level;
394*7c478bd9Sstevel@tonic-gate {
395*7c478bd9Sstevel@tonic-gate 	return sm_debug_loadlevel(debug) >= level;
396*7c478bd9Sstevel@tonic-gate }
397