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