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