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 * 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 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 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 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 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 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 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 * 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 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 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 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