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