1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * This is the main program file for the configuration administration 31*0Sstevel@tonic-gate * command as set out in manual page cfgadm(1M). It uses the configuration 32*0Sstevel@tonic-gate * administration library interface, libcfgadm, as set out in manual 33*0Sstevel@tonic-gate * page config_admin(3X). 34*0Sstevel@tonic-gate */ 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate #include <stdio.h> 37*0Sstevel@tonic-gate #include <stdlib.h> 38*0Sstevel@tonic-gate #include <string.h> 39*0Sstevel@tonic-gate #include <locale.h> 40*0Sstevel@tonic-gate #include <langinfo.h> 41*0Sstevel@tonic-gate #include <time.h> 42*0Sstevel@tonic-gate #include <assert.h> 43*0Sstevel@tonic-gate #include <sys/types.h> 44*0Sstevel@tonic-gate #include <sys/stat.h> 45*0Sstevel@tonic-gate #include <sys/param.h> 46*0Sstevel@tonic-gate #include <sys/sunddi.h> 47*0Sstevel@tonic-gate #include <sys/openpromio.h> 48*0Sstevel@tonic-gate #include <sys/ddi_impldefs.h> 49*0Sstevel@tonic-gate #include <sys/systeminfo.h> 50*0Sstevel@tonic-gate #include <ctype.h> 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate #include <config_admin.h> 53*0Sstevel@tonic-gate #include "cfgadm.h" 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate #define S_FREE(x) (((x) != NULL) ? (free(x), (x) = NULL) : (void *)0) 56*0Sstevel@tonic-gate #define GET_DYN(a) (strstr((a), CFGA_DYN_SEP)) 57*0Sstevel@tonic-gate /* 58*0Sstevel@tonic-gate * forward declarations 59*0Sstevel@tonic-gate */ 60*0Sstevel@tonic-gate static char *basename(char *); 61*0Sstevel@tonic-gate static void cfgadm_error(int, char *); 62*0Sstevel@tonic-gate static int confirm_interactive(void *, const char *); 63*0Sstevel@tonic-gate static int confirm_no(void *, const char *); 64*0Sstevel@tonic-gate static int confirm_yes(void *, const char *); 65*0Sstevel@tonic-gate static void usage(void); 66*0Sstevel@tonic-gate static void usage_field(void); 67*0Sstevel@tonic-gate static int extract_list_suboptions(char *, char **, char **, char **, 68*0Sstevel@tonic-gate int *, char **, char **, char **); 69*0Sstevel@tonic-gate static int message_output(void *appdata_ptr, const char *message); 70*0Sstevel@tonic-gate static void *config_calloc_check(size_t, size_t); 71*0Sstevel@tonic-gate static cfga_ap_types_t find_arg_type(const char *); 72*0Sstevel@tonic-gate static int yesno(char *, char *); 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate static int compare_ap_id(cfga_list_data_t *, cfga_list_data_t *, match_type_t); 76*0Sstevel@tonic-gate static int compare_r_state(cfga_list_data_t *, cfga_list_data_t *, 77*0Sstevel@tonic-gate match_type_t); 78*0Sstevel@tonic-gate static int compare_o_state(cfga_list_data_t *, cfga_list_data_t *, 79*0Sstevel@tonic-gate match_type_t); 80*0Sstevel@tonic-gate static int compare_cond(cfga_list_data_t *, cfga_list_data_t *, match_type_t); 81*0Sstevel@tonic-gate static int compare_time(cfga_list_data_t *, cfga_list_data_t *, match_type_t); 82*0Sstevel@tonic-gate static int compare_info(cfga_list_data_t *, cfga_list_data_t *, match_type_t); 83*0Sstevel@tonic-gate static int compare_type(cfga_list_data_t *, cfga_list_data_t *, match_type_t); 84*0Sstevel@tonic-gate static int compare_busy(cfga_list_data_t *, cfga_list_data_t *, match_type_t); 85*0Sstevel@tonic-gate static int compare_class(cfga_list_data_t *, cfga_list_data_t *, match_type_t); 86*0Sstevel@tonic-gate static int compare_null(cfga_list_data_t *, cfga_list_data_t *, match_type_t); 87*0Sstevel@tonic-gate static void print_log_id(cfga_list_data_t *, int, char *); 88*0Sstevel@tonic-gate static void print_r_state(cfga_list_data_t *, int, char *); 89*0Sstevel@tonic-gate static void print_o_state(cfga_list_data_t *, int, char *); 90*0Sstevel@tonic-gate static void print_cond(cfga_list_data_t *, int, char *); 91*0Sstevel@tonic-gate static void print_time(cfga_list_data_t *, int, char *); 92*0Sstevel@tonic-gate static void print_time_p(cfga_list_data_t *, int, char *); 93*0Sstevel@tonic-gate static void print_info(cfga_list_data_t *, int, char *); 94*0Sstevel@tonic-gate static void print_type(cfga_list_data_t *, int, char *); 95*0Sstevel@tonic-gate static void print_busy(cfga_list_data_t *, int, char *); 96*0Sstevel@tonic-gate static void print_phys_id(cfga_list_data_t *, int, char *); 97*0Sstevel@tonic-gate static void print_class(cfga_list_data_t *, int, char *); 98*0Sstevel@tonic-gate static void print_null(cfga_list_data_t *, int, char *); 99*0Sstevel@tonic-gate static int count_fields(char *, char); 100*0Sstevel@tonic-gate static int process_sort_fields(int, struct sort_el *, char *); 101*0Sstevel@tonic-gate static int process_fields(int, struct print_col *, int, char *); 102*0Sstevel@tonic-gate static cfga_err_t print_fields(int, struct print_col *, int, int, char *, 103*0Sstevel@tonic-gate cfga_list_data_t *, FILE *); 104*0Sstevel@tonic-gate static int ldata_compare(const void *, const void *); 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate static void arg_got_resp(ap_arg_t *inp, ap_out_t *out_array, int nouts, 107*0Sstevel@tonic-gate int dyn_exp); 108*0Sstevel@tonic-gate static void out_was_req(ap_out_t *outp, ap_arg_t *in_array, int nargs, 109*0Sstevel@tonic-gate int no_dyn); 110*0Sstevel@tonic-gate static void report_no_response(ap_arg_t *arg_array, int napids_to_list); 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate static cfga_err_t set_log_flt(cfga_list_data_t *p, const char *val); 113*0Sstevel@tonic-gate static cfga_err_t set_type_flt(cfga_list_data_t *p, const char *val); 114*0Sstevel@tonic-gate static cfga_err_t set_class_flt(cfga_list_data_t *p, const char *val); 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate static char *get_dyn(const char *ap_id); 117*0Sstevel@tonic-gate static void remove_dyn(char *ap_id); 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate /* 120*0Sstevel@tonic-gate * global data 121*0Sstevel@tonic-gate */ 122*0Sstevel@tonic-gate /* command name for messages */ 123*0Sstevel@tonic-gate static char *cmdname; 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate /* 126*0Sstevel@tonic-gate * control for comparing, printing and filtering cfga_list_data 127*0Sstevel@tonic-gate * NOTE:Field names (i.e. member 0 of field_info struct) may not contain '('. 128*0Sstevel@tonic-gate * The post filtering code depends on it. 129*0Sstevel@tonic-gate * NOTE:A NULL value for the set_filter member indicates that filtering based 130*0Sstevel@tonic-gate * on that field is currently not supported. 131*0Sstevel@tonic-gate */ 132*0Sstevel@tonic-gate static struct field_info all_fields[] = { 133*0Sstevel@tonic-gate {"ap_id", "Ap_Id", SZ_EL(ap_log_id), compare_ap_id, print_log_id, set_log_flt}, 134*0Sstevel@tonic-gate {"r_state", "Receptacle", STATE_WIDTH, compare_r_state, print_r_state, NULL}, 135*0Sstevel@tonic-gate {"o_state", "Occupant", STATE_WIDTH, compare_o_state, print_o_state, NULL}, 136*0Sstevel@tonic-gate {"condition", "Condition", COND_WIDTH, compare_cond, print_cond, NULL}, 137*0Sstevel@tonic-gate {"status_time", "When", TIME_WIDTH, compare_time, print_time, NULL}, 138*0Sstevel@tonic-gate {"status_time_p", "When", TIME_P_WIDTH, compare_time, print_time_p, NULL}, 139*0Sstevel@tonic-gate {"info", "Information", SZ_EL(ap_info), compare_info, print_info, NULL}, 140*0Sstevel@tonic-gate {"type", "Type", SZ_EL(ap_type), compare_type, print_type, set_type_flt}, 141*0Sstevel@tonic-gate {"busy", "Busy", 8, compare_busy, print_busy, NULL}, 142*0Sstevel@tonic-gate {"physid", "Phys_Id", SZ_EL(ap_phys_id), compare_ap_id, print_phys_id, NULL}, 143*0Sstevel@tonic-gate {"class", "Class", SZ_EL(ap_class), compare_class, print_class, set_class_flt} 144*0Sstevel@tonic-gate }; 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate #define PREFILT_CLASS_STR "class=" 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate typedef struct { 149*0Sstevel@tonic-gate cfga_list_data_t ldata; /* Selection criteria */ 150*0Sstevel@tonic-gate match_type_t match_type_p[N_FIELDS]; /* Type of match */ 151*0Sstevel@tonic-gate } post_filter_t; 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate static struct field_info null_field = 154*0Sstevel@tonic-gate {"null", "", 0, compare_null, print_null, NULL}; 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate static struct sort_el *sort_list; /* Used in ldata_compare() */ 157*0Sstevel@tonic-gate static int nsort_list; 158*0Sstevel@tonic-gate static char unk_field[] = "%s: field \"%s\" unknown\n"; 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate static char aptype_no_dyn[] = "%s: Invalid ap_id: %s\n"; 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate /* strings that make up the usage message */ 163*0Sstevel@tonic-gate static char *usage_tab[] = { 164*0Sstevel@tonic-gate " %s [-f] [-y|-n] [-v] [-o hardware_opts ] -c function ap_id [ap_id...]\n", 165*0Sstevel@tonic-gate " %s [-f] [-y|-n] [-v] [-o hardware_opts ] -x function ap_id [ap_id...]\n", 166*0Sstevel@tonic-gate " %s [-v] [-s listing_options ] [-o hardware_opts ] [-a]\n" 167*0Sstevel@tonic-gate "\t[-l [ap_id|ap_type...]]\n", 168*0Sstevel@tonic-gate " %s [-v] [-o hardware_opts ] -t ap_id [ap_id...]\n", 169*0Sstevel@tonic-gate " %s [-v] [-o hardware_opts ] -h [ap_id|ap_type...]\n", 170*0Sstevel@tonic-gate }; 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate /* Type of matches currently supported by the select sub-option */ 173*0Sstevel@tonic-gate static match_cvt_t match_type_array[] = { 174*0Sstevel@tonic-gate {"partial", CFGA_MATCH_PARTIAL}, 175*0Sstevel@tonic-gate {"exact", CFGA_MATCH_EXACT} 176*0Sstevel@tonic-gate }; 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate #define N_MATCH_TYPES (sizeof (match_type_array)/sizeof (match_type_array[0])) 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate static cfga_err_t setup_filter(const char *selectp, const char *matchp, 181*0Sstevel@tonic-gate post_filter_t *post_filtp, char **prefilt_optpp); 182*0Sstevel@tonic-gate static cfga_err_t parse_select_opt(const char *selectp, 183*0Sstevel@tonic-gate post_filter_t *post_filtp, match_type_t match_type); 184*0Sstevel@tonic-gate static int do_config_list(int, char *[], cfga_list_data_t *, int, char *, 185*0Sstevel@tonic-gate char *, char *, int, char *, post_filter_t *, int); 186*0Sstevel@tonic-gate static void do_post_filter(ap_out_t *outp, post_filter_t *post_filtp, int *jp); 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate /* 190*0Sstevel@tonic-gate * main - the main routine of cfgadm, processes the command line 191*0Sstevel@tonic-gate * and dispatches functions off to libraries. 192*0Sstevel@tonic-gate */ 193*0Sstevel@tonic-gate void 194*0Sstevel@tonic-gate main( 195*0Sstevel@tonic-gate int argc, 196*0Sstevel@tonic-gate char *argv[]) 197*0Sstevel@tonic-gate { 198*0Sstevel@tonic-gate extern char *optarg; 199*0Sstevel@tonic-gate extern int optind; 200*0Sstevel@tonic-gate int c; 201*0Sstevel@tonic-gate char *subopts; 202*0Sstevel@tonic-gate char *subvalue; 203*0Sstevel@tonic-gate char *const *ap_args = NULL; 204*0Sstevel@tonic-gate cfga_cmd_t sc_opt = NULL; 205*0Sstevel@tonic-gate struct cfga_confirm confirm; 206*0Sstevel@tonic-gate struct cfga_msg message; 207*0Sstevel@tonic-gate int ret = CFGA_ERROR; 208*0Sstevel@tonic-gate int i; 209*0Sstevel@tonic-gate char *estrp = NULL; 210*0Sstevel@tonic-gate cfga_op_t action = CFGA_OP_NONE; 211*0Sstevel@tonic-gate char *plat_opts = NULL; 212*0Sstevel@tonic-gate char *act_arg = NULL; 213*0Sstevel@tonic-gate enum confirm confarg = CONFIRM_DEFAULT; 214*0Sstevel@tonic-gate char *list_opts = NULL; 215*0Sstevel@tonic-gate cfga_flags_t flags = 0; 216*0Sstevel@tonic-gate int arg_error = 0; 217*0Sstevel@tonic-gate int dyn_exp = 0; 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate estrp = NULL; 220*0Sstevel@tonic-gate if (argc > 0) 221*0Sstevel@tonic-gate cmdname = basename(argv[0]); 222*0Sstevel@tonic-gate else 223*0Sstevel@tonic-gate cmdname = "cfgadm"; 224*0Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 225*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 226*0Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 227*0Sstevel@tonic-gate #endif 228*0Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate while ((c = getopt(argc, argv, OPTIONS)) != EOF) { 231*0Sstevel@tonic-gate static char dup_action[] = 232*0Sstevel@tonic-gate "%s: more than one action specified (-c,-l,-t,-x)\n"; 233*0Sstevel@tonic-gate static char dup_option[] = 234*0Sstevel@tonic-gate "%s: more than one -%c option specified\n"; 235*0Sstevel@tonic-gate switch (c) { 236*0Sstevel@tonic-gate case 'a': 237*0Sstevel@tonic-gate if (dyn_exp) { 238*0Sstevel@tonic-gate arg_error = 1; 239*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_option), 240*0Sstevel@tonic-gate cmdname, c); 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate dyn_exp = 1; 243*0Sstevel@tonic-gate break; 244*0Sstevel@tonic-gate case 'c': 245*0Sstevel@tonic-gate if (action != CFGA_OP_NONE) { 246*0Sstevel@tonic-gate arg_error = 1; 247*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_action), 248*0Sstevel@tonic-gate cmdname); 249*0Sstevel@tonic-gate } 250*0Sstevel@tonic-gate action = CFGA_OP_CHANGE_STATE; 251*0Sstevel@tonic-gate subopts = optarg; 252*0Sstevel@tonic-gate subvalue = NULL; 253*0Sstevel@tonic-gate /* 254*0Sstevel@tonic-gate * Reject -c suboption if they are unrecognized 255*0Sstevel@tonic-gate * or more than one or have a associated value. 256*0Sstevel@tonic-gate */ 257*0Sstevel@tonic-gate if ((sc_opt = getsubopt(&subopts, state_opts, 258*0Sstevel@tonic-gate &subvalue)) == -1 || *subopts != '\0' || 259*0Sstevel@tonic-gate subvalue != NULL) { 260*0Sstevel@tonic-gate arg_error = 1; 261*0Sstevel@tonic-gate break; 262*0Sstevel@tonic-gate } 263*0Sstevel@tonic-gate break; 264*0Sstevel@tonic-gate case 'f': 265*0Sstevel@tonic-gate if ((flags & CFGA_FLAG_FORCE) != 0) { 266*0Sstevel@tonic-gate arg_error = 1; 267*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_option), 268*0Sstevel@tonic-gate cmdname, c); 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate flags |= CFGA_FLAG_FORCE; 271*0Sstevel@tonic-gate break; 272*0Sstevel@tonic-gate case 'h': 273*0Sstevel@tonic-gate if (action != CFGA_OP_NONE) { 274*0Sstevel@tonic-gate arg_error = 1; 275*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_action), 276*0Sstevel@tonic-gate cmdname); 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate action = CFGA_OP_HELP; 279*0Sstevel@tonic-gate break; 280*0Sstevel@tonic-gate case 'l': 281*0Sstevel@tonic-gate if (action != CFGA_OP_NONE) { 282*0Sstevel@tonic-gate arg_error = 1; 283*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_action), 284*0Sstevel@tonic-gate cmdname); 285*0Sstevel@tonic-gate } 286*0Sstevel@tonic-gate action = CFGA_OP_LIST; 287*0Sstevel@tonic-gate break; 288*0Sstevel@tonic-gate case 'n': 289*0Sstevel@tonic-gate if (confarg != CONFIRM_DEFAULT) { 290*0Sstevel@tonic-gate arg_error = 1; 291*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_option), 292*0Sstevel@tonic-gate cmdname, c); 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate confarg = CONFIRM_NO; 295*0Sstevel@tonic-gate break; 296*0Sstevel@tonic-gate case 'o': 297*0Sstevel@tonic-gate if (plat_opts != NULL) { 298*0Sstevel@tonic-gate arg_error = 1; 299*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_option), 300*0Sstevel@tonic-gate cmdname, c); 301*0Sstevel@tonic-gate } 302*0Sstevel@tonic-gate plat_opts = optarg; 303*0Sstevel@tonic-gate break; 304*0Sstevel@tonic-gate case 's': 305*0Sstevel@tonic-gate if (list_opts != NULL) { 306*0Sstevel@tonic-gate arg_error = 1; 307*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_option), 308*0Sstevel@tonic-gate cmdname, c); 309*0Sstevel@tonic-gate } 310*0Sstevel@tonic-gate list_opts = optarg; 311*0Sstevel@tonic-gate break; 312*0Sstevel@tonic-gate case 't': 313*0Sstevel@tonic-gate if (action != CFGA_OP_NONE) { 314*0Sstevel@tonic-gate arg_error = 1; 315*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_action), 316*0Sstevel@tonic-gate cmdname); 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate action = CFGA_OP_TEST; 319*0Sstevel@tonic-gate break; 320*0Sstevel@tonic-gate case 'x': 321*0Sstevel@tonic-gate if (action != CFGA_OP_NONE) { 322*0Sstevel@tonic-gate arg_error = 1; 323*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_action), 324*0Sstevel@tonic-gate cmdname); 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate action = CFGA_OP_PRIVATE; 327*0Sstevel@tonic-gate act_arg = optarg; 328*0Sstevel@tonic-gate break; 329*0Sstevel@tonic-gate case 'v': 330*0Sstevel@tonic-gate if ((flags & CFGA_FLAG_VERBOSE) != 0) { 331*0Sstevel@tonic-gate arg_error = 1; 332*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_option), 333*0Sstevel@tonic-gate cmdname, c); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate flags |= CFGA_FLAG_VERBOSE; 336*0Sstevel@tonic-gate break; 337*0Sstevel@tonic-gate case 'y': 338*0Sstevel@tonic-gate if (confarg != CONFIRM_DEFAULT) { 339*0Sstevel@tonic-gate arg_error = 1; 340*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(dup_option), 341*0Sstevel@tonic-gate cmdname, c); 342*0Sstevel@tonic-gate } 343*0Sstevel@tonic-gate confarg = CONFIRM_YES; 344*0Sstevel@tonic-gate break; 345*0Sstevel@tonic-gate case '?': /* getopts issues message is this case */ 346*0Sstevel@tonic-gate default: /* catch programming errors */ 347*0Sstevel@tonic-gate arg_error = 1; 348*0Sstevel@tonic-gate break; 349*0Sstevel@tonic-gate } 350*0Sstevel@tonic-gate } 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate /* default action is list */ 353*0Sstevel@tonic-gate if (action == CFGA_OP_NONE) 354*0Sstevel@tonic-gate action = CFGA_OP_LIST; 355*0Sstevel@tonic-gate 356*0Sstevel@tonic-gate /* -s and -a option only for list */ 357*0Sstevel@tonic-gate if (action != CFGA_OP_LIST && (list_opts != NULL || dyn_exp)) { 358*0Sstevel@tonic-gate arg_error = 1; 359*0Sstevel@tonic-gate } 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate if (arg_error) { 362*0Sstevel@tonic-gate usage(); 363*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 364*0Sstevel@tonic-gate /*NOTREACHED*/ 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate ap_args = &argv[optind]; 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate /* 370*0Sstevel@tonic-gate * If neither -n of -y was specified, interactive confirmation 371*0Sstevel@tonic-gate * is used. Check if the program has terminal I/O and 372*0Sstevel@tonic-gate * enforce -n if not. 373*0Sstevel@tonic-gate */ 374*0Sstevel@tonic-gate (void) memset(&confirm, 0, sizeof (confirm)); 375*0Sstevel@tonic-gate if (action == CFGA_OP_CHANGE_STATE || action == CFGA_OP_PRIVATE) { 376*0Sstevel@tonic-gate if (confarg == CONFIRM_DEFAULT && 377*0Sstevel@tonic-gate !(isatty(fileno(stdin)) && isatty(fileno(stderr)))) 378*0Sstevel@tonic-gate confarg = CONFIRM_NO; 379*0Sstevel@tonic-gate switch (confarg) { 380*0Sstevel@tonic-gate case CONFIRM_DEFAULT: 381*0Sstevel@tonic-gate confirm.confirm = confirm_interactive; 382*0Sstevel@tonic-gate break; 383*0Sstevel@tonic-gate case CONFIRM_NO: 384*0Sstevel@tonic-gate confirm.confirm = confirm_no; 385*0Sstevel@tonic-gate break; 386*0Sstevel@tonic-gate case CONFIRM_YES: 387*0Sstevel@tonic-gate confirm.confirm = confirm_yes; 388*0Sstevel@tonic-gate break; 389*0Sstevel@tonic-gate default: /* paranoia */ 390*0Sstevel@tonic-gate abort(); 391*0Sstevel@tonic-gate /*NOTREACHED*/ 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate } 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gate /* 396*0Sstevel@tonic-gate * set up message output routine 397*0Sstevel@tonic-gate */ 398*0Sstevel@tonic-gate message.message_routine = message_output; 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate switch (action) { 401*0Sstevel@tonic-gate case CFGA_OP_CHANGE_STATE: 402*0Sstevel@tonic-gate /* Sanity check - requires an argument */ 403*0Sstevel@tonic-gate if ((argc - optind) <= 0) { 404*0Sstevel@tonic-gate usage(); 405*0Sstevel@tonic-gate break; 406*0Sstevel@tonic-gate } 407*0Sstevel@tonic-gate /* Sanity check - args cannot be ap_types */ 408*0Sstevel@tonic-gate for (i = 0; i < (argc - optind); i++) { 409*0Sstevel@tonic-gate if (find_arg_type(ap_args[i]) == AP_TYPE) { 410*0Sstevel@tonic-gate usage(); 411*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 412*0Sstevel@tonic-gate /*NOTREACHED*/ 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate } 415*0Sstevel@tonic-gate ret = config_change_state(sc_opt, argc - optind, ap_args, plat_opts, 416*0Sstevel@tonic-gate &confirm, &message, &estrp, flags); 417*0Sstevel@tonic-gate if (ret != CFGA_OK) 418*0Sstevel@tonic-gate cfgadm_error(ret, estrp); 419*0Sstevel@tonic-gate break; 420*0Sstevel@tonic-gate case CFGA_OP_PRIVATE: 421*0Sstevel@tonic-gate /* Sanity check - requires an argument */ 422*0Sstevel@tonic-gate if ((argc - optind) <= 0) { 423*0Sstevel@tonic-gate usage(); 424*0Sstevel@tonic-gate break; 425*0Sstevel@tonic-gate } 426*0Sstevel@tonic-gate /* Sanity check - args cannot be ap_types */ 427*0Sstevel@tonic-gate for (i = 0; i < (argc - optind); i++) { 428*0Sstevel@tonic-gate if (find_arg_type(ap_args[i]) == AP_TYPE) { 429*0Sstevel@tonic-gate usage(); 430*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 431*0Sstevel@tonic-gate /*NOTREACHED*/ 432*0Sstevel@tonic-gate } 433*0Sstevel@tonic-gate } 434*0Sstevel@tonic-gate 435*0Sstevel@tonic-gate ret = config_private_func(act_arg, argc - optind, ap_args, 436*0Sstevel@tonic-gate plat_opts, &confirm, &message, &estrp, flags); 437*0Sstevel@tonic-gate 438*0Sstevel@tonic-gate if (ret != CFGA_OK) 439*0Sstevel@tonic-gate cfgadm_error(ret, estrp); 440*0Sstevel@tonic-gate break; 441*0Sstevel@tonic-gate case CFGA_OP_TEST: 442*0Sstevel@tonic-gate /* Sanity check - requires an argument */ 443*0Sstevel@tonic-gate if ((argc - optind) <= 0) { 444*0Sstevel@tonic-gate usage(); 445*0Sstevel@tonic-gate break; 446*0Sstevel@tonic-gate } 447*0Sstevel@tonic-gate 448*0Sstevel@tonic-gate if ((flags & ~CFGA_FLAG_VERBOSE) != 0) { 449*0Sstevel@tonic-gate usage(); 450*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 451*0Sstevel@tonic-gate /*NOTREACHED*/ 452*0Sstevel@tonic-gate } 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate /* Sanity check - args cannot be ap_types */ 455*0Sstevel@tonic-gate for (i = 0; i < (argc - optind); i++) { 456*0Sstevel@tonic-gate if (find_arg_type(ap_args[i]) == AP_TYPE) { 457*0Sstevel@tonic-gate usage(); 458*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 459*0Sstevel@tonic-gate /*NOTREACHED*/ 460*0Sstevel@tonic-gate } 461*0Sstevel@tonic-gate } 462*0Sstevel@tonic-gate ret = config_test(argc - optind, ap_args, plat_opts, &message, 463*0Sstevel@tonic-gate &estrp, flags); 464*0Sstevel@tonic-gate if (ret != CFGA_OK) 465*0Sstevel@tonic-gate cfgadm_error(ret, estrp); 466*0Sstevel@tonic-gate break; 467*0Sstevel@tonic-gate case CFGA_OP_HELP: 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate if ((flags & ~CFGA_FLAG_VERBOSE) != 0) { 470*0Sstevel@tonic-gate usage(); 471*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 472*0Sstevel@tonic-gate /*NOTREACHED*/ 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate /* always do usage? */ 476*0Sstevel@tonic-gate usage(); 477*0Sstevel@tonic-gate ret = config_help(argc - optind, ap_args, &message, plat_opts, 478*0Sstevel@tonic-gate flags); 479*0Sstevel@tonic-gate if (ret != CFGA_OK) 480*0Sstevel@tonic-gate cfgadm_error(ret, estrp); 481*0Sstevel@tonic-gate break; 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate case CFGA_OP_LIST: { 484*0Sstevel@tonic-gate cfga_list_data_t *list_array = NULL; 485*0Sstevel@tonic-gate int nlist = 0; 486*0Sstevel@tonic-gate char *sort_fields = DEF_SORT_FIELDS; 487*0Sstevel@tonic-gate char *cols = DEF_COLS; 488*0Sstevel@tonic-gate char *cols2 = DEF_COLS2; 489*0Sstevel@tonic-gate int noheadings = 0; 490*0Sstevel@tonic-gate char *delim = DEF_DELIM; 491*0Sstevel@tonic-gate int exitcode = EXIT_OK; 492*0Sstevel@tonic-gate int i; 493*0Sstevel@tonic-gate int type = 0; 494*0Sstevel@tonic-gate char *selectp = NULL, *matchp = NULL, *prefilt_optp = NULL; 495*0Sstevel@tonic-gate post_filter_t *post_filtp = NULL; 496*0Sstevel@tonic-gate 497*0Sstevel@tonic-gate if ((flags & ~CFGA_FLAG_VERBOSE) != 0) { 498*0Sstevel@tonic-gate usage(); 499*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 500*0Sstevel@tonic-gate /*NOTREACHED*/ 501*0Sstevel@tonic-gate } 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate if (flags & CFGA_FLAG_VERBOSE) { 504*0Sstevel@tonic-gate cols = DEF_COLS_VERBOSE; 505*0Sstevel@tonic-gate cols2 = DEF_COLS2_VERBOSE; 506*0Sstevel@tonic-gate } 507*0Sstevel@tonic-gate 508*0Sstevel@tonic-gate if (list_opts != NULL && !extract_list_suboptions(list_opts, 509*0Sstevel@tonic-gate &sort_fields, &cols, &cols2, &noheadings, &delim, 510*0Sstevel@tonic-gate &selectp, &matchp)) { 511*0Sstevel@tonic-gate usage_field(); 512*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 513*0Sstevel@tonic-gate /*NOTREACHED*/ 514*0Sstevel@tonic-gate } 515*0Sstevel@tonic-gate 516*0Sstevel@tonic-gate /* 517*0Sstevel@tonic-gate * Scan any args and see if there are any ap_types. 518*0Sstevel@tonic-gate * If there are we get all attachment point stats and 519*0Sstevel@tonic-gate * then filter what gets printed. 520*0Sstevel@tonic-gate */ 521*0Sstevel@tonic-gate 522*0Sstevel@tonic-gate type = 0; 523*0Sstevel@tonic-gate for (i = 0; i < (argc - optind); i++) { 524*0Sstevel@tonic-gate if (find_arg_type(ap_args[i]) == AP_TYPE) { 525*0Sstevel@tonic-gate type = 1; 526*0Sstevel@tonic-gate /* ap_types cannot have dynamic components */ 527*0Sstevel@tonic-gate if (get_dyn(ap_args[i]) != NULL) { 528*0Sstevel@tonic-gate (void) fprintf(stderr, 529*0Sstevel@tonic-gate gettext(aptype_no_dyn), 530*0Sstevel@tonic-gate cmdname, ap_args[i]); 531*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 532*0Sstevel@tonic-gate /*NOTREACHED*/ 533*0Sstevel@tonic-gate } 534*0Sstevel@tonic-gate break; 535*0Sstevel@tonic-gate } 536*0Sstevel@tonic-gate } 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gate /* Setup filter */ 539*0Sstevel@tonic-gate post_filtp = config_calloc_check(1, sizeof (*post_filtp)); 540*0Sstevel@tonic-gate if (post_filtp == NULL) { 541*0Sstevel@tonic-gate exit(EXIT_OPFAILED); 542*0Sstevel@tonic-gate /*NOTREACHED*/ 543*0Sstevel@tonic-gate } 544*0Sstevel@tonic-gate if (setup_filter(selectp, matchp, post_filtp, &prefilt_optp) 545*0Sstevel@tonic-gate != CFGA_OK) { 546*0Sstevel@tonic-gate S_FREE(post_filtp); 547*0Sstevel@tonic-gate exit(EXIT_ARGERROR); 548*0Sstevel@tonic-gate /*NOTREACHED*/ 549*0Sstevel@tonic-gate } 550*0Sstevel@tonic-gate 551*0Sstevel@tonic-gate list_array = NULL; 552*0Sstevel@tonic-gate exitcode = EXIT_OK; 553*0Sstevel@tonic-gate 554*0Sstevel@tonic-gate /* 555*0Sstevel@tonic-gate * Check for args. No args means find all libs 556*0Sstevel@tonic-gate * and call the cfga_list_ext routine with no ap_ids specified. 557*0Sstevel@tonic-gate * With args, if any one of the args are ap_types we 558*0Sstevel@tonic-gate * again find all attachment points as in the 559*0Sstevel@tonic-gate * no-args case above and then select which attachment points 560*0Sstevel@tonic-gate * are actually displayed. 561*0Sstevel@tonic-gate */ 562*0Sstevel@tonic-gate if (((argc - optind) == 0) || (type == 1)) { 563*0Sstevel@tonic-gate /* 564*0Sstevel@tonic-gate * No args, or atleast 1 ap_type arg 565*0Sstevel@tonic-gate */ 566*0Sstevel@tonic-gate ret = config_list_ext(0, NULL, &list_array, 567*0Sstevel@tonic-gate &nlist, plat_opts, prefilt_optp, &estrp, 568*0Sstevel@tonic-gate dyn_exp ? CFGA_FLAG_LIST_ALL : 0); 569*0Sstevel@tonic-gate } else { 570*0Sstevel@tonic-gate /* 571*0Sstevel@tonic-gate * If the args are all ap_ids (no ap_types) we call the 572*0Sstevel@tonic-gate * cfga_list_ext routine with those specific ap_ids. 573*0Sstevel@tonic-gate */ 574*0Sstevel@tonic-gate ret = config_list_ext(argc - optind, ap_args, 575*0Sstevel@tonic-gate &list_array, &nlist, plat_opts, prefilt_optp, 576*0Sstevel@tonic-gate &estrp, dyn_exp ? CFGA_FLAG_LIST_ALL : 0); 577*0Sstevel@tonic-gate } 578*0Sstevel@tonic-gate 579*0Sstevel@tonic-gate S_FREE(prefilt_optp); 580*0Sstevel@tonic-gate 581*0Sstevel@tonic-gate if (ret == CFGA_OK) { 582*0Sstevel@tonic-gate 583*0Sstevel@tonic-gate if (do_config_list( 584*0Sstevel@tonic-gate (argc - optind), &argv[optind], list_array, nlist, 585*0Sstevel@tonic-gate sort_fields, cols, cols2, noheadings, delim, 586*0Sstevel@tonic-gate post_filtp, dyn_exp) != CFGA_OK) { 587*0Sstevel@tonic-gate exitcode = EXIT_ARGERROR; 588*0Sstevel@tonic-gate } else { 589*0Sstevel@tonic-gate exitcode = EXIT_OK; 590*0Sstevel@tonic-gate } 591*0Sstevel@tonic-gate 592*0Sstevel@tonic-gate S_FREE(list_array); 593*0Sstevel@tonic-gate S_FREE(post_filtp); 594*0Sstevel@tonic-gate 595*0Sstevel@tonic-gate if (exitcode != EXIT_OK) { 596*0Sstevel@tonic-gate exit(exitcode); 597*0Sstevel@tonic-gate /*NOTREACHED*/ 598*0Sstevel@tonic-gate } 599*0Sstevel@tonic-gate } else { 600*0Sstevel@tonic-gate 601*0Sstevel@tonic-gate S_FREE(post_filtp); 602*0Sstevel@tonic-gate cfgadm_error(ret, estrp); 603*0Sstevel@tonic-gate } 604*0Sstevel@tonic-gate break; 605*0Sstevel@tonic-gate } 606*0Sstevel@tonic-gate default: /* paranoia */ 607*0Sstevel@tonic-gate abort(); 608*0Sstevel@tonic-gate /*NOTREACHED*/ 609*0Sstevel@tonic-gate } 610*0Sstevel@tonic-gate 611*0Sstevel@tonic-gate if (ret == CFGA_NOTSUPP) { 612*0Sstevel@tonic-gate exit(EXIT_NOTSUPP); 613*0Sstevel@tonic-gate } else if (ret != CFGA_OK) { 614*0Sstevel@tonic-gate exit(EXIT_OPFAILED); 615*0Sstevel@tonic-gate } else { 616*0Sstevel@tonic-gate exit(EXIT_OK); 617*0Sstevel@tonic-gate } 618*0Sstevel@tonic-gate /*NOTREACHED*/ 619*0Sstevel@tonic-gate } 620*0Sstevel@tonic-gate 621*0Sstevel@tonic-gate /* 622*0Sstevel@tonic-gate * usage - outputs the usage help message. 623*0Sstevel@tonic-gate */ 624*0Sstevel@tonic-gate static void 625*0Sstevel@tonic-gate usage( 626*0Sstevel@tonic-gate void) 627*0Sstevel@tonic-gate { 628*0Sstevel@tonic-gate int i; 629*0Sstevel@tonic-gate 630*0Sstevel@tonic-gate (void) fprintf(stderr, "%s\n", gettext("Usage:")); 631*0Sstevel@tonic-gate for (i = 0; i < sizeof (usage_tab)/sizeof (usage_tab[0]); i++) { 632*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(usage_tab[i]), cmdname); 633*0Sstevel@tonic-gate } 634*0Sstevel@tonic-gate } 635*0Sstevel@tonic-gate 636*0Sstevel@tonic-gate /* 637*0Sstevel@tonic-gate * Emit an error message. 638*0Sstevel@tonic-gate * As a side-effect the hardware specific error message is deallocated 639*0Sstevel@tonic-gate * as described in config_admin(3X). 640*0Sstevel@tonic-gate */ 641*0Sstevel@tonic-gate static void 642*0Sstevel@tonic-gate cfgadm_error(int errnum, char *estrp) 643*0Sstevel@tonic-gate { 644*0Sstevel@tonic-gate const char *ep; 645*0Sstevel@tonic-gate 646*0Sstevel@tonic-gate ep = config_strerror(errnum); 647*0Sstevel@tonic-gate if (ep == NULL) 648*0Sstevel@tonic-gate ep = gettext("configuration administration unknown error"); 649*0Sstevel@tonic-gate if (estrp != NULL && *estrp != '\0') { 650*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: %s\n", cmdname, ep, estrp); 651*0Sstevel@tonic-gate } else { 652*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s\n", cmdname, ep); 653*0Sstevel@tonic-gate } 654*0Sstevel@tonic-gate if (estrp != NULL) 655*0Sstevel@tonic-gate free((void *)estrp); 656*0Sstevel@tonic-gate if (errnum == CFGA_INVAL) 657*0Sstevel@tonic-gate usage(); 658*0Sstevel@tonic-gate } 659*0Sstevel@tonic-gate 660*0Sstevel@tonic-gate /* 661*0Sstevel@tonic-gate * confirm_interactive - prompt user for confirmation 662*0Sstevel@tonic-gate */ 663*0Sstevel@tonic-gate static int 664*0Sstevel@tonic-gate confirm_interactive( 665*0Sstevel@tonic-gate void *appdata_ptr, 666*0Sstevel@tonic-gate const char *message) 667*0Sstevel@tonic-gate { 668*0Sstevel@tonic-gate static char yeschr[YESNO_STR_MAX + 2]; 669*0Sstevel@tonic-gate static char nochr[YESNO_STR_MAX + 2]; 670*0Sstevel@tonic-gate static int inited = 0; 671*0Sstevel@tonic-gate int isyes; 672*0Sstevel@tonic-gate 673*0Sstevel@tonic-gate #ifdef lint 674*0Sstevel@tonic-gate appdata_ptr = appdata_ptr; 675*0Sstevel@tonic-gate #endif /* lint */ 676*0Sstevel@tonic-gate /* 677*0Sstevel@tonic-gate * First time through initialisation. In the original 678*0Sstevel@tonic-gate * version of this command this function is only called once, 679*0Sstevel@tonic-gate * but this function is generalized for the future. 680*0Sstevel@tonic-gate */ 681*0Sstevel@tonic-gate if (!inited) { 682*0Sstevel@tonic-gate (void) strncpy(yeschr, nl_langinfo(YESSTR), YESNO_STR_MAX + 1); 683*0Sstevel@tonic-gate (void) strncpy(nochr, nl_langinfo(NOSTR), YESNO_STR_MAX + 1); 684*0Sstevel@tonic-gate inited = 1; 685*0Sstevel@tonic-gate } 686*0Sstevel@tonic-gate 687*0Sstevel@tonic-gate do { 688*0Sstevel@tonic-gate (void) fprintf(stderr, "%s (%s/%s)? ", message, yeschr, nochr); 689*0Sstevel@tonic-gate isyes = yesno(yeschr, nochr); 690*0Sstevel@tonic-gate } while (isyes == -1); 691*0Sstevel@tonic-gate return (isyes); 692*0Sstevel@tonic-gate } 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gate /* 695*0Sstevel@tonic-gate * If any text is input it must sub-string match either yes or no. 696*0Sstevel@tonic-gate * Failure of this match is indicated by return of -1. 697*0Sstevel@tonic-gate * If an empty line is input, this is taken as no. 698*0Sstevel@tonic-gate */ 699*0Sstevel@tonic-gate static int 700*0Sstevel@tonic-gate yesno( 701*0Sstevel@tonic-gate char *yesp, 702*0Sstevel@tonic-gate char *nop) 703*0Sstevel@tonic-gate { 704*0Sstevel@tonic-gate int i, b; 705*0Sstevel@tonic-gate char ans[YESNO_STR_MAX + 1]; 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate i = 0; 708*0Sstevel@tonic-gate 709*0Sstevel@tonic-gate /*CONSTCOND*/ 710*0Sstevel@tonic-gate while (1) { 711*0Sstevel@tonic-gate b = getc(stdin); /* more explicit that rm.c version */ 712*0Sstevel@tonic-gate if (b == '\n' || b == '\0' || b == EOF) { 713*0Sstevel@tonic-gate if (i < YESNO_STR_MAX) /* bug fix to rm.c version */ 714*0Sstevel@tonic-gate ans[i] = 0; 715*0Sstevel@tonic-gate break; 716*0Sstevel@tonic-gate } 717*0Sstevel@tonic-gate if (i < YESNO_STR_MAX) 718*0Sstevel@tonic-gate ans[i] = b; 719*0Sstevel@tonic-gate i++; 720*0Sstevel@tonic-gate } 721*0Sstevel@tonic-gate if (i >= YESNO_STR_MAX) { 722*0Sstevel@tonic-gate i = YESNO_STR_MAX; 723*0Sstevel@tonic-gate ans[YESNO_STR_MAX] = 0; 724*0Sstevel@tonic-gate } 725*0Sstevel@tonic-gate /* changes to rm.c version follow */ 726*0Sstevel@tonic-gate if (i == 0) 727*0Sstevel@tonic-gate return (0); 728*0Sstevel@tonic-gate if (strncmp(nop, ans, i) == 0) 729*0Sstevel@tonic-gate return (0); 730*0Sstevel@tonic-gate if (strncmp(yesp, ans, i) == 0) 731*0Sstevel@tonic-gate return (1); 732*0Sstevel@tonic-gate return (-1); 733*0Sstevel@tonic-gate } 734*0Sstevel@tonic-gate 735*0Sstevel@tonic-gate /*ARGSUSED*/ 736*0Sstevel@tonic-gate static int 737*0Sstevel@tonic-gate confirm_no( 738*0Sstevel@tonic-gate void *appdata_ptr, 739*0Sstevel@tonic-gate const char *message) 740*0Sstevel@tonic-gate { 741*0Sstevel@tonic-gate return (0); 742*0Sstevel@tonic-gate } 743*0Sstevel@tonic-gate 744*0Sstevel@tonic-gate /*ARGSUSED*/ 745*0Sstevel@tonic-gate static int 746*0Sstevel@tonic-gate confirm_yes( 747*0Sstevel@tonic-gate void *appdata_ptr, 748*0Sstevel@tonic-gate const char *message) 749*0Sstevel@tonic-gate { 750*0Sstevel@tonic-gate return (1); 751*0Sstevel@tonic-gate } 752*0Sstevel@tonic-gate 753*0Sstevel@tonic-gate /* 754*0Sstevel@tonic-gate * Find base name of filename. 755*0Sstevel@tonic-gate */ 756*0Sstevel@tonic-gate static char * 757*0Sstevel@tonic-gate basename( 758*0Sstevel@tonic-gate char *cp) 759*0Sstevel@tonic-gate { 760*0Sstevel@tonic-gate char *sp; 761*0Sstevel@tonic-gate 762*0Sstevel@tonic-gate if ((sp = strrchr(cp, '/')) != NULL) 763*0Sstevel@tonic-gate return (sp + 1); 764*0Sstevel@tonic-gate return (cp); 765*0Sstevel@tonic-gate } 766*0Sstevel@tonic-gate 767*0Sstevel@tonic-gate /*ARGSUSED*/ 768*0Sstevel@tonic-gate static int 769*0Sstevel@tonic-gate message_output( 770*0Sstevel@tonic-gate void *appdata_ptr, 771*0Sstevel@tonic-gate const char *message) 772*0Sstevel@tonic-gate { 773*0Sstevel@tonic-gate (void) fprintf(stderr, "%s", message); 774*0Sstevel@tonic-gate return (CFGA_OK); 775*0Sstevel@tonic-gate 776*0Sstevel@tonic-gate } 777*0Sstevel@tonic-gate 778*0Sstevel@tonic-gate /* 779*0Sstevel@tonic-gate * extract_list_suboptions - process list option string 780*0Sstevel@tonic-gate */ 781*0Sstevel@tonic-gate static int 782*0Sstevel@tonic-gate extract_list_suboptions( 783*0Sstevel@tonic-gate char *arg, 784*0Sstevel@tonic-gate char **sortpp, 785*0Sstevel@tonic-gate char **colspp, 786*0Sstevel@tonic-gate char **cols2pp, 787*0Sstevel@tonic-gate int *noheadingsp, 788*0Sstevel@tonic-gate char **delimpp, 789*0Sstevel@tonic-gate char **selectpp, 790*0Sstevel@tonic-gate char **matchpp) 791*0Sstevel@tonic-gate { 792*0Sstevel@tonic-gate char *value = NULL; 793*0Sstevel@tonic-gate int subopt = 0; 794*0Sstevel@tonic-gate int err = 0; 795*0Sstevel@tonic-gate 796*0Sstevel@tonic-gate while (*arg != '\0') { 797*0Sstevel@tonic-gate static char need_value[] = 798*0Sstevel@tonic-gate "%s: sub-option \"%s\" requires a value\n"; 799*0Sstevel@tonic-gate static char no_value[] = 800*0Sstevel@tonic-gate "%s: sub-option \"%s\" does not take a value\n"; 801*0Sstevel@tonic-gate static char unk_subopt[] = 802*0Sstevel@tonic-gate "%s: sub-option \"%s\" unknown\n"; 803*0Sstevel@tonic-gate char **pptr; 804*0Sstevel@tonic-gate 805*0Sstevel@tonic-gate subopt = getsubopt(&arg, list_options, &value); 806*0Sstevel@tonic-gate switch (subopt) { 807*0Sstevel@tonic-gate case LIST_SORT: 808*0Sstevel@tonic-gate pptr = sortpp; 809*0Sstevel@tonic-gate goto valcom; 810*0Sstevel@tonic-gate case LIST_COLS: 811*0Sstevel@tonic-gate pptr = colspp; 812*0Sstevel@tonic-gate goto valcom; 813*0Sstevel@tonic-gate case LIST_COLS2: 814*0Sstevel@tonic-gate pptr = cols2pp; 815*0Sstevel@tonic-gate goto valcom; 816*0Sstevel@tonic-gate case LIST_SELECT: 817*0Sstevel@tonic-gate pptr = selectpp; 818*0Sstevel@tonic-gate goto valcom; 819*0Sstevel@tonic-gate case LIST_MATCH: 820*0Sstevel@tonic-gate pptr = matchpp; 821*0Sstevel@tonic-gate goto valcom; 822*0Sstevel@tonic-gate case LIST_DELIM: 823*0Sstevel@tonic-gate pptr = delimpp; 824*0Sstevel@tonic-gate valcom: 825*0Sstevel@tonic-gate if (value == NULL) { 826*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(need_value), 827*0Sstevel@tonic-gate cmdname, list_options[subopt]); 828*0Sstevel@tonic-gate err = 1; 829*0Sstevel@tonic-gate } else 830*0Sstevel@tonic-gate *pptr = value; 831*0Sstevel@tonic-gate break; 832*0Sstevel@tonic-gate case LIST_NOHEADINGS: 833*0Sstevel@tonic-gate if (value != NULL) { 834*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(no_value), 835*0Sstevel@tonic-gate cmdname, list_options[subopt]); 836*0Sstevel@tonic-gate err = 1; 837*0Sstevel@tonic-gate } else 838*0Sstevel@tonic-gate *noheadingsp = 1; 839*0Sstevel@tonic-gate break; 840*0Sstevel@tonic-gate default: 841*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(unk_subopt), 842*0Sstevel@tonic-gate cmdname, value); 843*0Sstevel@tonic-gate err = 1; 844*0Sstevel@tonic-gate break; 845*0Sstevel@tonic-gate } 846*0Sstevel@tonic-gate } 847*0Sstevel@tonic-gate return (err == 0); 848*0Sstevel@tonic-gate } 849*0Sstevel@tonic-gate 850*0Sstevel@tonic-gate static cfga_err_t 851*0Sstevel@tonic-gate setup_prefilter(post_filter_t *post_filtp, char **prefilt_optpp) 852*0Sstevel@tonic-gate { 853*0Sstevel@tonic-gate size_t len; 854*0Sstevel@tonic-gate const char *clopt = PREFILT_CLASS_STR; 855*0Sstevel@tonic-gate int idx; 856*0Sstevel@tonic-gate 857*0Sstevel@tonic-gate 858*0Sstevel@tonic-gate *prefilt_optpp = NULL; 859*0Sstevel@tonic-gate 860*0Sstevel@tonic-gate /* Get the index for the "class" field */ 861*0Sstevel@tonic-gate for (idx = 0; idx < N_FIELDS; idx++) { 862*0Sstevel@tonic-gate if (strcmp(all_fields[idx].name, PREFILT_CLASS_STR) == 0) 863*0Sstevel@tonic-gate break; 864*0Sstevel@tonic-gate } 865*0Sstevel@tonic-gate 866*0Sstevel@tonic-gate /* 867*0Sstevel@tonic-gate * Currently pre-filter available only for class fld w/ EXACT match 868*0Sstevel@tonic-gate */ 869*0Sstevel@tonic-gate if (idx >= N_FIELDS || 870*0Sstevel@tonic-gate post_filtp->match_type_p[idx] != CFGA_MATCH_EXACT) { 871*0Sstevel@tonic-gate return (CFGA_OK); 872*0Sstevel@tonic-gate } 873*0Sstevel@tonic-gate 874*0Sstevel@tonic-gate len = strlen(clopt) + strlen(post_filtp->ldata.ap_class) + 1; 875*0Sstevel@tonic-gate if ((*prefilt_optpp = config_calloc_check(1, len)) == NULL) { 876*0Sstevel@tonic-gate return (CFGA_LIB_ERROR); 877*0Sstevel@tonic-gate } 878*0Sstevel@tonic-gate 879*0Sstevel@tonic-gate (void) strcpy(*prefilt_optpp, clopt); 880*0Sstevel@tonic-gate (void) strcat(*prefilt_optpp, post_filtp->ldata.ap_class); 881*0Sstevel@tonic-gate 882*0Sstevel@tonic-gate /* 883*0Sstevel@tonic-gate * Since it is being pre-filtered, this attribute does not need 884*0Sstevel@tonic-gate * post-filtering. 885*0Sstevel@tonic-gate */ 886*0Sstevel@tonic-gate post_filtp->match_type_p[idx] = CFGA_MATCH_NOFILTER; 887*0Sstevel@tonic-gate if (all_fields[idx].set_filter != NULL) { 888*0Sstevel@tonic-gate (void) all_fields[idx].set_filter(&post_filtp->ldata, ""); 889*0Sstevel@tonic-gate } 890*0Sstevel@tonic-gate 891*0Sstevel@tonic-gate return (CFGA_OK); 892*0Sstevel@tonic-gate } 893*0Sstevel@tonic-gate 894*0Sstevel@tonic-gate static cfga_err_t 895*0Sstevel@tonic-gate set_attrval( 896*0Sstevel@tonic-gate const char *attr, 897*0Sstevel@tonic-gate const char *val, 898*0Sstevel@tonic-gate post_filter_t *post_filtp, 899*0Sstevel@tonic-gate match_type_t match_type) 900*0Sstevel@tonic-gate { 901*0Sstevel@tonic-gate int fld = 0; 902*0Sstevel@tonic-gate cfga_err_t ret = CFGA_ERROR; 903*0Sstevel@tonic-gate 904*0Sstevel@tonic-gate for (fld = 0; fld < N_FIELDS; fld++) { 905*0Sstevel@tonic-gate if (strcmp(attr, all_fields[fld].name) == 0) 906*0Sstevel@tonic-gate break; 907*0Sstevel@tonic-gate } 908*0Sstevel@tonic-gate 909*0Sstevel@tonic-gate /* Valid field or is the select option supported for this field */ 910*0Sstevel@tonic-gate if (fld >= N_FIELDS || all_fields[fld].set_filter == NULL) { 911*0Sstevel@tonic-gate return (CFGA_ATTR_INVAL); 912*0Sstevel@tonic-gate } 913*0Sstevel@tonic-gate 914*0Sstevel@tonic-gate if ((ret = all_fields[fld].set_filter(&post_filtp->ldata, val)) 915*0Sstevel@tonic-gate == CFGA_OK) { 916*0Sstevel@tonic-gate post_filtp->match_type_p[fld] = match_type; 917*0Sstevel@tonic-gate } 918*0Sstevel@tonic-gate 919*0Sstevel@tonic-gate return (ret); 920*0Sstevel@tonic-gate 921*0Sstevel@tonic-gate } 922*0Sstevel@tonic-gate 923*0Sstevel@tonic-gate static char inval_optarg[] = 924*0Sstevel@tonic-gate "%s: invalid value \"%s\" for %s suboption.\n"; 925*0Sstevel@tonic-gate 926*0Sstevel@tonic-gate /* 927*0Sstevel@tonic-gate * Parses the "select" string and fills in the post_filter structure 928*0Sstevel@tonic-gate */ 929*0Sstevel@tonic-gate static cfga_err_t 930*0Sstevel@tonic-gate parse_select_opt( 931*0Sstevel@tonic-gate const char *selectp, 932*0Sstevel@tonic-gate post_filter_t *post_filtp, 933*0Sstevel@tonic-gate match_type_t match_type) 934*0Sstevel@tonic-gate { 935*0Sstevel@tonic-gate parse_state_t state = CFGA_PSTATE_INIT; 936*0Sstevel@tonic-gate char *cp = NULL, *optstr = NULL, *attr = NULL, *val = NULL; 937*0Sstevel@tonic-gate int bal = 0; /* Tracks balancing */ 938*0Sstevel@tonic-gate char chr; 939*0Sstevel@tonic-gate cfga_err_t ret; 940*0Sstevel@tonic-gate 941*0Sstevel@tonic-gate 942*0Sstevel@tonic-gate if (selectp == NULL || post_filtp == NULL) { 943*0Sstevel@tonic-gate return (CFGA_ERROR); 944*0Sstevel@tonic-gate } 945*0Sstevel@tonic-gate 946*0Sstevel@tonic-gate optstr = config_calloc_check(1, strlen(selectp) + 1); 947*0Sstevel@tonic-gate if (optstr == NULL) { 948*0Sstevel@tonic-gate return (CFGA_LIB_ERROR); 949*0Sstevel@tonic-gate } 950*0Sstevel@tonic-gate 951*0Sstevel@tonic-gate (void) strcpy(optstr, selectp); 952*0Sstevel@tonic-gate 953*0Sstevel@tonic-gate /* Init */ 954*0Sstevel@tonic-gate ret = CFGA_ATTR_INVAL; 955*0Sstevel@tonic-gate bal = 0; 956*0Sstevel@tonic-gate cp = attr = optstr; 957*0Sstevel@tonic-gate state = CFGA_PSTATE_INIT; 958*0Sstevel@tonic-gate 959*0Sstevel@tonic-gate for (; *cp != '\0'; cp++) { 960*0Sstevel@tonic-gate switch (state) { 961*0Sstevel@tonic-gate case CFGA_PSTATE_INIT: 962*0Sstevel@tonic-gate if (*cp != LEFT_PAREN) 963*0Sstevel@tonic-gate break; 964*0Sstevel@tonic-gate *cp = '\0'; 965*0Sstevel@tonic-gate val = cp + 1; 966*0Sstevel@tonic-gate bal = 1; 967*0Sstevel@tonic-gate state = CFGA_PSTATE_ATTR_DONE; 968*0Sstevel@tonic-gate break; 969*0Sstevel@tonic-gate case CFGA_PSTATE_ATTR_DONE: 970*0Sstevel@tonic-gate chr = *cp; 971*0Sstevel@tonic-gate switch (chr) { 972*0Sstevel@tonic-gate case LEFT_PAREN: 973*0Sstevel@tonic-gate bal++; 974*0Sstevel@tonic-gate break; 975*0Sstevel@tonic-gate case RIGHT_PAREN: 976*0Sstevel@tonic-gate bal--; 977*0Sstevel@tonic-gate if (bal == 0) { 978*0Sstevel@tonic-gate *cp = '\0'; 979*0Sstevel@tonic-gate state = CFGA_PSTATE_VAL_DONE; 980*0Sstevel@tonic-gate } 981*0Sstevel@tonic-gate break; 982*0Sstevel@tonic-gate } 983*0Sstevel@tonic-gate break; 984*0Sstevel@tonic-gate case CFGA_PSTATE_VAL_DONE: 985*0Sstevel@tonic-gate if (*cp != ':') { 986*0Sstevel@tonic-gate state = CFGA_PSTATE_ERR; 987*0Sstevel@tonic-gate goto out; 988*0Sstevel@tonic-gate } 989*0Sstevel@tonic-gate 990*0Sstevel@tonic-gate *cp = '\0'; 991*0Sstevel@tonic-gate if (set_attrval(attr, val, post_filtp, 992*0Sstevel@tonic-gate match_type) != CFGA_OK) { 993*0Sstevel@tonic-gate state = CFGA_PSTATE_ERR; 994*0Sstevel@tonic-gate goto out; 995*0Sstevel@tonic-gate } 996*0Sstevel@tonic-gate state = CFGA_PSTATE_INIT; 997*0Sstevel@tonic-gate attr = cp + 1; 998*0Sstevel@tonic-gate break; 999*0Sstevel@tonic-gate default: 1000*0Sstevel@tonic-gate state = CFGA_PSTATE_ERR; 1001*0Sstevel@tonic-gate /* FALLTHROUGH */ 1002*0Sstevel@tonic-gate case CFGA_PSTATE_ERR: 1003*0Sstevel@tonic-gate goto out; 1004*0Sstevel@tonic-gate } 1005*0Sstevel@tonic-gate } 1006*0Sstevel@tonic-gate 1007*0Sstevel@tonic-gate /*FALLTHRU*/ 1008*0Sstevel@tonic-gate out: 1009*0Sstevel@tonic-gate if (state == CFGA_PSTATE_VAL_DONE) { 1010*0Sstevel@tonic-gate ret = set_attrval(attr, val, post_filtp, match_type); 1011*0Sstevel@tonic-gate } else { 1012*0Sstevel@tonic-gate ret = CFGA_ATTR_INVAL; 1013*0Sstevel@tonic-gate } 1014*0Sstevel@tonic-gate 1015*0Sstevel@tonic-gate if (ret != CFGA_OK) { 1016*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(inval_optarg), cmdname, 1017*0Sstevel@tonic-gate selectp, list_options[LIST_SELECT]); 1018*0Sstevel@tonic-gate } 1019*0Sstevel@tonic-gate 1020*0Sstevel@tonic-gate S_FREE(optstr); 1021*0Sstevel@tonic-gate return (ret); 1022*0Sstevel@tonic-gate } 1023*0Sstevel@tonic-gate 1024*0Sstevel@tonic-gate 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate static cfga_err_t 1027*0Sstevel@tonic-gate setup_filter( 1028*0Sstevel@tonic-gate const char *selectp, 1029*0Sstevel@tonic-gate const char *matchp, 1030*0Sstevel@tonic-gate post_filter_t *post_filtp, 1031*0Sstevel@tonic-gate char **prefilt_optpp) 1032*0Sstevel@tonic-gate { 1033*0Sstevel@tonic-gate cfga_err_t ret = CFGA_ERROR; 1034*0Sstevel@tonic-gate match_type_t match_type = CFGA_MATCH_NOFILTER; 1035*0Sstevel@tonic-gate int i; 1036*0Sstevel@tonic-gate 1037*0Sstevel@tonic-gate static char match_needs_select[] = 1038*0Sstevel@tonic-gate "%s: %s suboption can only be used with %s suboption.\n"; 1039*0Sstevel@tonic-gate 1040*0Sstevel@tonic-gate 1041*0Sstevel@tonic-gate *prefilt_optpp = NULL; 1042*0Sstevel@tonic-gate 1043*0Sstevel@tonic-gate /* 1044*0Sstevel@tonic-gate * Initial: no filtering. 1045*0Sstevel@tonic-gate * CFGA_MATCH_NOFILTER is NOT a valid user input 1046*0Sstevel@tonic-gate */ 1047*0Sstevel@tonic-gate for (i = 0; i < N_FIELDS; i++) { 1048*0Sstevel@tonic-gate post_filtp->match_type_p[i] = CFGA_MATCH_NOFILTER; 1049*0Sstevel@tonic-gate } 1050*0Sstevel@tonic-gate 1051*0Sstevel@tonic-gate /* Determine type of match */ 1052*0Sstevel@tonic-gate if (matchp == NULL && selectp == NULL) { 1053*0Sstevel@tonic-gate /* No filtering */ 1054*0Sstevel@tonic-gate return (CFGA_OK); 1055*0Sstevel@tonic-gate } else if (matchp == NULL && selectp != NULL) { 1056*0Sstevel@tonic-gate match_type = CFGA_DEFAULT_MATCH; 1057*0Sstevel@tonic-gate } else if (matchp != NULL && selectp == NULL) { 1058*0Sstevel@tonic-gate /* If only match specified, select criteria also needed */ 1059*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(match_needs_select), 1060*0Sstevel@tonic-gate cmdname, list_options[LIST_MATCH], 1061*0Sstevel@tonic-gate list_options[LIST_SELECT]); 1062*0Sstevel@tonic-gate return (CFGA_ERROR); 1063*0Sstevel@tonic-gate } else { 1064*0Sstevel@tonic-gate for (i = 0; i < N_MATCH_TYPES; i++) { 1065*0Sstevel@tonic-gate if (strcmp(matchp, match_type_array[i].str) == 0) { 1066*0Sstevel@tonic-gate match_type = match_type_array[i].type; 1067*0Sstevel@tonic-gate break; 1068*0Sstevel@tonic-gate } 1069*0Sstevel@tonic-gate } 1070*0Sstevel@tonic-gate if (i >= N_MATCH_TYPES) { 1071*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(inval_optarg), cmdname, 1072*0Sstevel@tonic-gate matchp, list_options[LIST_MATCH]); 1073*0Sstevel@tonic-gate return (CFGA_ERROR); 1074*0Sstevel@tonic-gate } 1075*0Sstevel@tonic-gate } 1076*0Sstevel@tonic-gate 1077*0Sstevel@tonic-gate if ((ret = parse_select_opt(selectp, post_filtp, match_type)) 1078*0Sstevel@tonic-gate != CFGA_OK) { 1079*0Sstevel@tonic-gate return (ret); 1080*0Sstevel@tonic-gate } 1081*0Sstevel@tonic-gate 1082*0Sstevel@tonic-gate /* Handle pre-filtering. */ 1083*0Sstevel@tonic-gate if ((ret = setup_prefilter(post_filtp, prefilt_optpp)) != CFGA_OK) { 1084*0Sstevel@tonic-gate /* Cleanup */ 1085*0Sstevel@tonic-gate for (i = 0; i < N_FIELDS; i++) { 1086*0Sstevel@tonic-gate post_filtp->match_type_p[i] = CFGA_MATCH_NOFILTER; 1087*0Sstevel@tonic-gate } 1088*0Sstevel@tonic-gate return (ret); 1089*0Sstevel@tonic-gate } 1090*0Sstevel@tonic-gate 1091*0Sstevel@tonic-gate 1092*0Sstevel@tonic-gate return (CFGA_OK); 1093*0Sstevel@tonic-gate } 1094*0Sstevel@tonic-gate 1095*0Sstevel@tonic-gate /* 1096*0Sstevel@tonic-gate * compare_ap_id - compare two ap_id's 1097*0Sstevel@tonic-gate * 1098*0Sstevel@tonic-gate * For partial matches, argument order is significant. The filtering criterion 1099*0Sstevel@tonic-gate * should be the first argument. 1100*0Sstevel@tonic-gate */ 1101*0Sstevel@tonic-gate 1102*0Sstevel@tonic-gate static int 1103*0Sstevel@tonic-gate compare_ap_id( 1104*0Sstevel@tonic-gate cfga_list_data_t *p1, 1105*0Sstevel@tonic-gate cfga_list_data_t *p2, 1106*0Sstevel@tonic-gate match_type_t match_type) 1107*0Sstevel@tonic-gate { 1108*0Sstevel@tonic-gate 1109*0Sstevel@tonic-gate switch (match_type) { 1110*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: 1111*0Sstevel@tonic-gate return (0); /* No filtering. all pass */ 1112*0Sstevel@tonic-gate case CFGA_MATCH_PARTIAL: 1113*0Sstevel@tonic-gate return (strncmp(p1->ap_log_id, p2->ap_log_id, 1114*0Sstevel@tonic-gate strlen(p1->ap_log_id))); 1115*0Sstevel@tonic-gate case CFGA_MATCH_EXACT: 1116*0Sstevel@tonic-gate return (strcmp(p1->ap_log_id, p2->ap_log_id)); 1117*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1118*0Sstevel@tonic-gate default: 1119*0Sstevel@tonic-gate return (config_ap_id_cmp(p1->ap_log_id, p2->ap_log_id)); 1120*0Sstevel@tonic-gate } 1121*0Sstevel@tonic-gate } 1122*0Sstevel@tonic-gate 1123*0Sstevel@tonic-gate /* 1124*0Sstevel@tonic-gate * print_log_id - print logical ap_id 1125*0Sstevel@tonic-gate */ 1126*0Sstevel@tonic-gate static void 1127*0Sstevel@tonic-gate print_log_id( 1128*0Sstevel@tonic-gate cfga_list_data_t *p, 1129*0Sstevel@tonic-gate int width, 1130*0Sstevel@tonic-gate char *lp) 1131*0Sstevel@tonic-gate { 1132*0Sstevel@tonic-gate (void) sprintf(lp, "%-*.*s", width, sizeof (p->ap_log_id), 1133*0Sstevel@tonic-gate p->ap_log_id); 1134*0Sstevel@tonic-gate } 1135*0Sstevel@tonic-gate 1136*0Sstevel@tonic-gate /* 1137*0Sstevel@tonic-gate * set_log_flt - Setup filter for logical ap_id 1138*0Sstevel@tonic-gate */ 1139*0Sstevel@tonic-gate static cfga_err_t 1140*0Sstevel@tonic-gate set_log_flt( 1141*0Sstevel@tonic-gate cfga_list_data_t *p, 1142*0Sstevel@tonic-gate const char *val) 1143*0Sstevel@tonic-gate { 1144*0Sstevel@tonic-gate if (strlen(val) > sizeof (p->ap_log_id) - 1) 1145*0Sstevel@tonic-gate return (CFGA_ATTR_INVAL); 1146*0Sstevel@tonic-gate 1147*0Sstevel@tonic-gate (void) strcpy(p->ap_log_id, val); 1148*0Sstevel@tonic-gate 1149*0Sstevel@tonic-gate return (CFGA_OK); 1150*0Sstevel@tonic-gate } 1151*0Sstevel@tonic-gate 1152*0Sstevel@tonic-gate /* 1153*0Sstevel@tonic-gate * set_type_flt - Setup filter for type field 1154*0Sstevel@tonic-gate */ 1155*0Sstevel@tonic-gate 1156*0Sstevel@tonic-gate static cfga_err_t 1157*0Sstevel@tonic-gate set_type_flt( 1158*0Sstevel@tonic-gate cfga_list_data_t *p, 1159*0Sstevel@tonic-gate const char *val) 1160*0Sstevel@tonic-gate { 1161*0Sstevel@tonic-gate if (strlen(val) > sizeof (p->ap_type) - 1) 1162*0Sstevel@tonic-gate return (CFGA_ATTR_INVAL); 1163*0Sstevel@tonic-gate 1164*0Sstevel@tonic-gate (void) strcpy(p->ap_type, val); 1165*0Sstevel@tonic-gate 1166*0Sstevel@tonic-gate return (CFGA_OK); 1167*0Sstevel@tonic-gate } 1168*0Sstevel@tonic-gate 1169*0Sstevel@tonic-gate /* 1170*0Sstevel@tonic-gate * set_class_flt - Setup filter for class field 1171*0Sstevel@tonic-gate */ 1172*0Sstevel@tonic-gate static cfga_err_t 1173*0Sstevel@tonic-gate set_class_flt( 1174*0Sstevel@tonic-gate cfga_list_data_t *p, 1175*0Sstevel@tonic-gate const char *val) 1176*0Sstevel@tonic-gate { 1177*0Sstevel@tonic-gate if (strlen(val) > sizeof (p->ap_class) - 1) 1178*0Sstevel@tonic-gate return (CFGA_ATTR_INVAL); 1179*0Sstevel@tonic-gate 1180*0Sstevel@tonic-gate (void) strcpy(p->ap_class, val); 1181*0Sstevel@tonic-gate 1182*0Sstevel@tonic-gate return (CFGA_OK); 1183*0Sstevel@tonic-gate } 1184*0Sstevel@tonic-gate 1185*0Sstevel@tonic-gate 1186*0Sstevel@tonic-gate /* 1187*0Sstevel@tonic-gate * compare_r_state - compare receptacle state of two ap_id's 1188*0Sstevel@tonic-gate */ 1189*0Sstevel@tonic-gate static int 1190*0Sstevel@tonic-gate compare_r_state( 1191*0Sstevel@tonic-gate cfga_list_data_t *p1, 1192*0Sstevel@tonic-gate cfga_list_data_t *p2, 1193*0Sstevel@tonic-gate match_type_t match_type) 1194*0Sstevel@tonic-gate { 1195*0Sstevel@tonic-gate switch (match_type) { 1196*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: /* no filtering. pass all */ 1197*0Sstevel@tonic-gate return (0); 1198*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1199*0Sstevel@tonic-gate default: 1200*0Sstevel@tonic-gate return (p1->ap_r_state - p2->ap_r_state); 1201*0Sstevel@tonic-gate } 1202*0Sstevel@tonic-gate } 1203*0Sstevel@tonic-gate 1204*0Sstevel@tonic-gate /* 1205*0Sstevel@tonic-gate * compare_o_state - compare occupant state of two ap_id's 1206*0Sstevel@tonic-gate */ 1207*0Sstevel@tonic-gate static int 1208*0Sstevel@tonic-gate compare_o_state( 1209*0Sstevel@tonic-gate cfga_list_data_t *p1, 1210*0Sstevel@tonic-gate cfga_list_data_t *p2, 1211*0Sstevel@tonic-gate match_type_t match_type) 1212*0Sstevel@tonic-gate { 1213*0Sstevel@tonic-gate switch (match_type) { 1214*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: /* no filtering. all pass */ 1215*0Sstevel@tonic-gate return (0); 1216*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1217*0Sstevel@tonic-gate default: 1218*0Sstevel@tonic-gate return (p1->ap_o_state - p2->ap_o_state); 1219*0Sstevel@tonic-gate } 1220*0Sstevel@tonic-gate } 1221*0Sstevel@tonic-gate 1222*0Sstevel@tonic-gate /* 1223*0Sstevel@tonic-gate * compare_busy - compare busy field of two ap_id's 1224*0Sstevel@tonic-gate */ 1225*0Sstevel@tonic-gate static int 1226*0Sstevel@tonic-gate compare_busy( 1227*0Sstevel@tonic-gate cfga_list_data_t *p1, 1228*0Sstevel@tonic-gate cfga_list_data_t *p2, 1229*0Sstevel@tonic-gate match_type_t match_type) 1230*0Sstevel@tonic-gate { 1231*0Sstevel@tonic-gate 1232*0Sstevel@tonic-gate switch (match_type) { 1233*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: /* no filtering. all pass */ 1234*0Sstevel@tonic-gate return (0); 1235*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1236*0Sstevel@tonic-gate default: 1237*0Sstevel@tonic-gate return (p1->ap_busy - p2->ap_busy); 1238*0Sstevel@tonic-gate } 1239*0Sstevel@tonic-gate } 1240*0Sstevel@tonic-gate 1241*0Sstevel@tonic-gate /* 1242*0Sstevel@tonic-gate * print_r_state - print receptacle state 1243*0Sstevel@tonic-gate */ 1244*0Sstevel@tonic-gate static void 1245*0Sstevel@tonic-gate print_r_state( 1246*0Sstevel@tonic-gate cfga_list_data_t *p, 1247*0Sstevel@tonic-gate int width, 1248*0Sstevel@tonic-gate char *lp) 1249*0Sstevel@tonic-gate { 1250*0Sstevel@tonic-gate char *cp; 1251*0Sstevel@tonic-gate 1252*0Sstevel@tonic-gate switch (p->ap_r_state) { 1253*0Sstevel@tonic-gate case CFGA_STAT_EMPTY: 1254*0Sstevel@tonic-gate cp = "empty"; 1255*0Sstevel@tonic-gate break; 1256*0Sstevel@tonic-gate case CFGA_STAT_CONNECTED: 1257*0Sstevel@tonic-gate cp = "connected"; 1258*0Sstevel@tonic-gate break; 1259*0Sstevel@tonic-gate case CFGA_STAT_DISCONNECTED: 1260*0Sstevel@tonic-gate cp = "disconnected"; 1261*0Sstevel@tonic-gate break; 1262*0Sstevel@tonic-gate default: 1263*0Sstevel@tonic-gate cp = "???"; 1264*0Sstevel@tonic-gate break; 1265*0Sstevel@tonic-gate } 1266*0Sstevel@tonic-gate (void) sprintf(lp, "%-*s", width, cp); 1267*0Sstevel@tonic-gate } 1268*0Sstevel@tonic-gate 1269*0Sstevel@tonic-gate /* 1270*0Sstevel@tonic-gate * print_o_state - print occupant state 1271*0Sstevel@tonic-gate */ 1272*0Sstevel@tonic-gate static void 1273*0Sstevel@tonic-gate print_o_state( 1274*0Sstevel@tonic-gate cfga_list_data_t *p, 1275*0Sstevel@tonic-gate int width, 1276*0Sstevel@tonic-gate char *lp) 1277*0Sstevel@tonic-gate { 1278*0Sstevel@tonic-gate char *cp; 1279*0Sstevel@tonic-gate 1280*0Sstevel@tonic-gate switch (p->ap_o_state) { 1281*0Sstevel@tonic-gate case CFGA_STAT_UNCONFIGURED: 1282*0Sstevel@tonic-gate cp = "unconfigured"; 1283*0Sstevel@tonic-gate break; 1284*0Sstevel@tonic-gate case CFGA_STAT_CONFIGURED: 1285*0Sstevel@tonic-gate cp = "configured"; 1286*0Sstevel@tonic-gate break; 1287*0Sstevel@tonic-gate default: 1288*0Sstevel@tonic-gate cp = "???"; 1289*0Sstevel@tonic-gate break; 1290*0Sstevel@tonic-gate } 1291*0Sstevel@tonic-gate (void) sprintf(lp, "%-*s", width, cp); 1292*0Sstevel@tonic-gate } 1293*0Sstevel@tonic-gate 1294*0Sstevel@tonic-gate /* 1295*0Sstevel@tonic-gate * compare_cond - compare condition field of two ap_id's 1296*0Sstevel@tonic-gate */ 1297*0Sstevel@tonic-gate static int 1298*0Sstevel@tonic-gate compare_cond( 1299*0Sstevel@tonic-gate cfga_list_data_t *p1, 1300*0Sstevel@tonic-gate cfga_list_data_t *p2, 1301*0Sstevel@tonic-gate match_type_t match_type) 1302*0Sstevel@tonic-gate { 1303*0Sstevel@tonic-gate 1304*0Sstevel@tonic-gate switch (match_type) { 1305*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: 1306*0Sstevel@tonic-gate return (0); 1307*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1308*0Sstevel@tonic-gate default: 1309*0Sstevel@tonic-gate return (p1->ap_cond - p2->ap_cond); 1310*0Sstevel@tonic-gate } 1311*0Sstevel@tonic-gate } 1312*0Sstevel@tonic-gate 1313*0Sstevel@tonic-gate /* 1314*0Sstevel@tonic-gate * print_cond - print attachment point condition 1315*0Sstevel@tonic-gate */ 1316*0Sstevel@tonic-gate static void 1317*0Sstevel@tonic-gate print_cond( 1318*0Sstevel@tonic-gate cfga_list_data_t *p, 1319*0Sstevel@tonic-gate int width, 1320*0Sstevel@tonic-gate char *lp) 1321*0Sstevel@tonic-gate { 1322*0Sstevel@tonic-gate char *cp; 1323*0Sstevel@tonic-gate 1324*0Sstevel@tonic-gate switch (p->ap_cond) { 1325*0Sstevel@tonic-gate case CFGA_COND_UNKNOWN: 1326*0Sstevel@tonic-gate cp = "unknown"; 1327*0Sstevel@tonic-gate break; 1328*0Sstevel@tonic-gate case CFGA_COND_UNUSABLE: 1329*0Sstevel@tonic-gate cp = "unusable"; 1330*0Sstevel@tonic-gate break; 1331*0Sstevel@tonic-gate case CFGA_COND_FAILING: 1332*0Sstevel@tonic-gate cp = "failing"; 1333*0Sstevel@tonic-gate break; 1334*0Sstevel@tonic-gate case CFGA_COND_FAILED: 1335*0Sstevel@tonic-gate cp = "failed"; 1336*0Sstevel@tonic-gate break; 1337*0Sstevel@tonic-gate case CFGA_COND_OK: 1338*0Sstevel@tonic-gate cp = "ok"; 1339*0Sstevel@tonic-gate break; 1340*0Sstevel@tonic-gate default: 1341*0Sstevel@tonic-gate cp = "???"; 1342*0Sstevel@tonic-gate break; 1343*0Sstevel@tonic-gate } 1344*0Sstevel@tonic-gate (void) sprintf(lp, "%-*s", width, cp); 1345*0Sstevel@tonic-gate } 1346*0Sstevel@tonic-gate 1347*0Sstevel@tonic-gate /* 1348*0Sstevel@tonic-gate * compare_time - compare time field of two ap_id's 1349*0Sstevel@tonic-gate */ 1350*0Sstevel@tonic-gate static int 1351*0Sstevel@tonic-gate compare_time( 1352*0Sstevel@tonic-gate cfga_list_data_t *p1, 1353*0Sstevel@tonic-gate cfga_list_data_t *p2, 1354*0Sstevel@tonic-gate match_type_t match_type) 1355*0Sstevel@tonic-gate { 1356*0Sstevel@tonic-gate switch (match_type) { 1357*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: 1358*0Sstevel@tonic-gate return (0); 1359*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1360*0Sstevel@tonic-gate default: 1361*0Sstevel@tonic-gate return (p1->ap_status_time - p2->ap_status_time); 1362*0Sstevel@tonic-gate } 1363*0Sstevel@tonic-gate } 1364*0Sstevel@tonic-gate 1365*0Sstevel@tonic-gate 1366*0Sstevel@tonic-gate /* 1367*0Sstevel@tonic-gate * print_time - print time from cfga_list_data. 1368*0Sstevel@tonic-gate * Time print based on ls(1). 1369*0Sstevel@tonic-gate */ 1370*0Sstevel@tonic-gate static void 1371*0Sstevel@tonic-gate print_time( 1372*0Sstevel@tonic-gate cfga_list_data_t *p, 1373*0Sstevel@tonic-gate int width, 1374*0Sstevel@tonic-gate char *lp) 1375*0Sstevel@tonic-gate { 1376*0Sstevel@tonic-gate static time_t year, now; 1377*0Sstevel@tonic-gate time_t stime; 1378*0Sstevel@tonic-gate char time_buf[50]; /* array to hold day and time */ 1379*0Sstevel@tonic-gate 1380*0Sstevel@tonic-gate if (year == 0) { 1381*0Sstevel@tonic-gate now = time((long *)NULL); 1382*0Sstevel@tonic-gate year = now - 6L*30L*24L*60L*60L; /* 6 months ago */ 1383*0Sstevel@tonic-gate now = now + 60; 1384*0Sstevel@tonic-gate } 1385*0Sstevel@tonic-gate stime = p->ap_status_time; 1386*0Sstevel@tonic-gate if (stime == (time_t)-1) { 1387*0Sstevel@tonic-gate (void) sprintf(lp, "%-*s", width, gettext("unavailable")); 1388*0Sstevel@tonic-gate return; 1389*0Sstevel@tonic-gate } 1390*0Sstevel@tonic-gate 1391*0Sstevel@tonic-gate if ((stime < year) || (stime > now)) { 1392*0Sstevel@tonic-gate (void) strftime(time_buf, sizeof (time_buf), 1393*0Sstevel@tonic-gate dcgettext(NULL, FORMAT1, LC_TIME), localtime(&stime)); 1394*0Sstevel@tonic-gate } else { 1395*0Sstevel@tonic-gate (void) strftime(time_buf, sizeof (time_buf), 1396*0Sstevel@tonic-gate dcgettext(NULL, FORMAT2, LC_TIME), localtime(&stime)); 1397*0Sstevel@tonic-gate } 1398*0Sstevel@tonic-gate (void) sprintf(lp, "%-*s", width, time_buf); 1399*0Sstevel@tonic-gate } 1400*0Sstevel@tonic-gate 1401*0Sstevel@tonic-gate /* 1402*0Sstevel@tonic-gate * print_time_p - print time from cfga_list_data. 1403*0Sstevel@tonic-gate */ 1404*0Sstevel@tonic-gate static void 1405*0Sstevel@tonic-gate print_time_p( 1406*0Sstevel@tonic-gate cfga_list_data_t *p, 1407*0Sstevel@tonic-gate int width, 1408*0Sstevel@tonic-gate char *lp) 1409*0Sstevel@tonic-gate { 1410*0Sstevel@tonic-gate struct tm *tp; 1411*0Sstevel@tonic-gate char tstr[TIME_P_WIDTH+1]; 1412*0Sstevel@tonic-gate 1413*0Sstevel@tonic-gate tp = localtime(&p->ap_status_time); 1414*0Sstevel@tonic-gate (void) sprintf(tstr, "%04d%02d%02d%02d%02d%02d", tp->tm_year + 1900, 1415*0Sstevel@tonic-gate tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec); 1416*0Sstevel@tonic-gate (void) sprintf(lp, "%-*s", width, tstr); 1417*0Sstevel@tonic-gate } 1418*0Sstevel@tonic-gate 1419*0Sstevel@tonic-gate /* 1420*0Sstevel@tonic-gate * compare_info - compare info from two cfga_list_data structs 1421*0Sstevel@tonic-gate */ 1422*0Sstevel@tonic-gate static int 1423*0Sstevel@tonic-gate compare_info( 1424*0Sstevel@tonic-gate cfga_list_data_t *p1, 1425*0Sstevel@tonic-gate cfga_list_data_t *p2, 1426*0Sstevel@tonic-gate match_type_t match_type) 1427*0Sstevel@tonic-gate { 1428*0Sstevel@tonic-gate switch (match_type) { 1429*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: 1430*0Sstevel@tonic-gate return (0); 1431*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1432*0Sstevel@tonic-gate default: 1433*0Sstevel@tonic-gate return (strncmp(p1->ap_info, p2->ap_info, 1434*0Sstevel@tonic-gate sizeof (p2->ap_info))); 1435*0Sstevel@tonic-gate } 1436*0Sstevel@tonic-gate } 1437*0Sstevel@tonic-gate 1438*0Sstevel@tonic-gate /* 1439*0Sstevel@tonic-gate * print_info - print info from cfga_list_data struct 1440*0Sstevel@tonic-gate */ 1441*0Sstevel@tonic-gate static void 1442*0Sstevel@tonic-gate print_info( 1443*0Sstevel@tonic-gate cfga_list_data_t *p, 1444*0Sstevel@tonic-gate int width, 1445*0Sstevel@tonic-gate char *lp) 1446*0Sstevel@tonic-gate { 1447*0Sstevel@tonic-gate (void) sprintf(lp, "%-*.*s", width, sizeof (p->ap_info), p->ap_info); 1448*0Sstevel@tonic-gate } 1449*0Sstevel@tonic-gate 1450*0Sstevel@tonic-gate /* 1451*0Sstevel@tonic-gate * compare_type - compare type from two cfga_list_data structs 1452*0Sstevel@tonic-gate * 1453*0Sstevel@tonic-gate * For partial matches, argument order is significant. The filtering criterion 1454*0Sstevel@tonic-gate * should be the first argument. 1455*0Sstevel@tonic-gate */ 1456*0Sstevel@tonic-gate static int 1457*0Sstevel@tonic-gate compare_type( 1458*0Sstevel@tonic-gate cfga_list_data_t *p1, 1459*0Sstevel@tonic-gate cfga_list_data_t *p2, 1460*0Sstevel@tonic-gate match_type_t match_type) 1461*0Sstevel@tonic-gate { 1462*0Sstevel@tonic-gate switch (match_type) { 1463*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: 1464*0Sstevel@tonic-gate return (0); 1465*0Sstevel@tonic-gate case CFGA_MATCH_PARTIAL: 1466*0Sstevel@tonic-gate return (strncmp(p1->ap_type, p2->ap_type, strlen(p1->ap_type))); 1467*0Sstevel@tonic-gate case CFGA_MATCH_EXACT: 1468*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1469*0Sstevel@tonic-gate default: 1470*0Sstevel@tonic-gate return (strncmp(p1->ap_type, p2->ap_type, 1471*0Sstevel@tonic-gate sizeof (p2->ap_type))); 1472*0Sstevel@tonic-gate } 1473*0Sstevel@tonic-gate } 1474*0Sstevel@tonic-gate 1475*0Sstevel@tonic-gate /* 1476*0Sstevel@tonic-gate * print_type - print type from cfga_list_data struct 1477*0Sstevel@tonic-gate */ 1478*0Sstevel@tonic-gate static void 1479*0Sstevel@tonic-gate print_type( 1480*0Sstevel@tonic-gate cfga_list_data_t *p, 1481*0Sstevel@tonic-gate int width, 1482*0Sstevel@tonic-gate char *lp) 1483*0Sstevel@tonic-gate { 1484*0Sstevel@tonic-gate (void) sprintf(lp, "%-*.*s", width, sizeof (p->ap_type), p->ap_type); 1485*0Sstevel@tonic-gate } 1486*0Sstevel@tonic-gate 1487*0Sstevel@tonic-gate 1488*0Sstevel@tonic-gate /* 1489*0Sstevel@tonic-gate * compare_class - compare class from two cfga_list_data structs 1490*0Sstevel@tonic-gate * 1491*0Sstevel@tonic-gate * For partial matches, argument order is significant. The filtering criterion 1492*0Sstevel@tonic-gate * should be the first argument. 1493*0Sstevel@tonic-gate */ 1494*0Sstevel@tonic-gate static int 1495*0Sstevel@tonic-gate compare_class( 1496*0Sstevel@tonic-gate cfga_list_data_t *p1, 1497*0Sstevel@tonic-gate cfga_list_data_t *p2, 1498*0Sstevel@tonic-gate match_type_t match_type) 1499*0Sstevel@tonic-gate { 1500*0Sstevel@tonic-gate 1501*0Sstevel@tonic-gate switch (match_type) { 1502*0Sstevel@tonic-gate case CFGA_MATCH_NOFILTER: 1503*0Sstevel@tonic-gate return (0); 1504*0Sstevel@tonic-gate case CFGA_MATCH_PARTIAL: 1505*0Sstevel@tonic-gate return (strncmp(p1->ap_class, p2->ap_class, 1506*0Sstevel@tonic-gate strlen(p1->ap_class))); 1507*0Sstevel@tonic-gate case CFGA_MATCH_EXACT: 1508*0Sstevel@tonic-gate case CFGA_MATCH_ORDER: 1509*0Sstevel@tonic-gate default: 1510*0Sstevel@tonic-gate return (strncmp(p1->ap_class, p2->ap_class, 1511*0Sstevel@tonic-gate sizeof (p2->ap_class))); 1512*0Sstevel@tonic-gate } 1513*0Sstevel@tonic-gate } 1514*0Sstevel@tonic-gate 1515*0Sstevel@tonic-gate /* 1516*0Sstevel@tonic-gate * print_class - print class from cfga_list_data struct 1517*0Sstevel@tonic-gate */ 1518*0Sstevel@tonic-gate static void 1519*0Sstevel@tonic-gate print_class( 1520*0Sstevel@tonic-gate cfga_list_data_t *p, 1521*0Sstevel@tonic-gate int width, 1522*0Sstevel@tonic-gate char *lp) 1523*0Sstevel@tonic-gate { 1524*0Sstevel@tonic-gate (void) sprintf(lp, "%-*.*s", width, sizeof (p->ap_class), p->ap_class); 1525*0Sstevel@tonic-gate } 1526*0Sstevel@tonic-gate /* 1527*0Sstevel@tonic-gate * print_busy - print busy from cfga_list_data struct 1528*0Sstevel@tonic-gate */ 1529*0Sstevel@tonic-gate /* ARGSUSED */ 1530*0Sstevel@tonic-gate static void 1531*0Sstevel@tonic-gate print_busy( 1532*0Sstevel@tonic-gate cfga_list_data_t *p, 1533*0Sstevel@tonic-gate int width, 1534*0Sstevel@tonic-gate char *lp) 1535*0Sstevel@tonic-gate { 1536*0Sstevel@tonic-gate if (p->ap_busy) 1537*0Sstevel@tonic-gate (void) sprintf(lp, "%-*.*s", width, width, "y"); 1538*0Sstevel@tonic-gate else 1539*0Sstevel@tonic-gate (void) sprintf(lp, "%-*.*s", width, width, "n"); 1540*0Sstevel@tonic-gate } 1541*0Sstevel@tonic-gate 1542*0Sstevel@tonic-gate /* 1543*0Sstevel@tonic-gate * print_phys_id - print physical ap_id 1544*0Sstevel@tonic-gate */ 1545*0Sstevel@tonic-gate static void 1546*0Sstevel@tonic-gate print_phys_id( 1547*0Sstevel@tonic-gate cfga_list_data_t *p, 1548*0Sstevel@tonic-gate int width, 1549*0Sstevel@tonic-gate char *lp) 1550*0Sstevel@tonic-gate { 1551*0Sstevel@tonic-gate (void) sprintf(lp, "%-*.*s", width, sizeof (p->ap_phys_id), 1552*0Sstevel@tonic-gate p->ap_phys_id); 1553*0Sstevel@tonic-gate } 1554*0Sstevel@tonic-gate 1555*0Sstevel@tonic-gate 1556*0Sstevel@tonic-gate /* 1557*0Sstevel@tonic-gate * find_field - find the named field 1558*0Sstevel@tonic-gate */ 1559*0Sstevel@tonic-gate static struct field_info * 1560*0Sstevel@tonic-gate find_field(char *fname) 1561*0Sstevel@tonic-gate { 1562*0Sstevel@tonic-gate struct field_info *fldp; 1563*0Sstevel@tonic-gate 1564*0Sstevel@tonic-gate for (fldp = all_fields; fldp < &all_fields[N_FIELDS]; fldp++) 1565*0Sstevel@tonic-gate if (strcmp(fname, fldp->name) == 0) 1566*0Sstevel@tonic-gate return (fldp); 1567*0Sstevel@tonic-gate return (NULL); 1568*0Sstevel@tonic-gate } 1569*0Sstevel@tonic-gate 1570*0Sstevel@tonic-gate /* 1571*0Sstevel@tonic-gate * usage_field - print field usage 1572*0Sstevel@tonic-gate */ 1573*0Sstevel@tonic-gate static void 1574*0Sstevel@tonic-gate usage_field() 1575*0Sstevel@tonic-gate { 1576*0Sstevel@tonic-gate struct field_info *fldp = NULL; 1577*0Sstevel@tonic-gate const char *sep; 1578*0Sstevel@tonic-gate static char field_list[] = "%s: print or sort fields must be one of:"; 1579*0Sstevel@tonic-gate 1580*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(field_list), cmdname); 1581*0Sstevel@tonic-gate sep = ""; 1582*0Sstevel@tonic-gate 1583*0Sstevel@tonic-gate for (fldp = all_fields; fldp < &all_fields[N_FIELDS]; fldp++) { 1584*0Sstevel@tonic-gate (void) fprintf(stderr, "%s %s", sep, fldp->name); 1585*0Sstevel@tonic-gate sep = ","; 1586*0Sstevel@tonic-gate } 1587*0Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 1588*0Sstevel@tonic-gate } 1589*0Sstevel@tonic-gate 1590*0Sstevel@tonic-gate /* 1591*0Sstevel@tonic-gate * compare_null - null comparison routine 1592*0Sstevel@tonic-gate */ 1593*0Sstevel@tonic-gate /*ARGSUSED*/ 1594*0Sstevel@tonic-gate static int 1595*0Sstevel@tonic-gate compare_null( 1596*0Sstevel@tonic-gate cfga_list_data_t *p1, 1597*0Sstevel@tonic-gate cfga_list_data_t *p2, 1598*0Sstevel@tonic-gate match_type_t match_type) 1599*0Sstevel@tonic-gate { 1600*0Sstevel@tonic-gate return (0); 1601*0Sstevel@tonic-gate } 1602*0Sstevel@tonic-gate 1603*0Sstevel@tonic-gate /* 1604*0Sstevel@tonic-gate * print_null - print out a field of spaces 1605*0Sstevel@tonic-gate */ 1606*0Sstevel@tonic-gate /*ARGSUSED*/ 1607*0Sstevel@tonic-gate static void 1608*0Sstevel@tonic-gate print_null( 1609*0Sstevel@tonic-gate cfga_list_data_t *p, 1610*0Sstevel@tonic-gate int width, 1611*0Sstevel@tonic-gate char *lp) 1612*0Sstevel@tonic-gate { 1613*0Sstevel@tonic-gate (void) sprintf(lp, "%-*s", width, ""); 1614*0Sstevel@tonic-gate } 1615*0Sstevel@tonic-gate 1616*0Sstevel@tonic-gate /* 1617*0Sstevel@tonic-gate * do_config_list - directs the output of the listing functions 1618*0Sstevel@tonic-gate */ 1619*0Sstevel@tonic-gate static int 1620*0Sstevel@tonic-gate do_config_list( 1621*0Sstevel@tonic-gate int l_argc, 1622*0Sstevel@tonic-gate char *l_argv[], 1623*0Sstevel@tonic-gate cfga_list_data_t *statlist, 1624*0Sstevel@tonic-gate int nlist, 1625*0Sstevel@tonic-gate char *sortp, 1626*0Sstevel@tonic-gate char *colsp, 1627*0Sstevel@tonic-gate char *cols2p, 1628*0Sstevel@tonic-gate int noheadings, 1629*0Sstevel@tonic-gate char *delimp, 1630*0Sstevel@tonic-gate post_filter_t *post_filtp, 1631*0Sstevel@tonic-gate int dyn_exp) 1632*0Sstevel@tonic-gate { 1633*0Sstevel@tonic-gate int nprcols = 0, ncols2 = 0; 1634*0Sstevel@tonic-gate struct print_col *prnt_list = NULL; 1635*0Sstevel@tonic-gate int napids_to_list = 0; 1636*0Sstevel@tonic-gate FILE *fp = NULL; 1637*0Sstevel@tonic-gate int f_err; 1638*0Sstevel@tonic-gate cfga_list_data_t **sel_boards = NULL; 1639*0Sstevel@tonic-gate int nsel = 0; 1640*0Sstevel@tonic-gate int i, j; 1641*0Sstevel@tonic-gate cfga_err_t ret; 1642*0Sstevel@tonic-gate 1643*0Sstevel@tonic-gate ap_arg_t *arg_array = NULL; 1644*0Sstevel@tonic-gate ap_out_t *out_array = NULL; 1645*0Sstevel@tonic-gate 1646*0Sstevel@tonic-gate 1647*0Sstevel@tonic-gate sort_list = NULL; 1648*0Sstevel@tonic-gate f_err = 0; 1649*0Sstevel@tonic-gate fp = stdout; 1650*0Sstevel@tonic-gate nsort_list = count_fields(sortp, FDELIM); 1651*0Sstevel@tonic-gate if (nsort_list != 0) { 1652*0Sstevel@tonic-gate sort_list = config_calloc_check(nsort_list, 1653*0Sstevel@tonic-gate sizeof (*sort_list)); 1654*0Sstevel@tonic-gate if (sort_list == NULL) { 1655*0Sstevel@tonic-gate ret = CFGA_LIB_ERROR; 1656*0Sstevel@tonic-gate goto out; 1657*0Sstevel@tonic-gate } 1658*0Sstevel@tonic-gate f_err |= process_sort_fields(nsort_list, sort_list, sortp); 1659*0Sstevel@tonic-gate } else 1660*0Sstevel@tonic-gate sort_list = NULL; 1661*0Sstevel@tonic-gate 1662*0Sstevel@tonic-gate nprcols = count_fields(colsp, FDELIM); 1663*0Sstevel@tonic-gate if ((ncols2 = count_fields(cols2p, FDELIM)) > nprcols) 1664*0Sstevel@tonic-gate nprcols = ncols2; 1665*0Sstevel@tonic-gate if (nprcols != 0) { 1666*0Sstevel@tonic-gate prnt_list = config_calloc_check(nprcols, sizeof (*prnt_list)); 1667*0Sstevel@tonic-gate if (prnt_list == NULL) { 1668*0Sstevel@tonic-gate ret = CFGA_LIB_ERROR; 1669*0Sstevel@tonic-gate goto out; 1670*0Sstevel@tonic-gate } 1671*0Sstevel@tonic-gate f_err |= process_fields(nprcols, prnt_list, 0, colsp); 1672*0Sstevel@tonic-gate if (ncols2 != 0) 1673*0Sstevel@tonic-gate f_err |= process_fields(nprcols, prnt_list, 1, cols2p); 1674*0Sstevel@tonic-gate } else 1675*0Sstevel@tonic-gate prnt_list = NULL; 1676*0Sstevel@tonic-gate 1677*0Sstevel@tonic-gate if (f_err) { 1678*0Sstevel@tonic-gate usage_field(); 1679*0Sstevel@tonic-gate ret = CFGA_ERROR; 1680*0Sstevel@tonic-gate goto out; 1681*0Sstevel@tonic-gate } 1682*0Sstevel@tonic-gate 1683*0Sstevel@tonic-gate /* Create an array of all user args (if any) */ 1684*0Sstevel@tonic-gate if (l_argc != 0) { 1685*0Sstevel@tonic-gate int i, j; 1686*0Sstevel@tonic-gate 1687*0Sstevel@tonic-gate napids_to_list = 0; 1688*0Sstevel@tonic-gate 1689*0Sstevel@tonic-gate for (i = 0; i < l_argc; i++) { 1690*0Sstevel@tonic-gate napids_to_list += count_fields(l_argv[i], ARG_DELIM); 1691*0Sstevel@tonic-gate } 1692*0Sstevel@tonic-gate 1693*0Sstevel@tonic-gate arg_array = config_calloc_check(napids_to_list, 1694*0Sstevel@tonic-gate sizeof (*arg_array)); 1695*0Sstevel@tonic-gate if (arg_array == NULL) { 1696*0Sstevel@tonic-gate ret = CFGA_LIB_ERROR; 1697*0Sstevel@tonic-gate goto out; 1698*0Sstevel@tonic-gate } 1699*0Sstevel@tonic-gate 1700*0Sstevel@tonic-gate for (i = 0, j = 0; i < l_argc; i++) { 1701*0Sstevel@tonic-gate int n; 1702*0Sstevel@tonic-gate 1703*0Sstevel@tonic-gate n = count_fields(l_argv[i], ARG_DELIM); 1704*0Sstevel@tonic-gate if (n == 0) { 1705*0Sstevel@tonic-gate continue; 1706*0Sstevel@tonic-gate } else if (n == 1) { 1707*0Sstevel@tonic-gate arg_array[j].arg = l_argv[i]; 1708*0Sstevel@tonic-gate arg_array[j].resp = 0; 1709*0Sstevel@tonic-gate j++; 1710*0Sstevel@tonic-gate } else { 1711*0Sstevel@tonic-gate char *cp, *ncp; 1712*0Sstevel@tonic-gate 1713*0Sstevel@tonic-gate cp = l_argv[i]; 1714*0Sstevel@tonic-gate for (;;) { 1715*0Sstevel@tonic-gate arg_array[j].arg = cp; 1716*0Sstevel@tonic-gate arg_array[j].resp = 0; 1717*0Sstevel@tonic-gate j++; 1718*0Sstevel@tonic-gate ncp = strchr(cp, ARG_DELIM); 1719*0Sstevel@tonic-gate if (ncp == NULL) 1720*0Sstevel@tonic-gate break; 1721*0Sstevel@tonic-gate *ncp = '\0'; 1722*0Sstevel@tonic-gate cp = ncp + 1; 1723*0Sstevel@tonic-gate } 1724*0Sstevel@tonic-gate } 1725*0Sstevel@tonic-gate } 1726*0Sstevel@tonic-gate assert(j == napids_to_list); 1727*0Sstevel@tonic-gate } else { 1728*0Sstevel@tonic-gate napids_to_list = 0; 1729*0Sstevel@tonic-gate arg_array = NULL; 1730*0Sstevel@tonic-gate } 1731*0Sstevel@tonic-gate 1732*0Sstevel@tonic-gate assert(nlist != 0); 1733*0Sstevel@tonic-gate 1734*0Sstevel@tonic-gate out_array = config_calloc_check(nlist, sizeof (*out_array)); 1735*0Sstevel@tonic-gate if (out_array == NULL) { 1736*0Sstevel@tonic-gate ret = CFGA_LIB_ERROR; 1737*0Sstevel@tonic-gate goto out; 1738*0Sstevel@tonic-gate } 1739*0Sstevel@tonic-gate 1740*0Sstevel@tonic-gate 1741*0Sstevel@tonic-gate /* create a list of output stat data */ 1742*0Sstevel@tonic-gate for (i = 0; i < nlist; i++) { 1743*0Sstevel@tonic-gate out_array[i].ldatap = &statlist[i]; 1744*0Sstevel@tonic-gate out_array[i].req = 0; 1745*0Sstevel@tonic-gate } 1746*0Sstevel@tonic-gate 1747*0Sstevel@tonic-gate /* 1748*0Sstevel@tonic-gate * Mark all user input which got atleast 1 stat data in response 1749*0Sstevel@tonic-gate */ 1750*0Sstevel@tonic-gate for (i = 0; i < napids_to_list; i++) { 1751*0Sstevel@tonic-gate arg_got_resp(&arg_array[i], out_array, nlist, dyn_exp); 1752*0Sstevel@tonic-gate } 1753*0Sstevel@tonic-gate 1754*0Sstevel@tonic-gate /* 1755*0Sstevel@tonic-gate * Process output data 1756*0Sstevel@tonic-gate */ 1757*0Sstevel@tonic-gate nsel = 0; 1758*0Sstevel@tonic-gate for (i = 0; i < nlist; i++) { 1759*0Sstevel@tonic-gate /* 1760*0Sstevel@tonic-gate * Mark all the stats which were actually requested by user 1761*0Sstevel@tonic-gate */ 1762*0Sstevel@tonic-gate out_was_req(&out_array[i], arg_array, napids_to_list, 0); 1763*0Sstevel@tonic-gate if (out_array[i].req == 0 && dyn_exp) { 1764*0Sstevel@tonic-gate /* 1765*0Sstevel@tonic-gate * Try again without the dynamic component for the 1766*0Sstevel@tonic-gate * if dynamic expansion was requested. 1767*0Sstevel@tonic-gate */ 1768*0Sstevel@tonic-gate out_was_req(&out_array[i], arg_array, 1769*0Sstevel@tonic-gate napids_to_list, 1); 1770*0Sstevel@tonic-gate } 1771*0Sstevel@tonic-gate 1772*0Sstevel@tonic-gate /* 1773*0Sstevel@tonic-gate * post filter data which was actually requested 1774*0Sstevel@tonic-gate */ 1775*0Sstevel@tonic-gate if (out_array[i].req == 1) { 1776*0Sstevel@tonic-gate do_post_filter(&out_array[i], post_filtp, &nsel); 1777*0Sstevel@tonic-gate } 1778*0Sstevel@tonic-gate } 1779*0Sstevel@tonic-gate 1780*0Sstevel@tonic-gate sel_boards = config_calloc_check(nsel, sizeof (*sel_boards)); 1781*0Sstevel@tonic-gate if (sel_boards == NULL) { 1782*0Sstevel@tonic-gate ret = CFGA_LIB_ERROR; 1783*0Sstevel@tonic-gate goto out; 1784*0Sstevel@tonic-gate } 1785*0Sstevel@tonic-gate 1786*0Sstevel@tonic-gate for (i = 0, j = 0; i < nlist; i++) { 1787*0Sstevel@tonic-gate if (out_array[i].req == 1) { 1788*0Sstevel@tonic-gate sel_boards[j] = out_array[i].ldatap; 1789*0Sstevel@tonic-gate j++; 1790*0Sstevel@tonic-gate } 1791*0Sstevel@tonic-gate } 1792*0Sstevel@tonic-gate 1793*0Sstevel@tonic-gate assert(j == nsel); 1794*0Sstevel@tonic-gate 1795*0Sstevel@tonic-gate /* 1796*0Sstevel@tonic-gate * Print headings even if no list entries - Bug or feature ? 1797*0Sstevel@tonic-gate */ 1798*0Sstevel@tonic-gate if (!noheadings && prnt_list != NULL) { 1799*0Sstevel@tonic-gate if ((ret = print_fields(nprcols, prnt_list, 1, 0, 1800*0Sstevel@tonic-gate delimp, NULL, fp)) != CFGA_OK) { 1801*0Sstevel@tonic-gate goto out; 1802*0Sstevel@tonic-gate } 1803*0Sstevel@tonic-gate if (ncols2 != 0) { 1804*0Sstevel@tonic-gate if ((ret = print_fields(nprcols, prnt_list, 1, 1805*0Sstevel@tonic-gate 1, delimp, NULL, fp)) != CFGA_OK) { 1806*0Sstevel@tonic-gate goto out; 1807*0Sstevel@tonic-gate } 1808*0Sstevel@tonic-gate } 1809*0Sstevel@tonic-gate } 1810*0Sstevel@tonic-gate 1811*0Sstevel@tonic-gate if (nsel != 0) { 1812*0Sstevel@tonic-gate if (sort_list != NULL && nsel > 1) { 1813*0Sstevel@tonic-gate qsort(sel_boards, nsel, sizeof (sel_boards[0]), 1814*0Sstevel@tonic-gate ldata_compare); 1815*0Sstevel@tonic-gate } 1816*0Sstevel@tonic-gate 1817*0Sstevel@tonic-gate if (prnt_list != NULL) { 1818*0Sstevel@tonic-gate for (i = 0; i < nsel; i++) { 1819*0Sstevel@tonic-gate if ((ret = print_fields(nprcols, 1820*0Sstevel@tonic-gate prnt_list, 0, 0, delimp, sel_boards[i], fp)) 1821*0Sstevel@tonic-gate != CFGA_OK) 1822*0Sstevel@tonic-gate goto out; 1823*0Sstevel@tonic-gate if (ncols2 != 0) { 1824*0Sstevel@tonic-gate if ((ret = print_fields( 1825*0Sstevel@tonic-gate nprcols, prnt_list, 0, 1, delimp, 1826*0Sstevel@tonic-gate sel_boards[i], fp)) != CFGA_OK) 1827*0Sstevel@tonic-gate goto out; 1828*0Sstevel@tonic-gate } 1829*0Sstevel@tonic-gate } 1830*0Sstevel@tonic-gate } 1831*0Sstevel@tonic-gate } 1832*0Sstevel@tonic-gate /* 1833*0Sstevel@tonic-gate * Go thru the argument list and notify user about args 1834*0Sstevel@tonic-gate * which did not have a match 1835*0Sstevel@tonic-gate */ 1836*0Sstevel@tonic-gate report_no_response(arg_array, napids_to_list); 1837*0Sstevel@tonic-gate ret = CFGA_OK; 1838*0Sstevel@tonic-gate /*FALLTHRU*/ 1839*0Sstevel@tonic-gate out: 1840*0Sstevel@tonic-gate S_FREE(sel_boards); 1841*0Sstevel@tonic-gate S_FREE(arg_array); 1842*0Sstevel@tonic-gate S_FREE(out_array); 1843*0Sstevel@tonic-gate 1844*0Sstevel@tonic-gate S_FREE(sort_list); 1845*0Sstevel@tonic-gate S_FREE(prnt_list); 1846*0Sstevel@tonic-gate 1847*0Sstevel@tonic-gate return (ret); 1848*0Sstevel@tonic-gate } 1849*0Sstevel@tonic-gate 1850*0Sstevel@tonic-gate 1851*0Sstevel@tonic-gate /* 1852*0Sstevel@tonic-gate * Mark all user inputs which got a response 1853*0Sstevel@tonic-gate */ 1854*0Sstevel@tonic-gate static void 1855*0Sstevel@tonic-gate arg_got_resp(ap_arg_t *inp, ap_out_t *out_array, int nouts, int dyn_exp) 1856*0Sstevel@tonic-gate { 1857*0Sstevel@tonic-gate int i; 1858*0Sstevel@tonic-gate cfga_ap_types_t type; 1859*0Sstevel@tonic-gate 1860*0Sstevel@tonic-gate 1861*0Sstevel@tonic-gate if (nouts == 0) { 1862*0Sstevel@tonic-gate return; 1863*0Sstevel@tonic-gate } 1864*0Sstevel@tonic-gate 1865*0Sstevel@tonic-gate type = find_arg_type(inp->arg); 1866*0Sstevel@tonic-gate 1867*0Sstevel@tonic-gate /* 1868*0Sstevel@tonic-gate * Go through list of output stats and check if argument 1869*0Sstevel@tonic-gate * produced that output 1870*0Sstevel@tonic-gate */ 1871*0Sstevel@tonic-gate for (i = 0; i < nouts; i++) { 1872*0Sstevel@tonic-gate if (type == PHYSICAL_AP_ID) { 1873*0Sstevel@tonic-gate if (config_ap_id_cmp(out_array[i].ldatap->ap_phys_id, 1874*0Sstevel@tonic-gate inp->arg) == 0) { 1875*0Sstevel@tonic-gate break; 1876*0Sstevel@tonic-gate } 1877*0Sstevel@tonic-gate } else if (type == LOGICAL_AP_ID) { 1878*0Sstevel@tonic-gate if (config_ap_id_cmp(out_array[i].ldatap->ap_log_id, 1879*0Sstevel@tonic-gate inp->arg) == 0) { 1880*0Sstevel@tonic-gate break; 1881*0Sstevel@tonic-gate } 1882*0Sstevel@tonic-gate } else if (type == AP_TYPE) { 1883*0Sstevel@tonic-gate /* 1884*0Sstevel@tonic-gate * An AP_TYPE argument cannot generate dynamic 1885*0Sstevel@tonic-gate * attachment point stats unless dynamic expansion was 1886*0Sstevel@tonic-gate * requested by user. 1887*0Sstevel@tonic-gate */ 1888*0Sstevel@tonic-gate if (!dyn_exp && get_dyn(out_array[i].ldatap->ap_log_id) 1889*0Sstevel@tonic-gate != NULL) { 1890*0Sstevel@tonic-gate continue; 1891*0Sstevel@tonic-gate } 1892*0Sstevel@tonic-gate 1893*0Sstevel@tonic-gate if (strncmp(out_array[i].ldatap->ap_log_id, inp->arg, 1894*0Sstevel@tonic-gate strlen(inp->arg)) == 0) { 1895*0Sstevel@tonic-gate break; 1896*0Sstevel@tonic-gate } 1897*0Sstevel@tonic-gate } else { 1898*0Sstevel@tonic-gate return; 1899*0Sstevel@tonic-gate } 1900*0Sstevel@tonic-gate } 1901*0Sstevel@tonic-gate 1902*0Sstevel@tonic-gate if (i < nouts) { 1903*0Sstevel@tonic-gate inp->resp = 1; 1904*0Sstevel@tonic-gate } 1905*0Sstevel@tonic-gate } 1906*0Sstevel@tonic-gate 1907*0Sstevel@tonic-gate /* Mark all stat data which were requested by user */ 1908*0Sstevel@tonic-gate static void 1909*0Sstevel@tonic-gate out_was_req(ap_out_t *outp, ap_arg_t *in_array, int nargs, int no_dyn) 1910*0Sstevel@tonic-gate { 1911*0Sstevel@tonic-gate int i; 1912*0Sstevel@tonic-gate cfga_ap_types_t type = UNKNOWN_AP; 1913*0Sstevel@tonic-gate char physid[MAXPATHLEN], logid[MAXPATHLEN]; 1914*0Sstevel@tonic-gate 1915*0Sstevel@tonic-gate 1916*0Sstevel@tonic-gate /* If no user args, all output is acceptable */ 1917*0Sstevel@tonic-gate if (nargs == 0) { 1918*0Sstevel@tonic-gate outp->req = 1; 1919*0Sstevel@tonic-gate return; 1920*0Sstevel@tonic-gate } 1921*0Sstevel@tonic-gate 1922*0Sstevel@tonic-gate 1923*0Sstevel@tonic-gate (void) snprintf(physid, sizeof (physid), "%s", 1924*0Sstevel@tonic-gate outp->ldatap->ap_phys_id); 1925*0Sstevel@tonic-gate (void) snprintf(logid, sizeof (logid), "%s", outp->ldatap->ap_log_id); 1926*0Sstevel@tonic-gate 1927*0Sstevel@tonic-gate /* 1928*0Sstevel@tonic-gate * Do comparison with or without dynamic component as requested by 1929*0Sstevel@tonic-gate * user. 1930*0Sstevel@tonic-gate */ 1931*0Sstevel@tonic-gate if (no_dyn) { 1932*0Sstevel@tonic-gate /* Remove the dynamic component */ 1933*0Sstevel@tonic-gate remove_dyn(physid); 1934*0Sstevel@tonic-gate remove_dyn(logid); 1935*0Sstevel@tonic-gate } 1936*0Sstevel@tonic-gate 1937*0Sstevel@tonic-gate for (i = 0; i < nargs; i++) { 1938*0Sstevel@tonic-gate type = find_arg_type(in_array[i].arg); 1939*0Sstevel@tonic-gate if (type == PHYSICAL_AP_ID) { 1940*0Sstevel@tonic-gate 1941*0Sstevel@tonic-gate if (config_ap_id_cmp(in_array[i].arg, physid) == 0) { 1942*0Sstevel@tonic-gate break; 1943*0Sstevel@tonic-gate } 1944*0Sstevel@tonic-gate } else if (type == LOGICAL_AP_ID) { 1945*0Sstevel@tonic-gate 1946*0Sstevel@tonic-gate if (config_ap_id_cmp(in_array[i].arg, logid) == 0) { 1947*0Sstevel@tonic-gate break; 1948*0Sstevel@tonic-gate } 1949*0Sstevel@tonic-gate } else if (type == AP_TYPE) { 1950*0Sstevel@tonic-gate /* 1951*0Sstevel@tonic-gate * Aptypes cannot generate dynamic attachment 1952*0Sstevel@tonic-gate * points unless dynamic expansion is specified. 1953*0Sstevel@tonic-gate * in which case this routine would be called a 1954*0Sstevel@tonic-gate * 2nd time with the no_dyn flag set and there 1955*0Sstevel@tonic-gate * would be no dynamic ap_ids. 1956*0Sstevel@tonic-gate */ 1957*0Sstevel@tonic-gate if (get_dyn(logid) != NULL) { 1958*0Sstevel@tonic-gate continue; 1959*0Sstevel@tonic-gate } 1960*0Sstevel@tonic-gate 1961*0Sstevel@tonic-gate if (strncmp(in_array[i].arg, logid, 1962*0Sstevel@tonic-gate strlen(in_array[i].arg)) == 0) { 1963*0Sstevel@tonic-gate break; 1964*0Sstevel@tonic-gate } 1965*0Sstevel@tonic-gate } else { 1966*0Sstevel@tonic-gate continue; 1967*0Sstevel@tonic-gate } 1968*0Sstevel@tonic-gate } 1969*0Sstevel@tonic-gate 1970*0Sstevel@tonic-gate if (i < nargs) { 1971*0Sstevel@tonic-gate /* Ok, this output was requested */ 1972*0Sstevel@tonic-gate outp->req = 1; 1973*0Sstevel@tonic-gate } 1974*0Sstevel@tonic-gate 1975*0Sstevel@tonic-gate } 1976*0Sstevel@tonic-gate 1977*0Sstevel@tonic-gate static void 1978*0Sstevel@tonic-gate do_post_filter(ap_out_t *outp, post_filter_t *post_filtp, int *nselp) 1979*0Sstevel@tonic-gate { 1980*0Sstevel@tonic-gate int i; 1981*0Sstevel@tonic-gate 1982*0Sstevel@tonic-gate if (outp->req != 1) { 1983*0Sstevel@tonic-gate return; 1984*0Sstevel@tonic-gate } 1985*0Sstevel@tonic-gate 1986*0Sstevel@tonic-gate /* 1987*0Sstevel@tonic-gate * For fields without filtering (CFGA_MATCH_NOFILTER), 1988*0Sstevel@tonic-gate * compare always returns 0 (success) 1989*0Sstevel@tonic-gate */ 1990*0Sstevel@tonic-gate for (i = 0; i < N_FIELDS; i++) { 1991*0Sstevel@tonic-gate /* 1992*0Sstevel@tonic-gate * Note: Order is important for partial match (via strncmp). 1993*0Sstevel@tonic-gate * The first argument for compare must be the filter. 1994*0Sstevel@tonic-gate */ 1995*0Sstevel@tonic-gate if (all_fields[i].compare(&post_filtp->ldata, outp->ldatap, 1996*0Sstevel@tonic-gate post_filtp->match_type_p[i])) { 1997*0Sstevel@tonic-gate outp->req = 0; /* Blocked by filter */ 1998*0Sstevel@tonic-gate return; 1999*0Sstevel@tonic-gate } 2000*0Sstevel@tonic-gate } 2001*0Sstevel@tonic-gate 2002*0Sstevel@tonic-gate /* 2003*0Sstevel@tonic-gate * Passed through filter 2004*0Sstevel@tonic-gate */ 2005*0Sstevel@tonic-gate (*nselp)++; 2006*0Sstevel@tonic-gate } 2007*0Sstevel@tonic-gate 2008*0Sstevel@tonic-gate static void 2009*0Sstevel@tonic-gate report_no_response(ap_arg_t *arg_array, int nargs) 2010*0Sstevel@tonic-gate { 2011*0Sstevel@tonic-gate int i; 2012*0Sstevel@tonic-gate 2013*0Sstevel@tonic-gate if (nargs == 0) { 2014*0Sstevel@tonic-gate return; 2015*0Sstevel@tonic-gate } 2016*0Sstevel@tonic-gate 2017*0Sstevel@tonic-gate 2018*0Sstevel@tonic-gate /* 2019*0Sstevel@tonic-gate * nop if no user arguments 2020*0Sstevel@tonic-gate */ 2021*0Sstevel@tonic-gate for (i = 0; i < nargs; i++) { 2022*0Sstevel@tonic-gate if (arg_array[i].resp == 0) { 2023*0Sstevel@tonic-gate (void) fprintf(stderr, 2024*0Sstevel@tonic-gate gettext("%s: No matching library found\n"), 2025*0Sstevel@tonic-gate arg_array[i].arg); 2026*0Sstevel@tonic-gate } 2027*0Sstevel@tonic-gate } 2028*0Sstevel@tonic-gate } 2029*0Sstevel@tonic-gate 2030*0Sstevel@tonic-gate /* 2031*0Sstevel@tonic-gate * ldata_compare - compare two attachment point list data structures. 2032*0Sstevel@tonic-gate */ 2033*0Sstevel@tonic-gate static int 2034*0Sstevel@tonic-gate ldata_compare( 2035*0Sstevel@tonic-gate const void *vb1, 2036*0Sstevel@tonic-gate const void *vb2) 2037*0Sstevel@tonic-gate { 2038*0Sstevel@tonic-gate int i; 2039*0Sstevel@tonic-gate int res = -1; 2040*0Sstevel@tonic-gate cfga_list_data_t *b1, *b2; 2041*0Sstevel@tonic-gate 2042*0Sstevel@tonic-gate 2043*0Sstevel@tonic-gate b1 = *(cfga_list_data_t **)vb1; 2044*0Sstevel@tonic-gate b2 = *(cfga_list_data_t **)vb2; 2045*0Sstevel@tonic-gate 2046*0Sstevel@tonic-gate for (i = 0; i < nsort_list; i++) { 2047*0Sstevel@tonic-gate res = (*(sort_list[i].fld->compare))(b1, b2, CFGA_MATCH_ORDER); 2048*0Sstevel@tonic-gate if (res != 0) { 2049*0Sstevel@tonic-gate if (sort_list[i].reverse) 2050*0Sstevel@tonic-gate res = -res; 2051*0Sstevel@tonic-gate break; 2052*0Sstevel@tonic-gate } 2053*0Sstevel@tonic-gate } 2054*0Sstevel@tonic-gate 2055*0Sstevel@tonic-gate return (res); 2056*0Sstevel@tonic-gate } 2057*0Sstevel@tonic-gate 2058*0Sstevel@tonic-gate /* 2059*0Sstevel@tonic-gate * count_fields - Count the number of fields, using supplied delimiter. 2060*0Sstevel@tonic-gate */ 2061*0Sstevel@tonic-gate static int 2062*0Sstevel@tonic-gate count_fields(char *fspec, char delim) 2063*0Sstevel@tonic-gate { 2064*0Sstevel@tonic-gate char *cp = NULL; 2065*0Sstevel@tonic-gate int n; 2066*0Sstevel@tonic-gate 2067*0Sstevel@tonic-gate if (fspec == 0 || *fspec == '\0') 2068*0Sstevel@tonic-gate return (0); 2069*0Sstevel@tonic-gate n = 1; 2070*0Sstevel@tonic-gate for (cp = fspec; *cp != '\0'; cp++) 2071*0Sstevel@tonic-gate if (*cp == delim) 2072*0Sstevel@tonic-gate n++; 2073*0Sstevel@tonic-gate return (n); 2074*0Sstevel@tonic-gate } 2075*0Sstevel@tonic-gate 2076*0Sstevel@tonic-gate /* 2077*0Sstevel@tonic-gate * get_field 2078*0Sstevel@tonic-gate * This function is not a re-implementation of strtok(). 2079*0Sstevel@tonic-gate * There can be null fields - strtok() eats spans of delimiters. 2080*0Sstevel@tonic-gate */ 2081*0Sstevel@tonic-gate static char * 2082*0Sstevel@tonic-gate get_field(char **fspp) 2083*0Sstevel@tonic-gate { 2084*0Sstevel@tonic-gate char *cp = NULL, *fld; 2085*0Sstevel@tonic-gate 2086*0Sstevel@tonic-gate fld = *fspp; 2087*0Sstevel@tonic-gate 2088*0Sstevel@tonic-gate if (fld != NULL && *fld == '\0') 2089*0Sstevel@tonic-gate fld = NULL; 2090*0Sstevel@tonic-gate 2091*0Sstevel@tonic-gate if (fld != NULL) { 2092*0Sstevel@tonic-gate cp = strchr(*fspp, FDELIM); 2093*0Sstevel@tonic-gate if (cp == NULL) { 2094*0Sstevel@tonic-gate *fspp = NULL; 2095*0Sstevel@tonic-gate } else { 2096*0Sstevel@tonic-gate *cp = '\0'; 2097*0Sstevel@tonic-gate *fspp = cp + 1; 2098*0Sstevel@tonic-gate if (*fld == '\0') 2099*0Sstevel@tonic-gate fld = NULL; 2100*0Sstevel@tonic-gate } 2101*0Sstevel@tonic-gate } 2102*0Sstevel@tonic-gate return (fld); 2103*0Sstevel@tonic-gate } 2104*0Sstevel@tonic-gate 2105*0Sstevel@tonic-gate /* 2106*0Sstevel@tonic-gate * process_fields - 2107*0Sstevel@tonic-gate */ 2108*0Sstevel@tonic-gate static int 2109*0Sstevel@tonic-gate process_fields( 2110*0Sstevel@tonic-gate int ncol, 2111*0Sstevel@tonic-gate struct print_col *list, 2112*0Sstevel@tonic-gate int line2, 2113*0Sstevel@tonic-gate char *fmt) 2114*0Sstevel@tonic-gate { 2115*0Sstevel@tonic-gate struct print_col *pp = NULL; 2116*0Sstevel@tonic-gate struct field_info *fldp = NULL; 2117*0Sstevel@tonic-gate char *fmtx; 2118*0Sstevel@tonic-gate char *fldn; 2119*0Sstevel@tonic-gate int err; 2120*0Sstevel@tonic-gate 2121*0Sstevel@tonic-gate err = 0; 2122*0Sstevel@tonic-gate fmtx = fmt; 2123*0Sstevel@tonic-gate for (pp = list; pp < &list[ncol]; pp++) { 2124*0Sstevel@tonic-gate fldn = get_field(&fmtx); 2125*0Sstevel@tonic-gate fldp = &null_field; 2126*0Sstevel@tonic-gate if (fldn != NULL) { 2127*0Sstevel@tonic-gate struct field_info *tfldp; 2128*0Sstevel@tonic-gate 2129*0Sstevel@tonic-gate tfldp = find_field(fldn); 2130*0Sstevel@tonic-gate if (tfldp != NULL) { 2131*0Sstevel@tonic-gate fldp = tfldp; 2132*0Sstevel@tonic-gate } else { 2133*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(unk_field), 2134*0Sstevel@tonic-gate cmdname, fldn); 2135*0Sstevel@tonic-gate err = 1; 2136*0Sstevel@tonic-gate } 2137*0Sstevel@tonic-gate } 2138*0Sstevel@tonic-gate if (line2) { 2139*0Sstevel@tonic-gate pp->line2 = fldp; 2140*0Sstevel@tonic-gate if (fldp->width > pp->width) 2141*0Sstevel@tonic-gate pp->width = fldp->width; 2142*0Sstevel@tonic-gate } else { 2143*0Sstevel@tonic-gate pp->line1 = fldp; 2144*0Sstevel@tonic-gate pp->width = fldp->width; 2145*0Sstevel@tonic-gate } 2146*0Sstevel@tonic-gate } 2147*0Sstevel@tonic-gate return (err); 2148*0Sstevel@tonic-gate } 2149*0Sstevel@tonic-gate 2150*0Sstevel@tonic-gate /* 2151*0Sstevel@tonic-gate * process_sort_fields - 2152*0Sstevel@tonic-gate */ 2153*0Sstevel@tonic-gate static int 2154*0Sstevel@tonic-gate process_sort_fields( 2155*0Sstevel@tonic-gate int nsort, 2156*0Sstevel@tonic-gate struct sort_el *list, 2157*0Sstevel@tonic-gate char *fmt) 2158*0Sstevel@tonic-gate { 2159*0Sstevel@tonic-gate int i; 2160*0Sstevel@tonic-gate int rev; 2161*0Sstevel@tonic-gate struct field_info *fldp = NULL; 2162*0Sstevel@tonic-gate char *fmtx; 2163*0Sstevel@tonic-gate char *fldn; 2164*0Sstevel@tonic-gate int err; 2165*0Sstevel@tonic-gate 2166*0Sstevel@tonic-gate err = 0; 2167*0Sstevel@tonic-gate fmtx = fmt; 2168*0Sstevel@tonic-gate for (i = 0; i < nsort; i++) { 2169*0Sstevel@tonic-gate fldn = get_field(&fmtx); 2170*0Sstevel@tonic-gate fldp = &null_field; 2171*0Sstevel@tonic-gate rev = 0; 2172*0Sstevel@tonic-gate if (fldn != NULL) { 2173*0Sstevel@tonic-gate struct field_info *tfldp = NULL; 2174*0Sstevel@tonic-gate 2175*0Sstevel@tonic-gate if (*fldn == '-') { 2176*0Sstevel@tonic-gate rev = 1; 2177*0Sstevel@tonic-gate fldn++; 2178*0Sstevel@tonic-gate } 2179*0Sstevel@tonic-gate tfldp = find_field(fldn); 2180*0Sstevel@tonic-gate if (tfldp != NULL) { 2181*0Sstevel@tonic-gate fldp = tfldp; 2182*0Sstevel@tonic-gate } else { 2183*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(unk_field), 2184*0Sstevel@tonic-gate cmdname, fldn); 2185*0Sstevel@tonic-gate err = 1; 2186*0Sstevel@tonic-gate } 2187*0Sstevel@tonic-gate } 2188*0Sstevel@tonic-gate list[i].reverse = rev; 2189*0Sstevel@tonic-gate list[i].fld = fldp; 2190*0Sstevel@tonic-gate } 2191*0Sstevel@tonic-gate return (err); 2192*0Sstevel@tonic-gate } 2193*0Sstevel@tonic-gate 2194*0Sstevel@tonic-gate /* 2195*0Sstevel@tonic-gate * print_fields - 2196*0Sstevel@tonic-gate */ 2197*0Sstevel@tonic-gate static cfga_err_t 2198*0Sstevel@tonic-gate print_fields( 2199*0Sstevel@tonic-gate int ncol, 2200*0Sstevel@tonic-gate struct print_col *list, 2201*0Sstevel@tonic-gate int heading, 2202*0Sstevel@tonic-gate int line2, 2203*0Sstevel@tonic-gate char *delim, 2204*0Sstevel@tonic-gate cfga_list_data_t *bdp, 2205*0Sstevel@tonic-gate FILE *fp) 2206*0Sstevel@tonic-gate { 2207*0Sstevel@tonic-gate char *del = NULL; 2208*0Sstevel@tonic-gate struct print_col *pp = NULL; 2209*0Sstevel@tonic-gate struct field_info *fldp = NULL; 2210*0Sstevel@tonic-gate static char *outline, *end; 2211*0Sstevel@tonic-gate char *lp; 2212*0Sstevel@tonic-gate 2213*0Sstevel@tonic-gate if (outline == NULL) { 2214*0Sstevel@tonic-gate int out_len, delim_len; 2215*0Sstevel@tonic-gate 2216*0Sstevel@tonic-gate delim_len = strlen(delim); 2217*0Sstevel@tonic-gate out_len = 0; 2218*0Sstevel@tonic-gate for (pp = list; pp < &list[ncol]; pp++) { 2219*0Sstevel@tonic-gate out_len += pp->width; 2220*0Sstevel@tonic-gate out_len += delim_len; 2221*0Sstevel@tonic-gate } 2222*0Sstevel@tonic-gate out_len -= delim_len; 2223*0Sstevel@tonic-gate outline = config_calloc_check(out_len + 1, 1); 2224*0Sstevel@tonic-gate if (outline == NULL) { 2225*0Sstevel@tonic-gate return (CFGA_LIB_ERROR); 2226*0Sstevel@tonic-gate } 2227*0Sstevel@tonic-gate end = &outline[out_len + 1]; 2228*0Sstevel@tonic-gate } 2229*0Sstevel@tonic-gate 2230*0Sstevel@tonic-gate lp = outline; 2231*0Sstevel@tonic-gate del = ""; 2232*0Sstevel@tonic-gate for (pp = list; pp < &list[ncol]; pp++) { 2233*0Sstevel@tonic-gate fldp = line2 ? pp->line2 : pp->line1; 2234*0Sstevel@tonic-gate (void) snprintf(lp, end - lp, "%s", del); 2235*0Sstevel@tonic-gate lp += strlen(lp); 2236*0Sstevel@tonic-gate if (heading) { 2237*0Sstevel@tonic-gate (void) snprintf(lp, end - lp, "%-*s", 2238*0Sstevel@tonic-gate fldp->width, fldp->heading); 2239*0Sstevel@tonic-gate } else { 2240*0Sstevel@tonic-gate (*fldp->printfn)(bdp, fldp->width, lp); 2241*0Sstevel@tonic-gate } 2242*0Sstevel@tonic-gate lp += strlen(lp); 2243*0Sstevel@tonic-gate del = delim; 2244*0Sstevel@tonic-gate } 2245*0Sstevel@tonic-gate 2246*0Sstevel@tonic-gate /* 2247*0Sstevel@tonic-gate * Trim trailing spaces 2248*0Sstevel@tonic-gate */ 2249*0Sstevel@tonic-gate while (--lp >= outline && *lp == ' ') 2250*0Sstevel@tonic-gate *lp = '\0'; 2251*0Sstevel@tonic-gate (void) fprintf(fp, "%s\n", outline); 2252*0Sstevel@tonic-gate return (CFGA_OK); 2253*0Sstevel@tonic-gate } 2254*0Sstevel@tonic-gate 2255*0Sstevel@tonic-gate /* 2256*0Sstevel@tonic-gate * config_calloc_check - perform allocation, check result and 2257*0Sstevel@tonic-gate * set error indicator 2258*0Sstevel@tonic-gate */ 2259*0Sstevel@tonic-gate static void * 2260*0Sstevel@tonic-gate config_calloc_check( 2261*0Sstevel@tonic-gate size_t nelem, 2262*0Sstevel@tonic-gate size_t elsize) 2263*0Sstevel@tonic-gate { 2264*0Sstevel@tonic-gate void *p; 2265*0Sstevel@tonic-gate static char alloc_fail[] = 2266*0Sstevel@tonic-gate "%s: memory allocation failed (%d*%d bytes)\n"; 2267*0Sstevel@tonic-gate 2268*0Sstevel@tonic-gate 2269*0Sstevel@tonic-gate p = calloc(nelem, elsize); 2270*0Sstevel@tonic-gate if (p == NULL) { 2271*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(alloc_fail), cmdname, 2272*0Sstevel@tonic-gate nelem, elsize); 2273*0Sstevel@tonic-gate } 2274*0Sstevel@tonic-gate return (p); 2275*0Sstevel@tonic-gate } 2276*0Sstevel@tonic-gate 2277*0Sstevel@tonic-gate /* 2278*0Sstevel@tonic-gate * find_arg_type - determine if an argument is an ap_id or an ap_type. 2279*0Sstevel@tonic-gate */ 2280*0Sstevel@tonic-gate static cfga_ap_types_t 2281*0Sstevel@tonic-gate find_arg_type(const char *ap_id) 2282*0Sstevel@tonic-gate { 2283*0Sstevel@tonic-gate struct stat sbuf; 2284*0Sstevel@tonic-gate cfga_ap_types_t type; 2285*0Sstevel@tonic-gate char *mkr = NULL, *cp; 2286*0Sstevel@tonic-gate int size_ap = 0, size_mkr = 0, digit = 0, i = 0; 2287*0Sstevel@tonic-gate char path[MAXPATHLEN]; 2288*0Sstevel@tonic-gate char apbuf[MAXPATHLEN]; 2289*0Sstevel@tonic-gate size_t len; 2290*0Sstevel@tonic-gate 2291*0Sstevel@tonic-gate 2292*0Sstevel@tonic-gate /* 2293*0Sstevel@tonic-gate * sanity checks 2294*0Sstevel@tonic-gate */ 2295*0Sstevel@tonic-gate if (ap_id == NULL || *ap_id == '\0') { 2296*0Sstevel@tonic-gate return (UNKNOWN_AP); 2297*0Sstevel@tonic-gate } 2298*0Sstevel@tonic-gate 2299*0Sstevel@tonic-gate /* 2300*0Sstevel@tonic-gate * Mask the dynamic component if any 2301*0Sstevel@tonic-gate */ 2302*0Sstevel@tonic-gate if ((cp = GET_DYN(ap_id)) != NULL) { 2303*0Sstevel@tonic-gate len = cp - ap_id; 2304*0Sstevel@tonic-gate } else { 2305*0Sstevel@tonic-gate len = strlen(ap_id); 2306*0Sstevel@tonic-gate } 2307*0Sstevel@tonic-gate 2308*0Sstevel@tonic-gate if (len >= sizeof (apbuf)) { 2309*0Sstevel@tonic-gate return (UNKNOWN_AP); 2310*0Sstevel@tonic-gate } 2311*0Sstevel@tonic-gate 2312*0Sstevel@tonic-gate (void) strncpy(apbuf, ap_id, len); 2313*0Sstevel@tonic-gate apbuf[len] = '\0'; 2314*0Sstevel@tonic-gate 2315*0Sstevel@tonic-gate /* 2316*0Sstevel@tonic-gate * If it starts with a slash and is stat-able 2317*0Sstevel@tonic-gate * its a physical. 2318*0Sstevel@tonic-gate */ 2319*0Sstevel@tonic-gate if (*apbuf == '/' && stat(apbuf, &sbuf) == 0) { 2320*0Sstevel@tonic-gate return (PHYSICAL_AP_ID); 2321*0Sstevel@tonic-gate } 2322*0Sstevel@tonic-gate 2323*0Sstevel@tonic-gate /* 2324*0Sstevel@tonic-gate * Is this a symlink in CFGA_DEV_DIR ? 2325*0Sstevel@tonic-gate */ 2326*0Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s/%s", CFGA_DEV_DIR, apbuf); 2327*0Sstevel@tonic-gate 2328*0Sstevel@tonic-gate if (lstat(path, &sbuf) == 0 && S_ISLNK(sbuf.st_mode) && 2329*0Sstevel@tonic-gate stat(path, &sbuf) == 0) { 2330*0Sstevel@tonic-gate return (LOGICAL_AP_ID); 2331*0Sstevel@tonic-gate } 2332*0Sstevel@tonic-gate 2333*0Sstevel@tonic-gate /* 2334*0Sstevel@tonic-gate * Check for ":" which is always present in an ap_id but not maybe 2335*0Sstevel@tonic-gate * present or absent in an ap_type. 2336*0Sstevel@tonic-gate * We need to check that the characters right before the : are digits 2337*0Sstevel@tonic-gate * since an ap_id is of the form <name><instance>:<specific ap name> 2338*0Sstevel@tonic-gate */ 2339*0Sstevel@tonic-gate if ((mkr = strchr(apbuf, ':')) == NULL) { 2340*0Sstevel@tonic-gate type = AP_TYPE; 2341*0Sstevel@tonic-gate } else { 2342*0Sstevel@tonic-gate size_ap = strlen(apbuf); 2343*0Sstevel@tonic-gate size_mkr = strlen(mkr); 2344*0Sstevel@tonic-gate mkr = apbuf; 2345*0Sstevel@tonic-gate 2346*0Sstevel@tonic-gate digit = 0; 2347*0Sstevel@tonic-gate for (i = size_ap - size_mkr - 1; i > 0; i--) { 2348*0Sstevel@tonic-gate if ((int)isdigit(mkr[i])) { 2349*0Sstevel@tonic-gate digit++; 2350*0Sstevel@tonic-gate break; 2351*0Sstevel@tonic-gate } 2352*0Sstevel@tonic-gate } 2353*0Sstevel@tonic-gate if (digit == 0) { 2354*0Sstevel@tonic-gate type = AP_TYPE; 2355*0Sstevel@tonic-gate } else { 2356*0Sstevel@tonic-gate type = LOGICAL_AP_ID; 2357*0Sstevel@tonic-gate } 2358*0Sstevel@tonic-gate } 2359*0Sstevel@tonic-gate 2360*0Sstevel@tonic-gate return (type); 2361*0Sstevel@tonic-gate } 2362*0Sstevel@tonic-gate 2363*0Sstevel@tonic-gate 2364*0Sstevel@tonic-gate static char * 2365*0Sstevel@tonic-gate get_dyn(const char *ap_id) 2366*0Sstevel@tonic-gate { 2367*0Sstevel@tonic-gate if (ap_id == NULL) { 2368*0Sstevel@tonic-gate return (NULL); 2369*0Sstevel@tonic-gate } 2370*0Sstevel@tonic-gate 2371*0Sstevel@tonic-gate return (strstr(ap_id, CFGA_DYN_SEP)); 2372*0Sstevel@tonic-gate } 2373*0Sstevel@tonic-gate 2374*0Sstevel@tonic-gate /* 2375*0Sstevel@tonic-gate * removes the dynamic component 2376*0Sstevel@tonic-gate */ 2377*0Sstevel@tonic-gate static void 2378*0Sstevel@tonic-gate remove_dyn(char *ap_id) 2379*0Sstevel@tonic-gate { 2380*0Sstevel@tonic-gate char *cp; 2381*0Sstevel@tonic-gate 2382*0Sstevel@tonic-gate if (ap_id == NULL) { 2383*0Sstevel@tonic-gate return; 2384*0Sstevel@tonic-gate } 2385*0Sstevel@tonic-gate 2386*0Sstevel@tonic-gate cp = strstr(ap_id, CFGA_DYN_SEP); 2387*0Sstevel@tonic-gate if (cp != NULL) { 2388*0Sstevel@tonic-gate *cp = '\0'; 2389*0Sstevel@tonic-gate } 2390*0Sstevel@tonic-gate } 2391