Import sendmail 8.13.7
[dragonfly.git] / contrib / sendmail-8.13.7 / sendmail / trace.c
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 }