xref: /titanic_52/usr/src/cmd/tnf/prex/list.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1994, by Sun Microsytems, Inc.
24*7c478bd9Sstevel@tonic-gate  */
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate /*
29*7c478bd9Sstevel@tonic-gate  * Includes
30*7c478bd9Sstevel@tonic-gate  */
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #ifndef DEBUG
33*7c478bd9Sstevel@tonic-gate #define	NDEBUG	1
34*7c478bd9Sstevel@tonic-gate #endif
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #include <stdio.h>
37*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
38*7c478bd9Sstevel@tonic-gate #include <string.h>
39*7c478bd9Sstevel@tonic-gate #include <assert.h>
40*7c478bd9Sstevel@tonic-gate #include <libintl.h>
41*7c478bd9Sstevel@tonic-gate #include <search.h>
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #include "source.h"
44*7c478bd9Sstevel@tonic-gate #include "queue.h"
45*7c478bd9Sstevel@tonic-gate #include "list.h"
46*7c478bd9Sstevel@tonic-gate #include "spec.h"
47*7c478bd9Sstevel@tonic-gate #include "new.h"
48*7c478bd9Sstevel@tonic-gate #include "fcn.h"
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate extern caddr_t  g_commitfunc;
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate /*
54*7c478bd9Sstevel@tonic-gate  * Typedefs
55*7c478bd9Sstevel@tonic-gate  */
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate typedef struct list_probe_args {
58*7c478bd9Sstevel@tonic-gate 	spec_t		 *speclist_p;
59*7c478bd9Sstevel@tonic-gate 	expr_t		 *exprlist_p;
60*7c478bd9Sstevel@tonic-gate } list_probe_args_t;
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate typedef struct list_attrs_args {
63*7c478bd9Sstevel@tonic-gate 	spec_t		 *speclist_p;
64*7c478bd9Sstevel@tonic-gate 	void		   *attrroot_p;
65*7c478bd9Sstevel@tonic-gate } list_attrs_args_t;
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate typedef struct attr_node {
68*7c478bd9Sstevel@tonic-gate 	char		   *name;
69*7c478bd9Sstevel@tonic-gate 	void		   *valsroot_p;
70*7c478bd9Sstevel@tonic-gate } attr_node_t;
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate typedef struct vals_node {
73*7c478bd9Sstevel@tonic-gate 	char		   *name;
74*7c478bd9Sstevel@tonic-gate } vals_node_t;
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate /*
78*7c478bd9Sstevel@tonic-gate  * Globals
79*7c478bd9Sstevel@tonic-gate  */
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate /*
83*7c478bd9Sstevel@tonic-gate  * Declarations
84*7c478bd9Sstevel@tonic-gate  */
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t listprobe(tnfctl_handle_t *hndl,
87*7c478bd9Sstevel@tonic-gate 	tnfctl_probe_t *ref_p, void *calldata_p);
88*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t probescan(tnfctl_handle_t *hndl,
89*7c478bd9Sstevel@tonic-gate 	tnfctl_probe_t *ref_p, void *calldata_p);
90*7c478bd9Sstevel@tonic-gate static void printattrval(spec_t * spec_p, char *attr, char *value,
91*7c478bd9Sstevel@tonic-gate 	void *pdata);
92*7c478bd9Sstevel@tonic-gate static void attrscan(spec_t * spec_p, char *attr, char *values, void *pdata);
93*7c478bd9Sstevel@tonic-gate static int attrcompare(const void *node1, const void *node2);
94*7c478bd9Sstevel@tonic-gate static int valscompare(const void *node1, const void *node2);
95*7c478bd9Sstevel@tonic-gate static void printattrs(const void *node, VISIT order, int level);
96*7c478bd9Sstevel@tonic-gate static void printvals(const void *node, VISIT order, int level);
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate #if 0
99*7c478bd9Sstevel@tonic-gate static void	 attrnodedel(attr_node_t * an_p);
100*7c478bd9Sstevel@tonic-gate #endif
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate static void valadd(spec_t * spec_p, char *val, void *calldata_p);
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate /* ---------------------------------------------------------------- */
106*7c478bd9Sstevel@tonic-gate /* ----------------------- Public Functions ----------------------- */
107*7c478bd9Sstevel@tonic-gate /* ---------------------------------------------------------------- */
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate extern tnfctl_handle_t	*g_hndl;
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate /*
112*7c478bd9Sstevel@tonic-gate  * list_set() - lists all of the current probes in a target process
113*7c478bd9Sstevel@tonic-gate  */
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate void
116*7c478bd9Sstevel@tonic-gate list_set(spec_t * speclist_p, char *setname_p)
117*7c478bd9Sstevel@tonic-gate {
118*7c478bd9Sstevel@tonic-gate 	set_t *set_p;
119*7c478bd9Sstevel@tonic-gate 	list_probe_args_t args;
120*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t err;
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate 	set_p = set_find(setname_p);
123*7c478bd9Sstevel@tonic-gate 	if (!set_p) {
124*7c478bd9Sstevel@tonic-gate 		semantic_err(gettext("missing or invalid set"));
125*7c478bd9Sstevel@tonic-gate 		return;
126*7c478bd9Sstevel@tonic-gate 	}
127*7c478bd9Sstevel@tonic-gate 	args.speclist_p = speclist_p;
128*7c478bd9Sstevel@tonic-gate 	args.exprlist_p = set_p->exprlist_p;
129*7c478bd9Sstevel@tonic-gate 	err = tnfctl_probe_apply(g_hndl, listprobe, &args);
130*7c478bd9Sstevel@tonic-gate 	if (err) {
131*7c478bd9Sstevel@tonic-gate 		semantic_err(gettext("listing error : %s"),
132*7c478bd9Sstevel@tonic-gate 				tnfctl_strerror(err));
133*7c478bd9Sstevel@tonic-gate 	}
134*7c478bd9Sstevel@tonic-gate }
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate /*
138*7c478bd9Sstevel@tonic-gate  * list_expr() - lists all of the current probes in an expression list
139*7c478bd9Sstevel@tonic-gate  */
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate void
142*7c478bd9Sstevel@tonic-gate list_expr(spec_t * speclist_p, expr_t * expr_p)
143*7c478bd9Sstevel@tonic-gate {
144*7c478bd9Sstevel@tonic-gate 	list_probe_args_t args;
145*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t err;
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	args.speclist_p = speclist_p;
148*7c478bd9Sstevel@tonic-gate 	args.exprlist_p = expr_p;
149*7c478bd9Sstevel@tonic-gate 	err = tnfctl_probe_apply(g_hndl, listprobe, &args);
150*7c478bd9Sstevel@tonic-gate 	if (err) {
151*7c478bd9Sstevel@tonic-gate 		semantic_err(gettext("listing error : %s"),
152*7c478bd9Sstevel@tonic-gate 				tnfctl_strerror(err));
153*7c478bd9Sstevel@tonic-gate 	}
154*7c478bd9Sstevel@tonic-gate }
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate /*
158*7c478bd9Sstevel@tonic-gate  * list_values() - list all the values for a supplied spec
159*7c478bd9Sstevel@tonic-gate  */
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate void
162*7c478bd9Sstevel@tonic-gate list_values(spec_t * speclist_p)
163*7c478bd9Sstevel@tonic-gate {
164*7c478bd9Sstevel@tonic-gate 	list_attrs_args_t args;
165*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t err;
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 	/* setup argument block */
168*7c478bd9Sstevel@tonic-gate 	args.speclist_p = speclist_p;
169*7c478bd9Sstevel@tonic-gate 	args.attrroot_p = NULL;
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate 	/* traverse the probes, recording attributes that match */
172*7c478bd9Sstevel@tonic-gate 	err = tnfctl_probe_apply(g_hndl, probescan, &args);
173*7c478bd9Sstevel@tonic-gate 	if (err) {
174*7c478bd9Sstevel@tonic-gate 		semantic_err(gettext("probe traversal error : %s"),
175*7c478bd9Sstevel@tonic-gate 				tnfctl_strerror(err));
176*7c478bd9Sstevel@tonic-gate 	}
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	/* pretty print the results */
179*7c478bd9Sstevel@tonic-gate 	twalk(args.attrroot_p, printattrs);
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate 	/* destroy the attribute tree */
182*7c478bd9Sstevel@tonic-gate 	while (args.attrroot_p) {
183*7c478bd9Sstevel@tonic-gate 		attr_node_t   **aptr;
184*7c478bd9Sstevel@tonic-gate 		char			*anameptr;
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate 		aptr = (attr_node_t **) args.attrroot_p;
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate 		/* destroy the value tree */
189*7c478bd9Sstevel@tonic-gate 		while ((*aptr)->valsroot_p) {
190*7c478bd9Sstevel@tonic-gate 			vals_node_t   **vptr;
191*7c478bd9Sstevel@tonic-gate 			char			*vnameptr;
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 			vptr = (vals_node_t **) (*aptr)->valsroot_p;
194*7c478bd9Sstevel@tonic-gate 			vnameptr = (*vptr)->name;
195*7c478bd9Sstevel@tonic-gate #ifdef LEAKCHK
196*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "freeing value \"%s\"\n",
197*7c478bd9Sstevel@tonic-gate 				vnameptr);
198*7c478bd9Sstevel@tonic-gate #endif
199*7c478bd9Sstevel@tonic-gate 			(void) tdelete((void *) *vptr, &(*aptr)->valsroot_p,
200*7c478bd9Sstevel@tonic-gate 				valscompare);
201*7c478bd9Sstevel@tonic-gate 			if (vnameptr) free(vnameptr);
202*7c478bd9Sstevel@tonic-gate 		}
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 		anameptr = (*aptr)->name;
205*7c478bd9Sstevel@tonic-gate #ifdef LEAKCHK
206*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "freeing attr \"%s\"\n", anameptr);
207*7c478bd9Sstevel@tonic-gate #endif
208*7c478bd9Sstevel@tonic-gate 		(void) tdelete((void *) *aptr, &args.attrroot_p, attrcompare);
209*7c478bd9Sstevel@tonic-gate 		if (anameptr) free(anameptr);
210*7c478bd9Sstevel@tonic-gate 	}
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate }				/* end list_values */
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate /*
216*7c478bd9Sstevel@tonic-gate  * list_getattrs() - build an attribute string for this probe.
217*7c478bd9Sstevel@tonic-gate  */
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate #define	BUF_LIMIT	2048
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate char *
223*7c478bd9Sstevel@tonic-gate list_getattrs(tnfctl_probe_t *probe_p)
224*7c478bd9Sstevel@tonic-gate {
225*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t	err;
226*7c478bd9Sstevel@tonic-gate 	tnfctl_probe_state_t	p_state;
227*7c478bd9Sstevel@tonic-gate 	char			*attrs;
228*7c478bd9Sstevel@tonic-gate 	char			buffer[BUF_LIMIT];
229*7c478bd9Sstevel@tonic-gate 	char			*buf_p;
230*7c478bd9Sstevel@tonic-gate 	char			*buf_end;
231*7c478bd9Sstevel@tonic-gate 	int			str_len;
232*7c478bd9Sstevel@tonic-gate 	size_t			len;
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 	err = tnfctl_probe_state_get(g_hndl, probe_p, &p_state);
235*7c478bd9Sstevel@tonic-gate 	if (err) {
236*7c478bd9Sstevel@tonic-gate 		attrs = malloc(2);
237*7c478bd9Sstevel@tonic-gate 		if (attrs)
238*7c478bd9Sstevel@tonic-gate 			attrs[0] = '\0';
239*7c478bd9Sstevel@tonic-gate 		return (attrs);
240*7c478bd9Sstevel@tonic-gate 	}
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 	buf_p = buffer;
243*7c478bd9Sstevel@tonic-gate 	buf_end = buf_p + BUF_LIMIT;
244*7c478bd9Sstevel@tonic-gate 	str_len = sprintf(buf_p, "enable %s; trace %s; ",
245*7c478bd9Sstevel@tonic-gate 				(p_state.enabled) ? "on" : "off",
246*7c478bd9Sstevel@tonic-gate 				(p_state.traced) ? "on" : "off");
247*7c478bd9Sstevel@tonic-gate 	buf_p += str_len;
248*7c478bd9Sstevel@tonic-gate 	if (p_state.obj_name) {
249*7c478bd9Sstevel@tonic-gate 		str_len = strlen(p_state.obj_name);
250*7c478bd9Sstevel@tonic-gate 		if (buf_p + str_len < buf_end) {
251*7c478bd9Sstevel@tonic-gate 			str_len = sprintf(buf_p, "object %s; ",
252*7c478bd9Sstevel@tonic-gate 							p_state.obj_name);
253*7c478bd9Sstevel@tonic-gate 			buf_p += str_len;
254*7c478bd9Sstevel@tonic-gate 		}
255*7c478bd9Sstevel@tonic-gate 	}
256*7c478bd9Sstevel@tonic-gate 	str_len = sprintf(buf_p, "funcs");
257*7c478bd9Sstevel@tonic-gate 	buf_p += str_len;
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate 	/* REMIND: add limit for string size */
260*7c478bd9Sstevel@tonic-gate 	if (p_state.func_names) {
261*7c478bd9Sstevel@tonic-gate 		int 	i = 0;
262*7c478bd9Sstevel@tonic-gate 		char	*fcnname;
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate 		while (p_state.func_names[i]) {
265*7c478bd9Sstevel@tonic-gate 			(void) strcat(buffer, " ");
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 			fcnname = fcn_findname(p_state.func_names[i]);
268*7c478bd9Sstevel@tonic-gate 			if (fcnname) {
269*7c478bd9Sstevel@tonic-gate 				(void) strcat(buffer, "&");
270*7c478bd9Sstevel@tonic-gate 				(void) strcat(buffer, fcnname);
271*7c478bd9Sstevel@tonic-gate 			} else
272*7c478bd9Sstevel@tonic-gate 				(void) strcat(buffer, p_state.func_names[i]);
273*7c478bd9Sstevel@tonic-gate 			i++;
274*7c478bd9Sstevel@tonic-gate 		}
275*7c478bd9Sstevel@tonic-gate 	}
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate 	(void) strcat(buffer, ";");
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate 	len = strlen(buffer) + strlen(p_state.attr_string) + 1;
280*7c478bd9Sstevel@tonic-gate 	attrs = (char *) malloc(len);
281*7c478bd9Sstevel@tonic-gate 
282*7c478bd9Sstevel@tonic-gate 	if (attrs) {
283*7c478bd9Sstevel@tonic-gate 		(void) strcpy(attrs, buffer);
284*7c478bd9Sstevel@tonic-gate 		(void) strcat(attrs, p_state.attr_string);
285*7c478bd9Sstevel@tonic-gate 	}
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 	return (attrs);
288*7c478bd9Sstevel@tonic-gate }
289*7c478bd9Sstevel@tonic-gate 
290*7c478bd9Sstevel@tonic-gate 
291*7c478bd9Sstevel@tonic-gate /* ---------------------------------------------------------------- */
292*7c478bd9Sstevel@tonic-gate /* ----------------------- Private Functions ---------------------- */
293*7c478bd9Sstevel@tonic-gate /* ---------------------------------------------------------------- */
294*7c478bd9Sstevel@tonic-gate 
295*7c478bd9Sstevel@tonic-gate /*
296*7c478bd9Sstevel@tonic-gate  * probescan() - function used as a callback, gathers probe attributes and
297*7c478bd9Sstevel@tonic-gate  * values
298*7c478bd9Sstevel@tonic-gate  */
299*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
300*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t
301*7c478bd9Sstevel@tonic-gate probescan(tnfctl_handle_t *hndl, tnfctl_probe_t *ref_p, void *calldata_p)
302*7c478bd9Sstevel@tonic-gate {
303*7c478bd9Sstevel@tonic-gate 	list_attrs_args_t *args_p = (list_attrs_args_t *) calldata_p;
304*7c478bd9Sstevel@tonic-gate 	spec_t		*speclist_p;
305*7c478bd9Sstevel@tonic-gate 	spec_t		*spec_p;
306*7c478bd9Sstevel@tonic-gate 	char		*attrs;
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate 	speclist_p = args_p->speclist_p;
309*7c478bd9Sstevel@tonic-gate 	spec_p = NULL;
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate 	attrs = list_getattrs(ref_p);
312*7c478bd9Sstevel@tonic-gate 
313*7c478bd9Sstevel@tonic-gate 	while (spec_p = (spec_t *) queue_next(&speclist_p->qn, &spec_p->qn)) {
314*7c478bd9Sstevel@tonic-gate 		spec_attrtrav(spec_p, attrs, attrscan, calldata_p);
315*7c478bd9Sstevel@tonic-gate 	}
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate 	if (attrs)
318*7c478bd9Sstevel@tonic-gate 		free(attrs);
319*7c478bd9Sstevel@tonic-gate 
320*7c478bd9Sstevel@tonic-gate 	return (TNFCTL_ERR_NONE);
321*7c478bd9Sstevel@tonic-gate }
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate /*
325*7c478bd9Sstevel@tonic-gate  * attrscan() - called on each matching attr/values component
326*7c478bd9Sstevel@tonic-gate  */
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
329*7c478bd9Sstevel@tonic-gate static void
330*7c478bd9Sstevel@tonic-gate attrscan(spec_t * spec_p,
331*7c478bd9Sstevel@tonic-gate 	char *attr,
332*7c478bd9Sstevel@tonic-gate 	char *values,
333*7c478bd9Sstevel@tonic-gate 	void *pdata)
334*7c478bd9Sstevel@tonic-gate {
335*7c478bd9Sstevel@tonic-gate 	list_attrs_args_t *args_p = (list_attrs_args_t *) pdata;
336*7c478bd9Sstevel@tonic-gate 	attr_node_t	*an_p;
337*7c478bd9Sstevel@tonic-gate 	attr_node_t   **ret_pp;
338*7c478bd9Sstevel@tonic-gate 	static spec_t  *allspec = NULL;
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate 	if (!allspec)
341*7c478bd9Sstevel@tonic-gate 		allspec = spec(".*", SPEC_REGEXP);
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 	an_p = new(attr_node_t);
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate #ifdef LEAKCHK
346*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "creating attr \"%s\"\n", attr);
347*7c478bd9Sstevel@tonic-gate #endif
348*7c478bd9Sstevel@tonic-gate 	an_p->name = strdup(attr);
349*7c478bd9Sstevel@tonic-gate 	an_p->valsroot_p = NULL;
350*7c478bd9Sstevel@tonic-gate 
351*7c478bd9Sstevel@tonic-gate 	ret_pp = tfind((void *) an_p, &args_p->attrroot_p, attrcompare);
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 	if (ret_pp) {
354*7c478bd9Sstevel@tonic-gate 		/*
355*7c478bd9Sstevel@tonic-gate 		 * we already had a node for this attribute; delete ours *
356*7c478bd9Sstevel@tonic-gate 		 * and point at the original instead.
357*7c478bd9Sstevel@tonic-gate 		 */
358*7c478bd9Sstevel@tonic-gate #ifdef LEAKCHK
359*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "attr already there \"%s\"\n", attr);
360*7c478bd9Sstevel@tonic-gate #endif
361*7c478bd9Sstevel@tonic-gate 		if (an_p->name)
362*7c478bd9Sstevel@tonic-gate 			free(an_p->name);
363*7c478bd9Sstevel@tonic-gate 		free(an_p);
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate 		an_p = *ret_pp;
366*7c478bd9Sstevel@tonic-gate 	} else {
367*7c478bd9Sstevel@tonic-gate 		(void) tsearch((void *) an_p, &args_p->attrroot_p, attrcompare);
368*7c478bd9Sstevel@tonic-gate 	}
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate 	spec_valtrav(allspec, values, valadd, (void *) an_p);
371*7c478bd9Sstevel@tonic-gate 
372*7c478bd9Sstevel@tonic-gate }				/* end attrscan */
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate /*
376*7c478bd9Sstevel@tonic-gate  * valadd() - add vals to an attributes tree
377*7c478bd9Sstevel@tonic-gate  */
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
380*7c478bd9Sstevel@tonic-gate static void
381*7c478bd9Sstevel@tonic-gate valadd(spec_t * spec_p,
382*7c478bd9Sstevel@tonic-gate 	char *val,
383*7c478bd9Sstevel@tonic-gate 	void *calldata_p)
384*7c478bd9Sstevel@tonic-gate {
385*7c478bd9Sstevel@tonic-gate 	attr_node_t	*an_p = (attr_node_t *) calldata_p;
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate 	vals_node_t	*vn_p;
388*7c478bd9Sstevel@tonic-gate 	vals_node_t   **ret_pp;
389*7c478bd9Sstevel@tonic-gate 
390*7c478bd9Sstevel@tonic-gate 	vn_p = new(vals_node_t);
391*7c478bd9Sstevel@tonic-gate #ifdef LEAKCHK
392*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "creating value \"%s\"\n", val);
393*7c478bd9Sstevel@tonic-gate #endif
394*7c478bd9Sstevel@tonic-gate 	vn_p->name = strdup(val);
395*7c478bd9Sstevel@tonic-gate 
396*7c478bd9Sstevel@tonic-gate 	ret_pp = tfind((void *) vn_p, &an_p->valsroot_p, valscompare);
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 	if (ret_pp) {
399*7c478bd9Sstevel@tonic-gate 		/* we already had a node for this value */
400*7c478bd9Sstevel@tonic-gate #ifdef LEAKCHK
401*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "value already there \"%s\"\n", val);
402*7c478bd9Sstevel@tonic-gate #endif
403*7c478bd9Sstevel@tonic-gate 		if (vn_p->name)
404*7c478bd9Sstevel@tonic-gate 			free(vn_p->name);
405*7c478bd9Sstevel@tonic-gate 		free(vn_p);
406*7c478bd9Sstevel@tonic-gate 	} else {
407*7c478bd9Sstevel@tonic-gate 		(void) tsearch((void *) vn_p, &an_p->valsroot_p, valscompare);
408*7c478bd9Sstevel@tonic-gate 	}
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate }				/* end valadd */
412*7c478bd9Sstevel@tonic-gate 
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate /*
415*7c478bd9Sstevel@tonic-gate  * attrcompare() - compares attribute nodes, alphabetically
416*7c478bd9Sstevel@tonic-gate  */
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate static int
419*7c478bd9Sstevel@tonic-gate attrcompare(const void *node1,
420*7c478bd9Sstevel@tonic-gate 		const void *node2)
421*7c478bd9Sstevel@tonic-gate {
422*7c478bd9Sstevel@tonic-gate 	return strcmp(((attr_node_t *) node1)->name,
423*7c478bd9Sstevel@tonic-gate 		((attr_node_t *) node2)->name);
424*7c478bd9Sstevel@tonic-gate 
425*7c478bd9Sstevel@tonic-gate }				/* end attrcompare */
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate 
428*7c478bd9Sstevel@tonic-gate /*
429*7c478bd9Sstevel@tonic-gate  * valscompare() - compares attribute nodes, alphabetically
430*7c478bd9Sstevel@tonic-gate  */
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate static int
433*7c478bd9Sstevel@tonic-gate valscompare(const void *node1,
434*7c478bd9Sstevel@tonic-gate 		const void *node2)
435*7c478bd9Sstevel@tonic-gate {
436*7c478bd9Sstevel@tonic-gate 	return strcmp(((vals_node_t *) node1)->name,
437*7c478bd9Sstevel@tonic-gate 		((vals_node_t *) node2)->name);
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate }				/* end valscompare */
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate 
442*7c478bd9Sstevel@tonic-gate /*
443*7c478bd9Sstevel@tonic-gate  * printattrs() - prints attributes from the attr tree
444*7c478bd9Sstevel@tonic-gate  */
445*7c478bd9Sstevel@tonic-gate 
446*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
447*7c478bd9Sstevel@tonic-gate static void
448*7c478bd9Sstevel@tonic-gate printattrs(const void *node,
449*7c478bd9Sstevel@tonic-gate 	VISIT order,
450*7c478bd9Sstevel@tonic-gate 	int level)
451*7c478bd9Sstevel@tonic-gate {
452*7c478bd9Sstevel@tonic-gate 	attr_node_t	*an_p = (*(attr_node_t **) node);
453*7c478bd9Sstevel@tonic-gate 
454*7c478bd9Sstevel@tonic-gate 	if (order == postorder || order == leaf) {
455*7c478bd9Sstevel@tonic-gate 		(void) printf("%s =\n", an_p->name);
456*7c478bd9Sstevel@tonic-gate 		twalk(an_p->valsroot_p, printvals);
457*7c478bd9Sstevel@tonic-gate 	}
458*7c478bd9Sstevel@tonic-gate }				/* end printattrs */
459*7c478bd9Sstevel@tonic-gate 
460*7c478bd9Sstevel@tonic-gate 
461*7c478bd9Sstevel@tonic-gate /*
462*7c478bd9Sstevel@tonic-gate  * printvals() - prints values from a value tree
463*7c478bd9Sstevel@tonic-gate  */
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
466*7c478bd9Sstevel@tonic-gate static void
467*7c478bd9Sstevel@tonic-gate printvals(const void *node,
468*7c478bd9Sstevel@tonic-gate 	VISIT order,
469*7c478bd9Sstevel@tonic-gate 	int level)
470*7c478bd9Sstevel@tonic-gate {
471*7c478bd9Sstevel@tonic-gate 	vals_node_t	*vn_p = (*(vals_node_t **) node);
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate 	if (order == postorder || order == leaf)
474*7c478bd9Sstevel@tonic-gate 		(void) printf("	   %s\n", vn_p->name);
475*7c478bd9Sstevel@tonic-gate 
476*7c478bd9Sstevel@tonic-gate }				/* end printvals */
477*7c478bd9Sstevel@tonic-gate 
478*7c478bd9Sstevel@tonic-gate 
479*7c478bd9Sstevel@tonic-gate #if 0
480*7c478bd9Sstevel@tonic-gate /*
481*7c478bd9Sstevel@tonic-gate  * attrnodedel() - deletes an attr_node_t after the action
482*7c478bd9Sstevel@tonic-gate  */
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate static void
485*7c478bd9Sstevel@tonic-gate attrnodedel(attr_node_t * an_p)
486*7c478bd9Sstevel@tonic-gate {
487*7c478bd9Sstevel@tonic-gate 	if (an_p->name)
488*7c478bd9Sstevel@tonic-gate 		free(an_p->name);
489*7c478bd9Sstevel@tonic-gate 
490*7c478bd9Sstevel@tonic-gate 	/* destroy the value tree */
491*7c478bd9Sstevel@tonic-gate 	while (an_p->valsroot_p) {
492*7c478bd9Sstevel@tonic-gate 		vals_node_t   **ptr;
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate 		ptr = (vals_node_t **) an_p->valsroot_p;
495*7c478bd9Sstevel@tonic-gate 		(void) tdelete((void *) *ptr, &an_p->valsroot_p, valscompare);
496*7c478bd9Sstevel@tonic-gate 	}
497*7c478bd9Sstevel@tonic-gate 
498*7c478bd9Sstevel@tonic-gate 	/* We don't need to free this object, since tdelete() appears to */
499*7c478bd9Sstevel@tonic-gate 	/* free(an_p); */
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate }				/* end attrnodedel */
502*7c478bd9Sstevel@tonic-gate #endif
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 
505*7c478bd9Sstevel@tonic-gate /*
506*7c478bd9Sstevel@tonic-gate  * listprobe() - function used as a callback, pretty prints a probe
507*7c478bd9Sstevel@tonic-gate  */
508*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
509*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t
510*7c478bd9Sstevel@tonic-gate listprobe(tnfctl_handle_t *hndl, tnfctl_probe_t *ref_p, void *calldata_p)
511*7c478bd9Sstevel@tonic-gate {
512*7c478bd9Sstevel@tonic-gate 	static spec_t	*default_speclist = NULL;
513*7c478bd9Sstevel@tonic-gate 	list_probe_args_t *args_p = (list_probe_args_t *) calldata_p;
514*7c478bd9Sstevel@tonic-gate 	spec_t		*speclist_p;
515*7c478bd9Sstevel@tonic-gate 	spec_t		*spec_p;
516*7c478bd9Sstevel@tonic-gate 	boolean_t	sawattr;
517*7c478bd9Sstevel@tonic-gate 	char		*attrs;
518*7c478bd9Sstevel@tonic-gate 
519*7c478bd9Sstevel@tonic-gate 	/* build a default speclist if there is not one built already */
520*7c478bd9Sstevel@tonic-gate 	if (!default_speclist) {
521*7c478bd9Sstevel@tonic-gate 		default_speclist = spec_list(
522*7c478bd9Sstevel@tonic-gate 			spec_list(
523*7c478bd9Sstevel@tonic-gate 				spec_list(
524*7c478bd9Sstevel@tonic-gate 					spec_list(
525*7c478bd9Sstevel@tonic-gate 						spec_list(
526*7c478bd9Sstevel@tonic-gate 							spec("name",
527*7c478bd9Sstevel@tonic-gate 								SPEC_EXACT),
528*7c478bd9Sstevel@tonic-gate 							spec("enable",
529*7c478bd9Sstevel@tonic-gate 								SPEC_EXACT)),
530*7c478bd9Sstevel@tonic-gate 						spec("trace", SPEC_EXACT)),
531*7c478bd9Sstevel@tonic-gate 					spec("file", SPEC_EXACT)),
532*7c478bd9Sstevel@tonic-gate 				spec("line", SPEC_EXACT)),
533*7c478bd9Sstevel@tonic-gate 			spec("funcs", SPEC_EXACT));
534*7c478bd9Sstevel@tonic-gate 	}
535*7c478bd9Sstevel@tonic-gate 	attrs = list_getattrs(ref_p);
536*7c478bd9Sstevel@tonic-gate 
537*7c478bd9Sstevel@tonic-gate 	if (expr_match(args_p->exprlist_p, attrs)) {
538*7c478bd9Sstevel@tonic-gate 		speclist_p = args_p->speclist_p;
539*7c478bd9Sstevel@tonic-gate 		speclist_p = (speclist_p) ? speclist_p : default_speclist;
540*7c478bd9Sstevel@tonic-gate 
541*7c478bd9Sstevel@tonic-gate 		spec_p = NULL;
542*7c478bd9Sstevel@tonic-gate 		while (spec_p = (spec_t *)
543*7c478bd9Sstevel@tonic-gate 			queue_next(&speclist_p->qn, &spec_p->qn)) {
544*7c478bd9Sstevel@tonic-gate 			sawattr = B_FALSE;
545*7c478bd9Sstevel@tonic-gate 			spec_attrtrav(spec_p, attrs, printattrval, &sawattr);
546*7c478bd9Sstevel@tonic-gate 			if (!sawattr)
547*7c478bd9Sstevel@tonic-gate 				(void) printf("<no attr> ");
548*7c478bd9Sstevel@tonic-gate 		}
549*7c478bd9Sstevel@tonic-gate 		(void) printf("\n");
550*7c478bd9Sstevel@tonic-gate 	}
551*7c478bd9Sstevel@tonic-gate 	if (attrs)
552*7c478bd9Sstevel@tonic-gate 		free(attrs);
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate 	return (TNFCTL_ERR_NONE);
555*7c478bd9Sstevel@tonic-gate }
556*7c478bd9Sstevel@tonic-gate 
557*7c478bd9Sstevel@tonic-gate 
558*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
559*7c478bd9Sstevel@tonic-gate static void
560*7c478bd9Sstevel@tonic-gate printattrval(spec_t * spec_p,
561*7c478bd9Sstevel@tonic-gate 	char *attr,
562*7c478bd9Sstevel@tonic-gate 	char *value,
563*7c478bd9Sstevel@tonic-gate 	void *pdata)
564*7c478bd9Sstevel@tonic-gate {
565*7c478bd9Sstevel@tonic-gate 	boolean_t	  *bptr = (boolean_t *) pdata;
566*7c478bd9Sstevel@tonic-gate 
567*7c478bd9Sstevel@tonic-gate 	*bptr = B_TRUE;
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate 	(void) printf("%s=%s ", attr, (value && *value) ? value : "<no value>");
570*7c478bd9Sstevel@tonic-gate 
571*7c478bd9Sstevel@tonic-gate }				/* end printattrval */
572