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