138032Speter/* 2261363Sgshapiro * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers. 364562Sgshapiro * All rights reserved. 438032Speter * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 538032Speter * Copyright (c) 1988, 1993 638032Speter * The Regents of the University of California. All rights reserved. 738032Speter * 838032Speter * By using this file, you agree to the terms and conditions set 938032Speter * forth in the LICENSE file which can be found at the top level of 1038032Speter * the sendmail distribution. 1138032Speter * 1238032Speter */ 1338032Speter 1464562Sgshapiro#include <sendmail.h> 1590792Sgshapiro#include <sm/debug.h> 1690792Sgshapiro#include <sm/string.h> 1738032Speter 18266692SgshapiroSM_RCSID("@(#)$Id: trace.c,v 8.39 2013-11-22 20:51:57 ca Exp $") 1990792Sgshapiro 2090792Sgshapirostatic char *tTnewflag __P((char *)); 2190792Sgshapirostatic char *tToldflag __P((char *)); 2290792Sgshapiro 2338032Speter/* 2438032Speter** TtSETUP -- set up for trace package. 2538032Speter** 2638032Speter** Parameters: 2738032Speter** vect -- pointer to trace vector. 2838032Speter** size -- number of flags in trace vector. 2938032Speter** defflags -- flags to set if no value given. 3038032Speter** 3138032Speter** Returns: 3238032Speter** none 3338032Speter** 3438032Speter** Side Effects: 3538032Speter** environment is set up. 3638032Speter*/ 3738032Speter 3890792Sgshapirostatic unsigned char *tTvect; 3990792Sgshapirostatic unsigned int tTsize; 4038032Speterstatic char *DefFlags; 4138032Speter 4238032Spetervoid 4338032SpetertTsetup(vect, size, defflags) 4490792Sgshapiro unsigned char *vect; 4590792Sgshapiro unsigned int size; 4638032Speter char *defflags; 4738032Speter{ 4838032Speter tTvect = vect; 4938032Speter tTsize = size; 5038032Speter DefFlags = defflags; 5138032Speter} 5290792Sgshapiro 5390792Sgshapiro/* 5490792Sgshapiro** tToldflag -- process an old style trace flag 5538032Speter** 5638032Speter** Parameters: 5790792Sgshapiro** s -- points to a [\0, \t] terminated string, 5890792Sgshapiro** and the initial character is a digit. 5938032Speter** 6038032Speter** Returns: 6190792Sgshapiro** pointer to terminating [\0, \t] character 6238032Speter** 6338032Speter** Side Effects: 6490792Sgshapiro** modifies tTvect 6538032Speter*/ 6638032Speter 6790792Sgshapirostatic char * 6890792SgshapirotToldflag(s) 6938032Speter register char *s; 7038032Speter{ 7182017Sgshapiro unsigned int first, last; 7238032Speter register unsigned int i; 7338032Speter 7490792Sgshapiro /* find first flag to set */ 7590792Sgshapiro i = 0; 7690792Sgshapiro while (isascii(*s) && isdigit(*s) && i < tTsize) 7790792Sgshapiro i = i * 10 + (*s++ - '0'); 7838032Speter 7990792Sgshapiro /* 8090792Sgshapiro ** skip over rest of a too large number 8190792Sgshapiro ** Maybe we should complain if out-of-bounds values are used. 8290792Sgshapiro */ 8390792Sgshapiro 8490792Sgshapiro while (isascii(*s) && isdigit(*s) && i >= tTsize) 8590792Sgshapiro s++; 8690792Sgshapiro first = i; 8790792Sgshapiro 8890792Sgshapiro /* find last flag to set */ 8990792Sgshapiro if (*s == '-') 9038032Speter { 9138032Speter i = 0; 9290792Sgshapiro while (isascii(*++s) && isdigit(*s) && i < tTsize) 9390792Sgshapiro i = i * 10 + (*s - '0'); 9482017Sgshapiro 9590792Sgshapiro /* skip over rest of a too large number */ 9682017Sgshapiro while (isascii(*s) && isdigit(*s) && i >= tTsize) 9782017Sgshapiro s++; 9890792Sgshapiro } 9990792Sgshapiro last = i; 10038032Speter 10190792Sgshapiro /* find the level to set it to */ 10290792Sgshapiro i = 1; 10390792Sgshapiro if (*s == '.') 10490792Sgshapiro { 10590792Sgshapiro i = 0; 10690792Sgshapiro while (isascii(*++s) && isdigit(*s)) 10790792Sgshapiro i = i * 10 + (*s - '0'); 10890792Sgshapiro } 10982017Sgshapiro 11090792Sgshapiro /* clean up args */ 11190792Sgshapiro if (first >= tTsize) 11290792Sgshapiro first = tTsize - 1; 11390792Sgshapiro if (last >= tTsize) 11490792Sgshapiro last = tTsize - 1; 11538032Speter 11690792Sgshapiro /* set the flags */ 11790792Sgshapiro while (first <= last) 11890792Sgshapiro tTvect[first++] = (unsigned char) i; 11990792Sgshapiro 12090792Sgshapiro /* skip trailing junk */ 12190792Sgshapiro while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t') 12290792Sgshapiro ++s; 12390792Sgshapiro 12490792Sgshapiro return s; 12590792Sgshapiro} 12690792Sgshapiro 12790792Sgshapiro/* 12890792Sgshapiro** tTnewflag -- process a new style trace flag 12990792Sgshapiro** 13090792Sgshapiro** Parameters: 13190792Sgshapiro** s -- Points to a non-empty [\0, \t] terminated string, 13290792Sgshapiro** of which the initial character is not a digit. 13390792Sgshapiro** 13490792Sgshapiro** Returns: 13590792Sgshapiro** pointer to terminating [\0, \t] character 13690792Sgshapiro** 13790792Sgshapiro** Side Effects: 13890792Sgshapiro** adds trace flag to libsm debug database 13990792Sgshapiro*/ 14090792Sgshapiro 14190792Sgshapirostatic char * 14290792SgshapirotTnewflag(s) 14390792Sgshapiro register char *s; 14490792Sgshapiro{ 14590792Sgshapiro char *pat, *endpat; 14690792Sgshapiro int level; 14790792Sgshapiro 14890792Sgshapiro pat = s; 14990792Sgshapiro while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t' && *s != '.') 15090792Sgshapiro ++s; 15190792Sgshapiro endpat = s; 15290792Sgshapiro if (*s == '.') 15390792Sgshapiro { 15490792Sgshapiro ++s; 15590792Sgshapiro level = 0; 15690792Sgshapiro while (isascii(*s) && isdigit(*s)) 15738032Speter { 15890792Sgshapiro level = level * 10 + (*s - '0'); 15990792Sgshapiro ++s; 16038032Speter } 16190792Sgshapiro if (level < 0) 16290792Sgshapiro level = 0; 16390792Sgshapiro } 16490792Sgshapiro else 16590792Sgshapiro { 16690792Sgshapiro level = 1; 16790792Sgshapiro } 16838032Speter 16990792Sgshapiro sm_debug_addsetting_x(sm_strndup_x(pat, endpat - pat), level); 17038032Speter 17190792Sgshapiro /* skip trailing junk */ 17290792Sgshapiro while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t') 17390792Sgshapiro ++s; 17438032Speter 17590792Sgshapiro return s; 17690792Sgshapiro} 17790792Sgshapiro 17890792Sgshapiro/* 17990792Sgshapiro** TtFLAG -- process an external trace flag list. 18090792Sgshapiro** 18190792Sgshapiro** Parameters: 18290792Sgshapiro** s -- the trace flag. 18390792Sgshapiro** 18490792Sgshapiro** The syntax of a trace flag list is as follows: 18590792Sgshapiro** 18690792Sgshapiro** <flags> ::= <flag> | <flags> "," <flag> 18790792Sgshapiro** <flag> ::= <categories> | <categories> "." <level> 18890792Sgshapiro** <categories> ::= <int> | <int> "-" <int> | <pattern> 18990792Sgshapiro** <pattern> ::= <an sh glob pattern matching a C identifier> 19090792Sgshapiro** 19190792Sgshapiro** White space is ignored before and after a flag. 19290792Sgshapiro** However, note that we skip over anything we don't 19390792Sgshapiro** understand, rather than report an error. 19490792Sgshapiro** 19590792Sgshapiro** Returns: 19690792Sgshapiro** none. 19790792Sgshapiro** 19890792Sgshapiro** Side Effects: 19990792Sgshapiro** sets/clears old-style trace flags. 20090792Sgshapiro** registers new-style trace flags with the libsm debug package. 20190792Sgshapiro*/ 20290792Sgshapiro 20390792Sgshapirovoid 20490792SgshapirotTflag(s) 20590792Sgshapiro register char *s; 20690792Sgshapiro{ 207110560Sgshapiro if (s == NULL || *s == '\0') 20890792Sgshapiro s = DefFlags; 20990792Sgshapiro 21090792Sgshapiro for (;;) 21190792Sgshapiro { 21290792Sgshapiro if (*s == '\0') 21338032Speter return; 21490792Sgshapiro if (*s == ',' || *s == ' ' || *s == '\t') 21590792Sgshapiro { 21690792Sgshapiro ++s; 21790792Sgshapiro continue; 21890792Sgshapiro } 21990792Sgshapiro if (isascii(*s) && isdigit(*s)) 22090792Sgshapiro s = tToldflag(s); 22190792Sgshapiro else 22290792Sgshapiro s = tTnewflag(s); 22338032Speter } 22438032Speter} 225