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
list_set(spec_t * speclist_p,char * setname_p)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
list_expr(spec_t * speclist_p,expr_t * expr_p)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
list_values(spec_t * speclist_p)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 *
list_getattrs(tnfctl_probe_t * probe_p)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
probescan(tnfctl_handle_t * hndl,tnfctl_probe_t * ref_p,void * calldata_p)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
attrscan(spec_t * spec_p,char * attr,char * values,void * pdata)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
valadd(spec_t * spec_p,char * val,void * calldata_p)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
attrcompare(const void * node1,const void * node2)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
valscompare(const void * node1,const void * node2)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
printattrs(const void * node,VISIT order,int level)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
printvals(const void * node,VISIT order,int level)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
listprobe(tnfctl_handle_t * hndl,tnfctl_probe_t * ref_p,void * calldata_p)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
printattrval(spec_t * spec_p,char * attr,char * value,void * pdata)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