1 /* 2 * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14 #pragma ident "%Z%%M% %I% %E% SMI" 15 16 #include <sendmail.h> 17 #include <sm/debug.h> 18 #include <sm/string.h> 19 20 SM_RCSID("@(#)$Id: trace.c,v 8.37.4.1 2002/12/05 17:28:05 ca Exp $") 21 22 static char *tTnewflag __P((char *)); 23 static char *tToldflag __P((char *)); 24 25 /* 26 ** TtSETUP -- set up for trace package. 27 ** 28 ** Parameters: 29 ** vect -- pointer to trace vector. 30 ** size -- number of flags in trace vector. 31 ** defflags -- flags to set if no value given. 32 ** 33 ** Returns: 34 ** none 35 ** 36 ** Side Effects: 37 ** environment is set up. 38 */ 39 40 static unsigned char *tTvect; 41 static unsigned int tTsize; 42 static char *DefFlags; 43 44 void 45 tTsetup(vect, size, defflags) 46 unsigned char *vect; 47 unsigned int size; 48 char *defflags; 49 { 50 tTvect = vect; 51 tTsize = size; 52 DefFlags = defflags; 53 } 54 55 /* 56 ** tToldflag -- process an old style trace flag 57 ** 58 ** Parameters: 59 ** s -- points to a [\0, \t] terminated string, 60 ** and the initial character is a digit. 61 ** 62 ** Returns: 63 ** pointer to terminating [\0, \t] character 64 ** 65 ** Side Effects: 66 ** modifies tTvect 67 */ 68 69 static char * 70 tToldflag(s) 71 register char *s; 72 { 73 unsigned int first, last; 74 register unsigned int i; 75 76 /* find first flag to set */ 77 i = 0; 78 while (isascii(*s) && isdigit(*s) && i < tTsize) 79 i = i * 10 + (*s++ - '0'); 80 81 /* 82 ** skip over rest of a too large number 83 ** Maybe we should complain if out-of-bounds values are used. 84 */ 85 86 while (isascii(*s) && isdigit(*s) && i >= tTsize) 87 s++; 88 first = i; 89 90 /* find last flag to set */ 91 if (*s == '-') 92 { 93 i = 0; 94 while (isascii(*++s) && isdigit(*s) && i < tTsize) 95 i = i * 10 + (*s - '0'); 96 97 /* skip over rest of a too large number */ 98 while (isascii(*s) && isdigit(*s) && i >= tTsize) 99 s++; 100 } 101 last = i; 102 103 /* find the level to set it to */ 104 i = 1; 105 if (*s == '.') 106 { 107 i = 0; 108 while (isascii(*++s) && isdigit(*s)) 109 i = i * 10 + (*s - '0'); 110 } 111 112 /* clean up args */ 113 if (first >= tTsize) 114 first = tTsize - 1; 115 if (last >= tTsize) 116 last = tTsize - 1; 117 118 /* set the flags */ 119 while (first <= last) 120 tTvect[first++] = (unsigned char) i; 121 122 /* skip trailing junk */ 123 while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t') 124 ++s; 125 126 return s; 127 } 128 129 /* 130 ** tTnewflag -- process a new style trace flag 131 ** 132 ** Parameters: 133 ** s -- Points to a non-empty [\0, \t] terminated string, 134 ** of which the initial character is not a digit. 135 ** 136 ** Returns: 137 ** pointer to terminating [\0, \t] character 138 ** 139 ** Side Effects: 140 ** adds trace flag to libsm debug database 141 */ 142 143 static char * 144 tTnewflag(s) 145 register char *s; 146 { 147 char *pat, *endpat; 148 int level; 149 150 pat = s; 151 while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t' && *s != '.') 152 ++s; 153 endpat = s; 154 if (*s == '.') 155 { 156 ++s; 157 level = 0; 158 while (isascii(*s) && isdigit(*s)) 159 { 160 level = level * 10 + (*s - '0'); 161 ++s; 162 } 163 if (level < 0) 164 level = 0; 165 } 166 else 167 { 168 level = 1; 169 } 170 171 sm_debug_addsetting_x(sm_strndup_x(pat, endpat - pat), level); 172 173 /* skip trailing junk */ 174 while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t') 175 ++s; 176 177 return s; 178 } 179 180 /* 181 ** TtFLAG -- process an external trace flag list. 182 ** 183 ** Parameters: 184 ** s -- the trace flag. 185 ** 186 ** The syntax of a trace flag list is as follows: 187 ** 188 ** <flags> ::= <flag> | <flags> "," <flag> 189 ** <flag> ::= <categories> | <categories> "." <level> 190 ** <categories> ::= <int> | <int> "-" <int> | <pattern> 191 ** <pattern> ::= <an sh glob pattern matching a C identifier> 192 ** 193 ** White space is ignored before and after a flag. 194 ** However, note that we skip over anything we don't 195 ** understand, rather than report an error. 196 ** 197 ** Returns: 198 ** none. 199 ** 200 ** Side Effects: 201 ** sets/clears old-style trace flags. 202 ** registers new-style trace flags with the libsm debug package. 203 */ 204 205 void 206 tTflag(s) 207 register char *s; 208 { 209 if (s == NULL || *s == '\0') 210 s = DefFlags; 211 212 for (;;) 213 { 214 if (*s == '\0') 215 return; 216 if (*s == ',' || *s == ' ' || *s == '\t') 217 { 218 ++s; 219 continue; 220 } 221 if (isascii(*s) && isdigit(*s)) 222 s = tToldflag(s); 223 else 224 s = tTnewflag(s); 225 } 226 } 227