140266059SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro * Copyright (c) 2000, 2001, 2003, 2004 Proofpoint, Inc. and its suppliers.
340266059SGregory Neil Shapiro * All rights reserved.
440266059SGregory Neil Shapiro *
540266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set
640266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of
740266059SGregory Neil Shapiro * the sendmail distribution.
840266059SGregory Neil Shapiro */
940266059SGregory Neil Shapiro
1040266059SGregory Neil Shapiro #include <sm/gen.h>
114313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: debug.c,v 1.33 2013-11-22 20:51:42 ca Exp $")
1240266059SGregory Neil Shapiro
1340266059SGregory Neil Shapiro /*
1440266059SGregory Neil Shapiro ** libsm debugging and tracing
1540266059SGregory Neil Shapiro ** For documentation, see debug.html.
1640266059SGregory Neil Shapiro */
1740266059SGregory Neil Shapiro
1840266059SGregory Neil Shapiro #include <ctype.h>
1940266059SGregory Neil Shapiro #include <stdlib.h>
209bd497b8SGregory Neil Shapiro #if _FFR_DEBUG_PID_TIME
219bd497b8SGregory Neil Shapiro #include <unistd.h>
22*5b0945b5SGregory Neil Shapiro #include <sm/types.h>
23*5b0945b5SGregory Neil Shapiro #include <sm/time.h>
249bd497b8SGregory Neil Shapiro #include <time.h>
259bd497b8SGregory Neil Shapiro #endif /* _FFR_DEBUG_PID_TIME */
2640266059SGregory Neil Shapiro #include <setjmp.h>
2740266059SGregory Neil Shapiro #include <sm/io.h>
2840266059SGregory Neil Shapiro #include <sm/assert.h>
2940266059SGregory Neil Shapiro #include <sm/conf.h>
3040266059SGregory Neil Shapiro #include <sm/debug.h>
3140266059SGregory Neil Shapiro #include <sm/string.h>
3240266059SGregory Neil Shapiro #include <sm/varargs.h>
3340266059SGregory Neil Shapiro #include <sm/heap.h>
3440266059SGregory Neil Shapiro
35b6bacd31SGregory Neil Shapiro static void sm_debug_reset __P((void));
36b6bacd31SGregory Neil Shapiro static const char *parse_named_setting_x __P((const char *));
37b6bacd31SGregory Neil Shapiro
3840266059SGregory Neil Shapiro /*
3940266059SGregory Neil Shapiro ** Abstractions for printing trace messages.
4040266059SGregory Neil Shapiro */
4140266059SGregory Neil Shapiro
4240266059SGregory Neil Shapiro /*
4340266059SGregory Neil Shapiro ** The output file to which trace output is directed.
4440266059SGregory Neil Shapiro ** There is a controversy over whether this variable
4540266059SGregory Neil Shapiro ** should be process global or thread local.
4640266059SGregory Neil Shapiro ** To make the interface more abstract, we've hidden the
4740266059SGregory Neil Shapiro ** variable behind access functions.
4840266059SGregory Neil Shapiro */
4940266059SGregory Neil Shapiro
5040266059SGregory Neil Shapiro static SM_FILE_T *SmDebugOutput = smioout;
5140266059SGregory Neil Shapiro
5240266059SGregory Neil Shapiro /*
5340266059SGregory Neil Shapiro ** SM_DEBUG_FILE -- Returns current debug file pointer.
5440266059SGregory Neil Shapiro **
5540266059SGregory Neil Shapiro ** Parameters:
5640266059SGregory Neil Shapiro ** none.
5740266059SGregory Neil Shapiro **
5840266059SGregory Neil Shapiro ** Returns:
5940266059SGregory Neil Shapiro ** current debug file pointer.
6040266059SGregory Neil Shapiro */
6140266059SGregory Neil Shapiro
6240266059SGregory Neil Shapiro SM_FILE_T *
sm_debug_file()6340266059SGregory Neil Shapiro sm_debug_file()
6440266059SGregory Neil Shapiro {
6540266059SGregory Neil Shapiro return SmDebugOutput;
6640266059SGregory Neil Shapiro }
6740266059SGregory Neil Shapiro
6840266059SGregory Neil Shapiro /*
6940266059SGregory Neil Shapiro ** SM_DEBUG_SETFILE -- Sets debug file pointer.
7040266059SGregory Neil Shapiro **
7140266059SGregory Neil Shapiro ** Parameters:
7240266059SGregory Neil Shapiro ** fp -- new debug file pointer.
7340266059SGregory Neil Shapiro **
7440266059SGregory Neil Shapiro ** Returns:
7540266059SGregory Neil Shapiro ** none.
7640266059SGregory Neil Shapiro **
7740266059SGregory Neil Shapiro ** Side Effects:
7840266059SGregory Neil Shapiro ** Sets SmDebugOutput.
7940266059SGregory Neil Shapiro */
8040266059SGregory Neil Shapiro
8140266059SGregory Neil Shapiro void
sm_debug_setfile(fp)8240266059SGregory Neil Shapiro sm_debug_setfile(fp)
8340266059SGregory Neil Shapiro SM_FILE_T *fp;
8440266059SGregory Neil Shapiro {
8540266059SGregory Neil Shapiro SmDebugOutput = fp;
8640266059SGregory Neil Shapiro }
8740266059SGregory Neil Shapiro
8840266059SGregory Neil Shapiro /*
89e92d3f3fSGregory Neil Shapiro ** SM_DEBUG_CLOSE -- Close debug file pointer.
90e92d3f3fSGregory Neil Shapiro **
91e92d3f3fSGregory Neil Shapiro ** Parameters:
92e92d3f3fSGregory Neil Shapiro ** none.
93e92d3f3fSGregory Neil Shapiro **
94e92d3f3fSGregory Neil Shapiro ** Returns:
95e92d3f3fSGregory Neil Shapiro ** none.
96e92d3f3fSGregory Neil Shapiro **
97e92d3f3fSGregory Neil Shapiro ** Side Effects:
98e92d3f3fSGregory Neil Shapiro ** Closes SmDebugOutput.
99e92d3f3fSGregory Neil Shapiro */
100e92d3f3fSGregory Neil Shapiro
101e92d3f3fSGregory Neil Shapiro void
sm_debug_close()102e92d3f3fSGregory Neil Shapiro sm_debug_close()
103e92d3f3fSGregory Neil Shapiro {
104e92d3f3fSGregory Neil Shapiro if (SmDebugOutput != NULL && SmDebugOutput != smioout)
105e92d3f3fSGregory Neil Shapiro {
106e92d3f3fSGregory Neil Shapiro sm_io_close(SmDebugOutput, SM_TIME_DEFAULT);
107e92d3f3fSGregory Neil Shapiro SmDebugOutput = NULL;
108e92d3f3fSGregory Neil Shapiro }
109e92d3f3fSGregory Neil Shapiro }
110e92d3f3fSGregory Neil Shapiro
111e92d3f3fSGregory Neil Shapiro /*
11240266059SGregory Neil Shapiro ** SM_DPRINTF -- printf() for debug output.
11340266059SGregory Neil Shapiro **
11440266059SGregory Neil Shapiro ** Parameters:
11540266059SGregory Neil Shapiro ** fmt -- format for printf()
11640266059SGregory Neil Shapiro **
11740266059SGregory Neil Shapiro ** Returns:
11840266059SGregory Neil Shapiro ** none.
11940266059SGregory Neil Shapiro */
12040266059SGregory Neil Shapiro
1219bd497b8SGregory Neil Shapiro #if _FFR_DEBUG_PID_TIME
1229bd497b8SGregory Neil Shapiro SM_DEBUG_T SmDBGPidTime = SM_DEBUG_INITIALIZER("sm_trace_pid_time",
1239bd497b8SGregory Neil Shapiro "@(#)$Debug: sm_trace_pid_time - print pid and time in debug $");
124*5b0945b5SGregory Neil Shapiro #endif
1259bd497b8SGregory Neil Shapiro
12640266059SGregory Neil Shapiro void
12740266059SGregory Neil Shapiro #if SM_VA_STD
sm_dprintf(char * fmt,...)12840266059SGregory Neil Shapiro sm_dprintf(char *fmt, ...)
12940266059SGregory Neil Shapiro #else /* SM_VA_STD */
13040266059SGregory Neil Shapiro sm_dprintf(fmt, va_alist)
13140266059SGregory Neil Shapiro char *fmt;
13240266059SGregory Neil Shapiro va_dcl
13340266059SGregory Neil Shapiro #endif /* SM_VA_STD */
13440266059SGregory Neil Shapiro {
13540266059SGregory Neil Shapiro SM_VA_LOCAL_DECL
136*5b0945b5SGregory Neil Shapiro #if _FFR_DEBUG_PID_TIME
137*5b0945b5SGregory Neil Shapiro static struct timeval lasttv;
138*5b0945b5SGregory Neil Shapiro #endif
13940266059SGregory Neil Shapiro
14040266059SGregory Neil Shapiro if (SmDebugOutput == NULL)
14140266059SGregory Neil Shapiro return;
1429bd497b8SGregory Neil Shapiro #if _FFR_DEBUG_PID_TIME
1439bd497b8SGregory Neil Shapiro /* note: this is ugly if the output isn't a full line! */
144*5b0945b5SGregory Neil Shapiro if (sm_debug_active(&SmDBGPidTime, 3))
145*5b0945b5SGregory Neil Shapiro {
146*5b0945b5SGregory Neil Shapiro struct timeval tv, tvd;
147*5b0945b5SGregory Neil Shapiro
148*5b0945b5SGregory Neil Shapiro gettimeofday(&tv, NULL);
149*5b0945b5SGregory Neil Shapiro if (timerisset(&lasttv))
150*5b0945b5SGregory Neil Shapiro timersub(&tv, &lasttv, &tvd);
151*5b0945b5SGregory Neil Shapiro else
152*5b0945b5SGregory Neil Shapiro timerclear(&tvd);
153*5b0945b5SGregory Neil Shapiro sm_io_fprintf(SmDebugOutput, SmDebugOutput->f_timeout,
154*5b0945b5SGregory Neil Shapiro "%ld: %ld.%06ld ",
155*5b0945b5SGregory Neil Shapiro (long) getpid(),
156*5b0945b5SGregory Neil Shapiro (long) tvd.tv_sec,
157*5b0945b5SGregory Neil Shapiro (long) tvd.tv_usec);
158*5b0945b5SGregory Neil Shapiro lasttv = tv;
159*5b0945b5SGregory Neil Shapiro }
160*5b0945b5SGregory Neil Shapiro else if (sm_debug_active(&SmDBGPidTime, 2))
161*5b0945b5SGregory Neil Shapiro {
162*5b0945b5SGregory Neil Shapiro struct timeval tv;
163*5b0945b5SGregory Neil Shapiro
164*5b0945b5SGregory Neil Shapiro gettimeofday(&tv, NULL);
165*5b0945b5SGregory Neil Shapiro sm_io_fprintf(SmDebugOutput, SmDebugOutput->f_timeout,
166*5b0945b5SGregory Neil Shapiro "%ld: %ld.%06ld ",
167*5b0945b5SGregory Neil Shapiro (long) getpid(),
168*5b0945b5SGregory Neil Shapiro (long) tv.tv_sec,
169*5b0945b5SGregory Neil Shapiro (long) tv.tv_usec);
170*5b0945b5SGregory Neil Shapiro }
171*5b0945b5SGregory Neil Shapiro else if (sm_debug_active(&SmDBGPidTime, 1))
1729bd497b8SGregory Neil Shapiro {
1739bd497b8SGregory Neil Shapiro static char str[32] = "[1900-00-00/00:00:00] ";
1749bd497b8SGregory Neil Shapiro struct tm *tmp;
1759bd497b8SGregory Neil Shapiro time_t currt;
1769bd497b8SGregory Neil Shapiro
1779bd497b8SGregory Neil Shapiro currt = time((time_t *)0);
1789bd497b8SGregory Neil Shapiro tmp = localtime(&currt);
1799bd497b8SGregory Neil Shapiro snprintf(str, sizeof(str), "[%d-%02d-%02d/%02d:%02d:%02d] ",
1809bd497b8SGregory Neil Shapiro 1900 + tmp->tm_year, /* HACK */
1819bd497b8SGregory Neil Shapiro tmp->tm_mon + 1,
1829bd497b8SGregory Neil Shapiro tmp->tm_mday,
1839bd497b8SGregory Neil Shapiro tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
1849bd497b8SGregory Neil Shapiro sm_io_fprintf(SmDebugOutput, SmDebugOutput->f_timeout,
1859bd497b8SGregory Neil Shapiro "%ld: %s ", (long) getpid(), str);
1869bd497b8SGregory Neil Shapiro }
1879bd497b8SGregory Neil Shapiro #endif /* _FFR_DEBUG_PID_TIME */
1889bd497b8SGregory Neil Shapiro
18940266059SGregory Neil Shapiro SM_VA_START(ap, fmt);
19040266059SGregory Neil Shapiro sm_io_vfprintf(SmDebugOutput, SmDebugOutput->f_timeout, fmt, ap);
19140266059SGregory Neil Shapiro SM_VA_END(ap);
19240266059SGregory Neil Shapiro }
19340266059SGregory Neil Shapiro
19440266059SGregory Neil Shapiro /*
19540266059SGregory Neil Shapiro ** SM_DFLUSH -- Flush debug output.
19640266059SGregory Neil Shapiro **
19740266059SGregory Neil Shapiro ** Parameters:
19840266059SGregory Neil Shapiro ** none.
19940266059SGregory Neil Shapiro **
20040266059SGregory Neil Shapiro ** Returns:
20140266059SGregory Neil Shapiro ** none.
20240266059SGregory Neil Shapiro */
20340266059SGregory Neil Shapiro
20440266059SGregory Neil Shapiro void
sm_dflush()20540266059SGregory Neil Shapiro sm_dflush()
20640266059SGregory Neil Shapiro {
20740266059SGregory Neil Shapiro sm_io_flush(SmDebugOutput, SM_TIME_DEFAULT);
20840266059SGregory Neil Shapiro }
20940266059SGregory Neil Shapiro
21040266059SGregory Neil Shapiro /*
21140266059SGregory Neil Shapiro ** This is the internal database of debug settings.
21240266059SGregory Neil Shapiro ** The semantics of looking up a setting in the settings database
21340266059SGregory Neil Shapiro ** are that the *last* setting specified in a -d option on the sendmail
21440266059SGregory Neil Shapiro ** command line that matches a given SM_DEBUG structure is the one that is
21540266059SGregory Neil Shapiro ** used. That is necessary to conform to the existing semantics of
21640266059SGregory Neil Shapiro ** the sendmail -d option. We store the settings as a linked list in
21740266059SGregory Neil Shapiro ** reverse order, so when we do a lookup, we take the *first* entry
21840266059SGregory Neil Shapiro ** that matches.
21940266059SGregory Neil Shapiro */
22040266059SGregory Neil Shapiro
22140266059SGregory Neil Shapiro typedef struct sm_debug_setting SM_DEBUG_SETTING_T;
22240266059SGregory Neil Shapiro struct sm_debug_setting
22340266059SGregory Neil Shapiro {
22440266059SGregory Neil Shapiro const char *ds_pattern;
22540266059SGregory Neil Shapiro unsigned int ds_level;
22640266059SGregory Neil Shapiro SM_DEBUG_SETTING_T *ds_next;
22740266059SGregory Neil Shapiro };
22840266059SGregory Neil Shapiro SM_DEBUG_SETTING_T *SmDebugSettings = NULL;
22940266059SGregory Neil Shapiro
23040266059SGregory Neil Shapiro /*
23140266059SGregory Neil Shapiro ** We keep a linked list of SM_DEBUG structures that have been initialized,
23240266059SGregory Neil Shapiro ** for use by sm_debug_reset.
23340266059SGregory Neil Shapiro */
23440266059SGregory Neil Shapiro
23540266059SGregory Neil Shapiro SM_DEBUG_T *SmDebugInitialized = NULL;
23640266059SGregory Neil Shapiro
23740266059SGregory Neil Shapiro const char SmDebugMagic[] = "sm_debug";
23840266059SGregory Neil Shapiro
23940266059SGregory Neil Shapiro /*
24040266059SGregory Neil Shapiro ** SM_DEBUG_RESET -- Reset SM_DEBUG structures.
24140266059SGregory Neil Shapiro **
24240266059SGregory Neil Shapiro ** Reset all SM_DEBUG structures back to the uninitialized state.
24340266059SGregory Neil Shapiro ** This is used by sm_debug_addsetting to ensure that references to
24440266059SGregory Neil Shapiro ** SM_DEBUG structures that occur before sendmail processes its -d flags
24540266059SGregory Neil Shapiro ** do not cause those structures to be permanently forced to level 0.
24640266059SGregory Neil Shapiro **
24740266059SGregory Neil Shapiro ** Parameters:
24840266059SGregory Neil Shapiro ** none.
24940266059SGregory Neil Shapiro **
25040266059SGregory Neil Shapiro ** Returns:
25140266059SGregory Neil Shapiro ** none.
25240266059SGregory Neil Shapiro */
25340266059SGregory Neil Shapiro
254b6bacd31SGregory Neil Shapiro static void
sm_debug_reset()25540266059SGregory Neil Shapiro sm_debug_reset()
25640266059SGregory Neil Shapiro {
25740266059SGregory Neil Shapiro SM_DEBUG_T *debug;
25840266059SGregory Neil Shapiro
25940266059SGregory Neil Shapiro for (debug = SmDebugInitialized;
26040266059SGregory Neil Shapiro debug != NULL;
26140266059SGregory Neil Shapiro debug = debug->debug_next)
26240266059SGregory Neil Shapiro {
26340266059SGregory Neil Shapiro debug->debug_level = SM_DEBUG_UNKNOWN;
26440266059SGregory Neil Shapiro }
26540266059SGregory Neil Shapiro SmDebugInitialized = NULL;
26640266059SGregory Neil Shapiro }
26740266059SGregory Neil Shapiro
26840266059SGregory Neil Shapiro /*
26940266059SGregory Neil Shapiro ** SM_DEBUG_ADDSETTING_X -- add an entry to the database of debug settings
27040266059SGregory Neil Shapiro **
27140266059SGregory Neil Shapiro ** Parameters:
27240266059SGregory Neil Shapiro ** pattern -- a shell-style glob pattern (see sm_match).
27340266059SGregory Neil Shapiro ** WARNING: the storage for 'pattern' will be owned by
27440266059SGregory Neil Shapiro ** the debug package, so it should either be a string
27540266059SGregory Neil Shapiro ** literal or the result of a call to sm_strdup_x.
27640266059SGregory Neil Shapiro ** level -- a non-negative integer.
27740266059SGregory Neil Shapiro **
27840266059SGregory Neil Shapiro ** Returns:
27940266059SGregory Neil Shapiro ** none.
28040266059SGregory Neil Shapiro **
28140266059SGregory Neil Shapiro ** Exceptions:
28240266059SGregory Neil Shapiro ** F:sm_heap -- out of memory
28340266059SGregory Neil Shapiro */
28440266059SGregory Neil Shapiro
28540266059SGregory Neil Shapiro void
sm_debug_addsetting_x(pattern,level)28640266059SGregory Neil Shapiro sm_debug_addsetting_x(pattern, level)
28740266059SGregory Neil Shapiro const char *pattern;
28840266059SGregory Neil Shapiro int level;
28940266059SGregory Neil Shapiro {
29040266059SGregory Neil Shapiro SM_DEBUG_SETTING_T *s;
29140266059SGregory Neil Shapiro
29240266059SGregory Neil Shapiro SM_REQUIRE(pattern != NULL);
29340266059SGregory Neil Shapiro SM_REQUIRE(level >= 0);
29440266059SGregory Neil Shapiro s = sm_malloc_x(sizeof(SM_DEBUG_SETTING_T));
29540266059SGregory Neil Shapiro s->ds_pattern = pattern;
29640266059SGregory Neil Shapiro s->ds_level = (unsigned int) level;
29740266059SGregory Neil Shapiro s->ds_next = SmDebugSettings;
29840266059SGregory Neil Shapiro SmDebugSettings = s;
29940266059SGregory Neil Shapiro sm_debug_reset();
30040266059SGregory Neil Shapiro }
30140266059SGregory Neil Shapiro
30240266059SGregory Neil Shapiro /*
30340266059SGregory Neil Shapiro ** PARSE_NAMED_SETTING_X -- process a symbolic debug setting
30440266059SGregory Neil Shapiro **
30540266059SGregory Neil Shapiro ** Parameters:
30640266059SGregory Neil Shapiro ** s -- Points to a non-empty \0 or , terminated string,
30740266059SGregory Neil Shapiro ** of which the initial character is not a digit.
30840266059SGregory Neil Shapiro **
30940266059SGregory Neil Shapiro ** Returns:
31040266059SGregory Neil Shapiro ** pointer to terminating \0 or , character.
31140266059SGregory Neil Shapiro **
31240266059SGregory Neil Shapiro ** Exceptions:
31340266059SGregory Neil Shapiro ** F:sm.heap -- out of memory.
31440266059SGregory Neil Shapiro **
31540266059SGregory Neil Shapiro ** Side Effects:
31640266059SGregory Neil Shapiro ** adds the setting to the database.
31740266059SGregory Neil Shapiro */
31840266059SGregory Neil Shapiro
31940266059SGregory Neil Shapiro static const char *
parse_named_setting_x(s)32040266059SGregory Neil Shapiro parse_named_setting_x(s)
321b6bacd31SGregory Neil Shapiro const char *s;
32240266059SGregory Neil Shapiro {
32340266059SGregory Neil Shapiro const char *pat, *endpat;
32440266059SGregory Neil Shapiro int level;
32540266059SGregory Neil Shapiro
32640266059SGregory Neil Shapiro pat = s;
32740266059SGregory Neil Shapiro while (*s != '\0' && *s != ',' && *s != '.')
32840266059SGregory Neil Shapiro ++s;
32940266059SGregory Neil Shapiro endpat = s;
33040266059SGregory Neil Shapiro if (*s == '.')
33140266059SGregory Neil Shapiro {
33240266059SGregory Neil Shapiro ++s;
33340266059SGregory Neil Shapiro level = 0;
33440266059SGregory Neil Shapiro while (isascii(*s) && isdigit(*s))
33540266059SGregory Neil Shapiro {
33640266059SGregory Neil Shapiro level = level * 10 + (*s - '0');
33740266059SGregory Neil Shapiro ++s;
33840266059SGregory Neil Shapiro }
33940266059SGregory Neil Shapiro if (level < 0)
34040266059SGregory Neil Shapiro level = 0;
34140266059SGregory Neil Shapiro }
34240266059SGregory Neil Shapiro else
34340266059SGregory Neil Shapiro level = 1;
34440266059SGregory Neil Shapiro
34540266059SGregory Neil Shapiro sm_debug_addsetting_x(sm_strndup_x(pat, endpat - pat), level);
34640266059SGregory Neil Shapiro
34740266059SGregory Neil Shapiro /* skip trailing junk */
34840266059SGregory Neil Shapiro while (*s != '\0' && *s != ',')
34940266059SGregory Neil Shapiro ++s;
35040266059SGregory Neil Shapiro
35140266059SGregory Neil Shapiro return s;
35240266059SGregory Neil Shapiro }
35340266059SGregory Neil Shapiro
35440266059SGregory Neil Shapiro /*
35540266059SGregory Neil Shapiro ** SM_DEBUG_ADDSETTINGS_X -- process a list of debug options
35640266059SGregory Neil Shapiro **
35740266059SGregory Neil Shapiro ** Parameters:
35840266059SGregory Neil Shapiro ** s -- a list of debug settings, eg the argument to the
35940266059SGregory Neil Shapiro ** sendmail -d option.
36040266059SGregory Neil Shapiro **
36140266059SGregory Neil Shapiro ** The syntax of the string s is as follows:
36240266059SGregory Neil Shapiro **
36340266059SGregory Neil Shapiro ** <settings> ::= <setting> | <settings> "," <setting>
36440266059SGregory Neil Shapiro ** <setting> ::= <categories> | <categories> "." <level>
36540266059SGregory Neil Shapiro ** <categories> ::= [a-zA-Z_*?][a-zA-Z0-9_*?]*
36640266059SGregory Neil Shapiro **
36740266059SGregory Neil Shapiro ** However, note that we skip over anything we don't
36840266059SGregory Neil Shapiro ** understand, rather than report an error.
36940266059SGregory Neil Shapiro **
37040266059SGregory Neil Shapiro ** Returns:
37140266059SGregory Neil Shapiro ** none.
37240266059SGregory Neil Shapiro **
37340266059SGregory Neil Shapiro ** Exceptions:
37440266059SGregory Neil Shapiro ** F:sm.heap -- out of memory
37540266059SGregory Neil Shapiro **
37640266059SGregory Neil Shapiro ** Side Effects:
37740266059SGregory Neil Shapiro ** updates the database of debug settings.
37840266059SGregory Neil Shapiro */
37940266059SGregory Neil Shapiro
38040266059SGregory Neil Shapiro void
sm_debug_addsettings_x(s)38140266059SGregory Neil Shapiro sm_debug_addsettings_x(s)
382b6bacd31SGregory Neil Shapiro const char *s;
38340266059SGregory Neil Shapiro {
38440266059SGregory Neil Shapiro for (;;)
38540266059SGregory Neil Shapiro {
38640266059SGregory Neil Shapiro if (*s == '\0')
38740266059SGregory Neil Shapiro return;
38840266059SGregory Neil Shapiro if (*s == ',')
38940266059SGregory Neil Shapiro {
39040266059SGregory Neil Shapiro ++s;
39140266059SGregory Neil Shapiro continue;
39240266059SGregory Neil Shapiro }
39340266059SGregory Neil Shapiro s = parse_named_setting_x(s);
39440266059SGregory Neil Shapiro }
39540266059SGregory Neil Shapiro }
39640266059SGregory Neil Shapiro
39740266059SGregory Neil Shapiro /*
39840266059SGregory Neil Shapiro ** SM_DEBUG_LOADLEVEL -- Get activation level of the specified debug object.
39940266059SGregory Neil Shapiro **
40040266059SGregory Neil Shapiro ** Parameters:
40140266059SGregory Neil Shapiro ** debug -- debug object.
40240266059SGregory Neil Shapiro **
40340266059SGregory Neil Shapiro ** Returns:
40440266059SGregory Neil Shapiro ** Activation level of the specified debug object.
40540266059SGregory Neil Shapiro **
40640266059SGregory Neil Shapiro ** Side Effects:
40740266059SGregory Neil Shapiro ** Ensures that the debug object is initialized.
40840266059SGregory Neil Shapiro */
40940266059SGregory Neil Shapiro
41040266059SGregory Neil Shapiro int
sm_debug_loadlevel(debug)41140266059SGregory Neil Shapiro sm_debug_loadlevel(debug)
41240266059SGregory Neil Shapiro SM_DEBUG_T *debug;
41340266059SGregory Neil Shapiro {
41440266059SGregory Neil Shapiro if (debug->debug_level == SM_DEBUG_UNKNOWN)
41540266059SGregory Neil Shapiro {
41640266059SGregory Neil Shapiro SM_DEBUG_SETTING_T *s;
41740266059SGregory Neil Shapiro
41840266059SGregory Neil Shapiro for (s = SmDebugSettings; s != NULL; s = s->ds_next)
41940266059SGregory Neil Shapiro {
42040266059SGregory Neil Shapiro if (sm_match(debug->debug_name, s->ds_pattern))
42140266059SGregory Neil Shapiro {
42240266059SGregory Neil Shapiro debug->debug_level = s->ds_level;
42340266059SGregory Neil Shapiro goto initialized;
42440266059SGregory Neil Shapiro }
42540266059SGregory Neil Shapiro }
42640266059SGregory Neil Shapiro debug->debug_level = 0;
42740266059SGregory Neil Shapiro initialized:
42840266059SGregory Neil Shapiro debug->debug_next = SmDebugInitialized;
42940266059SGregory Neil Shapiro SmDebugInitialized = debug;
43040266059SGregory Neil Shapiro }
43140266059SGregory Neil Shapiro return (int) debug->debug_level;
43240266059SGregory Neil Shapiro }
43340266059SGregory Neil Shapiro
43440266059SGregory Neil Shapiro /*
43540266059SGregory Neil Shapiro ** SM_DEBUG_LOADACTIVE -- Activation level reached?
43640266059SGregory Neil Shapiro **
43740266059SGregory Neil Shapiro ** Parameters:
43840266059SGregory Neil Shapiro ** debug -- debug object.
43940266059SGregory Neil Shapiro ** level -- level to check.
44040266059SGregory Neil Shapiro **
44140266059SGregory Neil Shapiro ** Returns:
44240266059SGregory Neil Shapiro ** true iff the activation level of the specified debug
44340266059SGregory Neil Shapiro ** object >= level.
44440266059SGregory Neil Shapiro **
44540266059SGregory Neil Shapiro ** Side Effects:
44640266059SGregory Neil Shapiro ** Ensures that the debug object is initialized.
44740266059SGregory Neil Shapiro */
44840266059SGregory Neil Shapiro
44940266059SGregory Neil Shapiro bool
sm_debug_loadactive(debug,level)45040266059SGregory Neil Shapiro sm_debug_loadactive(debug, level)
45140266059SGregory Neil Shapiro SM_DEBUG_T *debug;
45240266059SGregory Neil Shapiro int level;
45340266059SGregory Neil Shapiro {
45440266059SGregory Neil Shapiro return sm_debug_loadlevel(debug) >= level;
45540266059SGregory Neil Shapiro }
456