1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright (c) 2000, 2001, 2003 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  *	$Id: debug.h,v 1.16 2003/01/10 00:26:06 ca Exp $
10*7c478bd9Sstevel@tonic-gate  */
11*7c478bd9Sstevel@tonic-gate 
12*7c478bd9Sstevel@tonic-gate /*
13*7c478bd9Sstevel@tonic-gate **  libsm debugging and tracing
14*7c478bd9Sstevel@tonic-gate **  See libsm/debug.html for documentation.
15*7c478bd9Sstevel@tonic-gate */
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #ifndef SM_DEBUG_H
18*7c478bd9Sstevel@tonic-gate # define SM_DEBUG_H
19*7c478bd9Sstevel@tonic-gate 
20*7c478bd9Sstevel@tonic-gate # include <sm/gen.h>
21*7c478bd9Sstevel@tonic-gate # include <sm/io.h>
22*7c478bd9Sstevel@tonic-gate 
23*7c478bd9Sstevel@tonic-gate /*
24*7c478bd9Sstevel@tonic-gate **  abstractions for printing trace messages
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate extern SM_FILE_T *
28*7c478bd9Sstevel@tonic-gate sm_debug_file __P((void));
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate extern void
31*7c478bd9Sstevel@tonic-gate sm_debug_setfile __P(( SM_FILE_T *));
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate extern void PRINTFLIKE(1, 2)
34*7c478bd9Sstevel@tonic-gate sm_dprintf __P((char *_fmt, ...));
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate extern void
37*7c478bd9Sstevel@tonic-gate sm_dflush __P((void));
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate extern void
40*7c478bd9Sstevel@tonic-gate sm_debug_close __P((void));
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate /*
43*7c478bd9Sstevel@tonic-gate **  abstractions for setting and testing debug activation levels
44*7c478bd9Sstevel@tonic-gate */
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate extern void
47*7c478bd9Sstevel@tonic-gate sm_debug_addsettings_x __P((const char *));
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate extern void
50*7c478bd9Sstevel@tonic-gate sm_debug_addsetting_x __P((const char *, int));
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate # define SM_DEBUG_UNKNOWN	((SM_ATOMIC_UINT_T)(-1))
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate extern const char SmDebugMagic[];
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate typedef struct sm_debug SM_DEBUG_T;
57*7c478bd9Sstevel@tonic-gate struct sm_debug
58*7c478bd9Sstevel@tonic-gate {
59*7c478bd9Sstevel@tonic-gate 	const char *sm_magic;	/* points to SmDebugMagic */
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate 	/*
62*7c478bd9Sstevel@tonic-gate 	**  debug_level is the activation level of this debug
63*7c478bd9Sstevel@tonic-gate 	**  object.  Level 0 means no debug activity.
64*7c478bd9Sstevel@tonic-gate 	**  It is initialized to SM_DEBUG_UNKNOWN, which indicates
65*7c478bd9Sstevel@tonic-gate 	**  that the true value is unknown.  If debug_level ==
66*7c478bd9Sstevel@tonic-gate 	**  SM_DEBUG_UNKNOWN, then the access functions will look up
67*7c478bd9Sstevel@tonic-gate 	**  its true value in the internal table of debug settings.
68*7c478bd9Sstevel@tonic-gate 	*/
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate 	SM_ATOMIC_UINT_T debug_level;
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate 	/*
73*7c478bd9Sstevel@tonic-gate 	**  debug_name is the name used to reference this SM_DEBUG
74*7c478bd9Sstevel@tonic-gate 	**  structure via the sendmail -d option.
75*7c478bd9Sstevel@tonic-gate 	*/
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 	char *debug_name;
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	/*
80*7c478bd9Sstevel@tonic-gate 	**  debug_desc is a literal character string of the form
81*7c478bd9Sstevel@tonic-gate 	**  "@(#)$Debug: <name> - <short description> $"
82*7c478bd9Sstevel@tonic-gate 	*/
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate 	char *debug_desc;
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate 	/*
87*7c478bd9Sstevel@tonic-gate 	**  We keep a linked list of initialized SM_DEBUG structures
88*7c478bd9Sstevel@tonic-gate 	**  so that when sm_debug_addsetting is called, we can reset
89*7c478bd9Sstevel@tonic-gate 	**  them all back to the uninitialized state.
90*7c478bd9Sstevel@tonic-gate 	*/
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate 	SM_DEBUG_T *debug_next;
93*7c478bd9Sstevel@tonic-gate };
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate # ifndef SM_DEBUG_CHECK
96*7c478bd9Sstevel@tonic-gate #  define SM_DEBUG_CHECK 1
97*7c478bd9Sstevel@tonic-gate # endif /* ! SM_DEBUG_CHECK */
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate # if SM_DEBUG_CHECK
100*7c478bd9Sstevel@tonic-gate /*
101*7c478bd9Sstevel@tonic-gate **  This macro is cleverly designed so that if the debug object is below
102*7c478bd9Sstevel@tonic-gate **  the specified level, then the only overhead is a single comparison
103*7c478bd9Sstevel@tonic-gate **  (except for the first time this macro is invoked).
104*7c478bd9Sstevel@tonic-gate */
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate #  define sm_debug_active(debug, level) \
107*7c478bd9Sstevel@tonic-gate 	    ((debug)->debug_level >= (level) && \
108*7c478bd9Sstevel@tonic-gate 	     ((debug)->debug_level != SM_DEBUG_UNKNOWN || \
109*7c478bd9Sstevel@tonic-gate 	      sm_debug_loadactive(debug, level)))
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate #  define sm_debug_level(debug) \
112*7c478bd9Sstevel@tonic-gate 	    ((debug)->debug_level == SM_DEBUG_UNKNOWN \
113*7c478bd9Sstevel@tonic-gate 	     ? sm_debug_loadlevel(debug) : (debug)->debug_level)
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate #  define sm_debug_unknown(debug) ((debug)->debug_level == SM_DEBUG_UNKNOWN)
116*7c478bd9Sstevel@tonic-gate # else /* SM_DEBUG_CHECK */
117*7c478bd9Sstevel@tonic-gate #  define sm_debug_active(debug, level)	0
118*7c478bd9Sstevel@tonic-gate #  define sm_debug_level(debug)		0
119*7c478bd9Sstevel@tonic-gate #  define sm_debug_unknown(debug)	0
120*7c478bd9Sstevel@tonic-gate # endif /* SM_DEBUG_CHECK */
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate extern bool
123*7c478bd9Sstevel@tonic-gate sm_debug_loadactive __P((SM_DEBUG_T *, int));
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate extern int
126*7c478bd9Sstevel@tonic-gate sm_debug_loadlevel __P((SM_DEBUG_T *));
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate # define SM_DEBUG_INITIALIZER(name, desc) { \
129*7c478bd9Sstevel@tonic-gate 		SmDebugMagic, \
130*7c478bd9Sstevel@tonic-gate 		SM_DEBUG_UNKNOWN, \
131*7c478bd9Sstevel@tonic-gate 		name, \
132*7c478bd9Sstevel@tonic-gate 		desc, \
133*7c478bd9Sstevel@tonic-gate 		NULL}
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate #endif /* ! SM_DEBUG_H */
136