1/* 2 * Copyright (c) 1998-2001 Proofpoint, 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 18SM_RCSID("@(#)$Id: trace.c,v 8.39 2013-11-22 20:51:57 ca Exp $") 19 20static char *tTnewflag __P((char *)); 21static 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 38static unsigned char *tTvect; 39static unsigned int tTsize; 40static char *DefFlags; 41 42void 43tTsetup(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 67static char * 68tToldflag(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 141static char * 142tTnewflag(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 203void 204tTflag(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