xref: /freebsd-src/contrib/sendmail/src/trace.c (revision 2fb4f839f3fc72ce2bab12f9ba4760f97f73e97f)
1c2aa98e2SPeter Wemm /*
25dd76dd0SGregory Neil Shapiro  * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro  *	All rights reserved.
4c2aa98e2SPeter Wemm  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5c2aa98e2SPeter Wemm  * Copyright (c) 1988, 1993
6c2aa98e2SPeter Wemm  *	The Regents of the University of California.  All rights reserved.
7c2aa98e2SPeter Wemm  *
8c2aa98e2SPeter Wemm  * By using this file, you agree to the terms and conditions set
9c2aa98e2SPeter Wemm  * forth in the LICENSE file which can be found at the top level of
10c2aa98e2SPeter Wemm  * the sendmail distribution.
11c2aa98e2SPeter Wemm  *
12c2aa98e2SPeter Wemm  */
13c2aa98e2SPeter Wemm 
1406f25ae9SGregory Neil Shapiro #include <sendmail.h>
1540266059SGregory Neil Shapiro #include <sm/debug.h>
1640266059SGregory Neil Shapiro #include <sm/string.h>
1740266059SGregory Neil Shapiro 
184313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: trace.c,v 8.39 2013-11-22 20:51:57 ca Exp $")
1940266059SGregory Neil Shapiro 
2040266059SGregory Neil Shapiro static char	*tTnewflag __P((char *));
2140266059SGregory Neil Shapiro static char	*tToldflag __P((char *));
22c2aa98e2SPeter Wemm 
23c2aa98e2SPeter Wemm /*
24c2aa98e2SPeter Wemm **  TtSETUP -- set up for trace package.
25c2aa98e2SPeter Wemm **
26c2aa98e2SPeter Wemm **	Parameters:
27c2aa98e2SPeter Wemm **		vect -- pointer to trace vector.
28c2aa98e2SPeter Wemm **		size -- number of flags in trace vector.
29c2aa98e2SPeter Wemm **		defflags -- flags to set if no value given.
30c2aa98e2SPeter Wemm **
31c2aa98e2SPeter Wemm **	Returns:
32c2aa98e2SPeter Wemm **		none
33c2aa98e2SPeter Wemm **
34c2aa98e2SPeter Wemm **	Side Effects:
35c2aa98e2SPeter Wemm **		environment is set up.
36c2aa98e2SPeter Wemm */
37c2aa98e2SPeter Wemm 
3840266059SGregory Neil Shapiro static unsigned char	*tTvect;
3940266059SGregory Neil Shapiro static unsigned int	tTsize;
40c2aa98e2SPeter Wemm static char	*DefFlags;
41c2aa98e2SPeter Wemm 
42c2aa98e2SPeter Wemm void
tTsetup(vect,size,defflags)43c2aa98e2SPeter Wemm tTsetup(vect, size, defflags)
4440266059SGregory Neil Shapiro 	unsigned char *vect;
4540266059SGregory Neil Shapiro 	unsigned int size;
46c2aa98e2SPeter Wemm 	char *defflags;
47c2aa98e2SPeter Wemm {
48c2aa98e2SPeter Wemm 	tTvect = vect;
49c2aa98e2SPeter Wemm 	tTsize = size;
50c2aa98e2SPeter Wemm 	DefFlags = defflags;
51c2aa98e2SPeter Wemm }
5240266059SGregory Neil Shapiro 
5340266059SGregory Neil Shapiro /*
5440266059SGregory Neil Shapiro **  tToldflag -- process an old style trace flag
55c2aa98e2SPeter Wemm **
56c2aa98e2SPeter Wemm **	Parameters:
5740266059SGregory Neil Shapiro **		s -- points to a [\0, \t] terminated string,
5840266059SGregory Neil Shapiro **		     and the initial character is a digit.
59c2aa98e2SPeter Wemm **
60c2aa98e2SPeter Wemm **	Returns:
6140266059SGregory Neil Shapiro **		pointer to terminating [\0, \t] character
62c2aa98e2SPeter Wemm **
63c2aa98e2SPeter Wemm **	Side Effects:
6440266059SGregory Neil Shapiro **		modifies tTvect
65c2aa98e2SPeter Wemm */
66c2aa98e2SPeter Wemm 
6740266059SGregory Neil Shapiro static char *
tToldflag(s)6840266059SGregory Neil Shapiro tToldflag(s)
69c2aa98e2SPeter Wemm 	register char *s;
70c2aa98e2SPeter Wemm {
71c86d5965SGregory Neil Shapiro 	unsigned int first, last;
72c2aa98e2SPeter Wemm 	register unsigned int i;
73c2aa98e2SPeter Wemm 
74c2aa98e2SPeter Wemm 	/* find first flag to set */
75c2aa98e2SPeter Wemm 	i = 0;
76c86d5965SGregory Neil Shapiro 	while (isascii(*s) && isdigit(*s) && i < tTsize)
77c2aa98e2SPeter Wemm 		i = i * 10 + (*s++ - '0');
78c86d5965SGregory Neil Shapiro 
79c86d5965SGregory Neil Shapiro 	/*
80c86d5965SGregory Neil Shapiro 	**  skip over rest of a too large number
81c86d5965SGregory Neil Shapiro 	**  Maybe we should complain if out-of-bounds values are used.
82c86d5965SGregory Neil Shapiro 	*/
83c86d5965SGregory Neil Shapiro 
84c86d5965SGregory Neil Shapiro 	while (isascii(*s) && isdigit(*s) && i >= tTsize)
85c86d5965SGregory Neil Shapiro 		s++;
86c2aa98e2SPeter Wemm 	first = i;
87c2aa98e2SPeter Wemm 
88c2aa98e2SPeter Wemm 	/* find last flag to set */
89c2aa98e2SPeter Wemm 	if (*s == '-')
90c2aa98e2SPeter Wemm 	{
91c2aa98e2SPeter Wemm 		i = 0;
92c86d5965SGregory Neil Shapiro 		while (isascii(*++s) && isdigit(*s) && i < tTsize)
93c2aa98e2SPeter Wemm 			i = i * 10 + (*s - '0');
94c86d5965SGregory Neil Shapiro 
95c86d5965SGregory Neil Shapiro 		/* skip over rest of a too large number */
96c86d5965SGregory Neil Shapiro 		while (isascii(*s) && isdigit(*s) && i >= tTsize)
97c86d5965SGregory Neil Shapiro 			s++;
98c2aa98e2SPeter Wemm 	}
99c2aa98e2SPeter Wemm 	last = i;
100c2aa98e2SPeter Wemm 
101c2aa98e2SPeter Wemm 	/* find the level to set it to */
102c2aa98e2SPeter Wemm 	i = 1;
103c2aa98e2SPeter Wemm 	if (*s == '.')
104c2aa98e2SPeter Wemm 	{
105c2aa98e2SPeter Wemm 		i = 0;
106c2aa98e2SPeter Wemm 		while (isascii(*++s) && isdigit(*s))
107c2aa98e2SPeter Wemm 			i = i * 10 + (*s - '0');
108c2aa98e2SPeter Wemm 	}
109c2aa98e2SPeter Wemm 
110c2aa98e2SPeter Wemm 	/* clean up args */
111c2aa98e2SPeter Wemm 	if (first >= tTsize)
112c2aa98e2SPeter Wemm 		first = tTsize - 1;
113c2aa98e2SPeter Wemm 	if (last >= tTsize)
114c2aa98e2SPeter Wemm 		last = tTsize - 1;
115c2aa98e2SPeter Wemm 
116c2aa98e2SPeter Wemm 	/* set the flags */
117c2aa98e2SPeter Wemm 	while (first <= last)
11840266059SGregory Neil Shapiro 		tTvect[first++] = (unsigned char) i;
119c2aa98e2SPeter Wemm 
12040266059SGregory Neil Shapiro 	/* skip trailing junk */
12140266059SGregory Neil Shapiro 	while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t')
12240266059SGregory Neil Shapiro 		++s;
12340266059SGregory Neil Shapiro 
12440266059SGregory Neil Shapiro 	return s;
12540266059SGregory Neil Shapiro }
12640266059SGregory Neil Shapiro 
12740266059SGregory Neil Shapiro /*
12840266059SGregory Neil Shapiro **  tTnewflag -- process a new style trace flag
12940266059SGregory Neil Shapiro **
13040266059SGregory Neil Shapiro **	Parameters:
13140266059SGregory Neil Shapiro **		s -- Points to a non-empty [\0, \t] terminated string,
13240266059SGregory Neil Shapiro **		     of which the initial character is not a digit.
13340266059SGregory Neil Shapiro **
13440266059SGregory Neil Shapiro **	Returns:
13540266059SGregory Neil Shapiro **		pointer to terminating [\0, \t] character
13640266059SGregory Neil Shapiro **
13740266059SGregory Neil Shapiro **	Side Effects:
13840266059SGregory Neil Shapiro **		adds trace flag to libsm debug database
13940266059SGregory Neil Shapiro */
14040266059SGregory Neil Shapiro 
14140266059SGregory Neil Shapiro static char *
tTnewflag(s)14240266059SGregory Neil Shapiro tTnewflag(s)
14340266059SGregory Neil Shapiro 	register char *s;
14440266059SGregory Neil Shapiro {
14540266059SGregory Neil Shapiro 	char *pat, *endpat;
14640266059SGregory Neil Shapiro 	int level;
14740266059SGregory Neil Shapiro 
14840266059SGregory Neil Shapiro 	pat = s;
14940266059SGregory Neil Shapiro 	while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t' && *s != '.')
15040266059SGregory Neil Shapiro 		++s;
15140266059SGregory Neil Shapiro 	endpat = s;
15240266059SGregory Neil Shapiro 	if (*s == '.')
15340266059SGregory Neil Shapiro 	{
15440266059SGregory Neil Shapiro 		++s;
15540266059SGregory Neil Shapiro 		level = 0;
15640266059SGregory Neil Shapiro 		while (isascii(*s) && isdigit(*s))
15740266059SGregory Neil Shapiro 		{
15840266059SGregory Neil Shapiro 			level = level * 10 + (*s - '0');
15940266059SGregory Neil Shapiro 			++s;
16040266059SGregory Neil Shapiro 		}
16140266059SGregory Neil Shapiro 		if (level < 0)
16240266059SGregory Neil Shapiro 			level = 0;
16340266059SGregory Neil Shapiro 	}
16440266059SGregory Neil Shapiro 	else
16540266059SGregory Neil Shapiro 	{
16640266059SGregory Neil Shapiro 		level = 1;
16740266059SGregory Neil Shapiro 	}
16840266059SGregory Neil Shapiro 
16940266059SGregory Neil Shapiro 	sm_debug_addsetting_x(sm_strndup_x(pat, endpat - pat), level);
17040266059SGregory Neil Shapiro 
17140266059SGregory Neil Shapiro 	/* skip trailing junk */
17240266059SGregory Neil Shapiro 	while (*s != '\0' && *s != ',' && *s != ' ' && *s != '\t')
17340266059SGregory Neil Shapiro 		++s;
17440266059SGregory Neil Shapiro 
17540266059SGregory Neil Shapiro 	return s;
17640266059SGregory Neil Shapiro }
17740266059SGregory Neil Shapiro 
17840266059SGregory Neil Shapiro /*
17940266059SGregory Neil Shapiro **  TtFLAG -- process an external trace flag list.
18040266059SGregory Neil Shapiro **
18140266059SGregory Neil Shapiro **	Parameters:
18240266059SGregory Neil Shapiro **		s -- the trace flag.
18340266059SGregory Neil Shapiro **
18440266059SGregory Neil Shapiro **		The syntax of a trace flag list is as follows:
18540266059SGregory Neil Shapiro **
18640266059SGregory Neil Shapiro **		<flags> ::= <flag> | <flags> "," <flag>
18740266059SGregory Neil Shapiro **		<flag> ::= <categories> | <categories> "." <level>
18840266059SGregory Neil Shapiro **		<categories> ::= <int> | <int> "-" <int> | <pattern>
18940266059SGregory Neil Shapiro **		<pattern> ::= <an sh glob pattern matching a C identifier>
19040266059SGregory Neil Shapiro **
19140266059SGregory Neil Shapiro **		White space is ignored before and after a flag.
19240266059SGregory Neil Shapiro **		However, note that we skip over anything we don't
19340266059SGregory Neil Shapiro **		understand, rather than report an error.
19440266059SGregory Neil Shapiro **
19540266059SGregory Neil Shapiro **	Returns:
19640266059SGregory Neil Shapiro **		none.
19740266059SGregory Neil Shapiro **
19840266059SGregory Neil Shapiro **	Side Effects:
19940266059SGregory Neil Shapiro **		sets/clears old-style trace flags.
20040266059SGregory Neil Shapiro **		registers new-style trace flags with the libsm debug package.
20140266059SGregory Neil Shapiro */
20240266059SGregory Neil Shapiro 
20340266059SGregory Neil Shapiro void
tTflag(s)20440266059SGregory Neil Shapiro tTflag(s)
20540266059SGregory Neil Shapiro 	register char *s;
20640266059SGregory Neil Shapiro {
207*2fb4f839SGregory Neil Shapiro 	if (SM_IS_EMPTY(s))
20840266059SGregory Neil Shapiro 		s = DefFlags;
20940266059SGregory Neil Shapiro 
21040266059SGregory Neil Shapiro 	for (;;)
21140266059SGregory Neil Shapiro 	{
21240266059SGregory Neil Shapiro 		if (*s == '\0')
213c2aa98e2SPeter Wemm 			return;
21440266059SGregory Neil Shapiro 		if (*s == ',' || *s == ' ' || *s == '\t')
21540266059SGregory Neil Shapiro 		{
21640266059SGregory Neil Shapiro 			++s;
21740266059SGregory Neil Shapiro 			continue;
21840266059SGregory Neil Shapiro 		}
21940266059SGregory Neil Shapiro 		if (isascii(*s) && isdigit(*s))
22040266059SGregory Neil Shapiro 			s = tToldflag(s);
22140266059SGregory Neil Shapiro 		else
22240266059SGregory Neil Shapiro 			s = tTnewflag(s);
223c2aa98e2SPeter Wemm 	}
224c2aa98e2SPeter Wemm }
225