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