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