xref: /freebsd/contrib/sendmail/src/trace.c (revision 38f0b757fd84d17d0fc24739a7cda160c4516d81)
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 
18 SM_RCSID("@(#)$Id: trace.c,v 8.39 2013/11/22 20:51:57 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 }
225