1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * svcprop - report service configuration properties 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <locale.h> 34*7c478bd9Sstevel@tonic-gate #include <libintl.h> 35*7c478bd9Sstevel@tonic-gate #include <libscf.h> 36*7c478bd9Sstevel@tonic-gate #include <libscf_priv.h> 37*7c478bd9Sstevel@tonic-gate #include <libuutil.h> 38*7c478bd9Sstevel@tonic-gate #include <stddef.h> 39*7c478bd9Sstevel@tonic-gate #include <stdio.h> 40*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 41*7c478bd9Sstevel@tonic-gate #include <unistd.h> 42*7c478bd9Sstevel@tonic-gate #include <strings.h> 43*7c478bd9Sstevel@tonic-gate #include <assert.h> 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN 46*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SUNW_OST_OSCMD" 47*7c478bd9Sstevel@tonic-gate #endif /* TEXT_DOMAIN */ 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate /* 50*7c478bd9Sstevel@tonic-gate * Error functions. These can change if the quiet (-q) option is used. 51*7c478bd9Sstevel@tonic-gate */ 52*7c478bd9Sstevel@tonic-gate static void (*warn)(const char *, ...) = uu_warn; 53*7c478bd9Sstevel@tonic-gate static void (*die)(const char *, ...) = uu_die; 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * Entity encapsulation. This allows me to treat services and instances 57*7c478bd9Sstevel@tonic-gate * similarly, and avoid duplicating process_ent(). 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate typedef struct { 60*7c478bd9Sstevel@tonic-gate char type; /* !=0: service, 0: instance */ 61*7c478bd9Sstevel@tonic-gate union { 62*7c478bd9Sstevel@tonic-gate scf_service_t *svc; 63*7c478bd9Sstevel@tonic-gate scf_instance_t *inst; 64*7c478bd9Sstevel@tonic-gate } u; 65*7c478bd9Sstevel@tonic-gate } scf_entityp_t; 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate #define ENT_INSTANCE 0 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate #define SCF_ENTITY_SET_TO_SERVICE(ent, s) { ent.type = 1; ent.u.svc = s; } 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate #define SCF_ENTITY_SET_TO_INSTANCE(ent, i) \ 72*7c478bd9Sstevel@tonic-gate { ent.type = ENT_INSTANCE; ent.u.inst = i; } 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate #define scf_entity_get_pg(ent, name, pg) \ 75*7c478bd9Sstevel@tonic-gate (ent.type ? scf_service_get_pg(ent.u.svc, name, pg) : \ 76*7c478bd9Sstevel@tonic-gate scf_instance_get_pg(ent.u.inst, name, pg)) 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate #define scf_entity_to_fmri(ent, buf, buf_sz) \ 79*7c478bd9Sstevel@tonic-gate (ent.type ? scf_service_to_fmri(ent.u.svc, buf, buf_sz) : \ 80*7c478bd9Sstevel@tonic-gate scf_instance_to_fmri(ent.u.inst, buf, buf_sz)) 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate #define SCF_ENTITY_TYPE_NAME(ent) (ent.type ? "service" : "instance") 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate /* 85*7c478bd9Sstevel@tonic-gate * Data structure for -p arguments. Since they may be name or name/name, we 86*7c478bd9Sstevel@tonic-gate * just track the components. 87*7c478bd9Sstevel@tonic-gate */ 88*7c478bd9Sstevel@tonic-gate typedef struct svcprop_prop_node { 89*7c478bd9Sstevel@tonic-gate uu_list_node_t spn_list_node; 90*7c478bd9Sstevel@tonic-gate const char *spn_comp1; 91*7c478bd9Sstevel@tonic-gate const char *spn_comp2; 92*7c478bd9Sstevel@tonic-gate } svcprop_prop_node_t; 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate static uu_list_pool_t *prop_pool; 95*7c478bd9Sstevel@tonic-gate static uu_list_t *prop_list; 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate static scf_handle_t *hndl; 98*7c478bd9Sstevel@tonic-gate static ssize_t max_scf_name_length; 99*7c478bd9Sstevel@tonic-gate static ssize_t max_scf_value_length; 100*7c478bd9Sstevel@tonic-gate static ssize_t max_scf_fmri_length; 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* Options */ 103*7c478bd9Sstevel@tonic-gate static int quiet = 0; /* No output. Nothing found, exit(1) */ 104*7c478bd9Sstevel@tonic-gate static int types = 0; /* Display types of properties. */ 105*7c478bd9Sstevel@tonic-gate static int verbose = 0; /* Print not found errors to stderr. */ 106*7c478bd9Sstevel@tonic-gate static int fmris = 0; /* Display full FMRIs for properties. */ 107*7c478bd9Sstevel@tonic-gate static int wait = 0; /* Wait mode. */ 108*7c478bd9Sstevel@tonic-gate static char *snapshot = "running"; /* Snapshot to use. */ 109*7c478bd9Sstevel@tonic-gate static int Cflag = 0; /* C option supplied */ 110*7c478bd9Sstevel@tonic-gate static int cflag = 0; /* c option supplied */ 111*7c478bd9Sstevel@tonic-gate static int sflag = 0; /* s option supplied */ 112*7c478bd9Sstevel@tonic-gate static int return_code; /* main's return code */ 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate #define PRINT_NOPROP_ERRORS (!quiet || verbose) 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate /* 117*7c478bd9Sstevel@tonic-gate * For unexpected libscf errors. The ending newline is necessary to keep 118*7c478bd9Sstevel@tonic-gate * uu_die() from appending the errno error. 119*7c478bd9Sstevel@tonic-gate */ 120*7c478bd9Sstevel@tonic-gate static void 121*7c478bd9Sstevel@tonic-gate scfdie() 122*7c478bd9Sstevel@tonic-gate { 123*7c478bd9Sstevel@tonic-gate die(gettext("Unexpected libscf error: %s. Exiting.\n"), 124*7c478bd9Sstevel@tonic-gate scf_strerror(scf_error())); 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate static void * 128*7c478bd9Sstevel@tonic-gate safe_malloc(size_t sz) 129*7c478bd9Sstevel@tonic-gate { 130*7c478bd9Sstevel@tonic-gate void *p; 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate p = malloc(sz); 133*7c478bd9Sstevel@tonic-gate if (p == NULL) 134*7c478bd9Sstevel@tonic-gate die(gettext("Could not allocate memory")); 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate return (p); 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate static void 140*7c478bd9Sstevel@tonic-gate usage() 141*7c478bd9Sstevel@tonic-gate { 142*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Usage: %1$s [-fqtv] " 143*7c478bd9Sstevel@tonic-gate "[-C | -c | -s snapshot] " 144*7c478bd9Sstevel@tonic-gate "[-p [name/]name]... \n" 145*7c478bd9Sstevel@tonic-gate " {FMRI | pattern}...\n" 146*7c478bd9Sstevel@tonic-gate " %1$s -w [-fqtv] [-p [name/]name] " 147*7c478bd9Sstevel@tonic-gate "{FMRI | pattern}\n"), uu_getpname()); 148*7c478bd9Sstevel@tonic-gate exit(UU_EXIT_USAGE); 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate /* 152*7c478bd9Sstevel@tonic-gate * Return an allocated copy of str, with the Bourne shell's metacharacters 153*7c478bd9Sstevel@tonic-gate * escaped by '\'. 154*7c478bd9Sstevel@tonic-gate * 155*7c478bd9Sstevel@tonic-gate * What about unicode? 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate static char * 158*7c478bd9Sstevel@tonic-gate quote_for_shell(const char *str) 159*7c478bd9Sstevel@tonic-gate { 160*7c478bd9Sstevel@tonic-gate const char *sp; 161*7c478bd9Sstevel@tonic-gate char *dst, *dp; 162*7c478bd9Sstevel@tonic-gate size_t dst_len; 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate const char * const metachars = ";&()|^<>\n \t\\\"\'`"; 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate if (str[0] == '\0') 167*7c478bd9Sstevel@tonic-gate return (strdup("\"\"")); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate dst_len = 0; 170*7c478bd9Sstevel@tonic-gate for (sp = str; *sp != '\0'; ++sp) { 171*7c478bd9Sstevel@tonic-gate ++dst_len; 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate if (strchr(metachars, *sp) != NULL) 174*7c478bd9Sstevel@tonic-gate ++dst_len; 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate if (sp - str == dst_len) 178*7c478bd9Sstevel@tonic-gate return (strdup(str)); 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate dst = safe_malloc(dst_len + 1); 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate for (dp = dst, sp = str; *sp != '\0'; ++dp, ++sp) { 183*7c478bd9Sstevel@tonic-gate if (strchr(metachars, *sp) != NULL) 184*7c478bd9Sstevel@tonic-gate *dp++ = '\\'; 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate *dp = *sp; 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate *dp = '\0'; 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate return (dst); 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate static void 194*7c478bd9Sstevel@tonic-gate print_value(scf_value_t *val) 195*7c478bd9Sstevel@tonic-gate { 196*7c478bd9Sstevel@tonic-gate char *buf, *qbuf; 197*7c478bd9Sstevel@tonic-gate ssize_t bufsz, r; 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate bufsz = scf_value_get_as_string(val, NULL, 0) + 1; 200*7c478bd9Sstevel@tonic-gate if (bufsz - 1 < 0) 201*7c478bd9Sstevel@tonic-gate scfdie(); 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate buf = safe_malloc(bufsz); 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate r = scf_value_get_as_string(val, buf, bufsz); 206*7c478bd9Sstevel@tonic-gate assert(r + 1 == bufsz); 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate qbuf = quote_for_shell(buf); 209*7c478bd9Sstevel@tonic-gate (void) fputs(qbuf, stdout); 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate free(qbuf); 212*7c478bd9Sstevel@tonic-gate free(buf); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate /* 216*7c478bd9Sstevel@tonic-gate * Display a property's values on a line. If types is true, prepend 217*7c478bd9Sstevel@tonic-gate * identification (the FMRI if fmris is true, pg/prop otherwise) and the type 218*7c478bd9Sstevel@tonic-gate * of the property. 219*7c478bd9Sstevel@tonic-gate */ 220*7c478bd9Sstevel@tonic-gate static void 221*7c478bd9Sstevel@tonic-gate display_prop(scf_propertygroup_t *pg, scf_property_t *prop) 222*7c478bd9Sstevel@tonic-gate { 223*7c478bd9Sstevel@tonic-gate scf_value_t *val; 224*7c478bd9Sstevel@tonic-gate scf_iter_t *iter; 225*7c478bd9Sstevel@tonic-gate int ret, first; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate if (types) { 228*7c478bd9Sstevel@tonic-gate scf_type_t ty; 229*7c478bd9Sstevel@tonic-gate char *buf; 230*7c478bd9Sstevel@tonic-gate size_t buf_sz; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (fmris) { 233*7c478bd9Sstevel@tonic-gate buf_sz = max_scf_fmri_length + 1; 234*7c478bd9Sstevel@tonic-gate buf = safe_malloc(buf_sz); 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate if (scf_property_to_fmri(prop, buf, buf_sz) == -1) 237*7c478bd9Sstevel@tonic-gate scfdie(); 238*7c478bd9Sstevel@tonic-gate (void) fputs(buf, stdout); 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate free(buf); 241*7c478bd9Sstevel@tonic-gate } else { 242*7c478bd9Sstevel@tonic-gate buf_sz = max_scf_name_length + 1; 243*7c478bd9Sstevel@tonic-gate buf = safe_malloc(buf_sz); 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate if (scf_pg_get_name(pg, buf, buf_sz) < 0) 246*7c478bd9Sstevel@tonic-gate scfdie(); 247*7c478bd9Sstevel@tonic-gate (void) fputs(buf, stdout); 248*7c478bd9Sstevel@tonic-gate (void) putchar('/'); 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate if (scf_property_get_name(prop, buf, buf_sz) < 0) 251*7c478bd9Sstevel@tonic-gate scfdie(); 252*7c478bd9Sstevel@tonic-gate (void) fputs(buf, stdout); 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate free(buf); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate (void) putchar(' '); 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate if (scf_property_type(prop, &ty) == -1) 260*7c478bd9Sstevel@tonic-gate scfdie(); 261*7c478bd9Sstevel@tonic-gate (void) fputs(scf_type_to_string(ty), stdout); 262*7c478bd9Sstevel@tonic-gate (void) putchar(' '); 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate if ((iter = scf_iter_create(hndl)) == NULL || 266*7c478bd9Sstevel@tonic-gate (val = scf_value_create(hndl)) == NULL) 267*7c478bd9Sstevel@tonic-gate scfdie(); 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate if (scf_iter_property_values(iter, prop) == -1) 270*7c478bd9Sstevel@tonic-gate scfdie(); 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate first = 1; 273*7c478bd9Sstevel@tonic-gate while ((ret = scf_iter_next_value(iter, val)) == 1) { 274*7c478bd9Sstevel@tonic-gate if (first) 275*7c478bd9Sstevel@tonic-gate first = 0; 276*7c478bd9Sstevel@tonic-gate else 277*7c478bd9Sstevel@tonic-gate (void) putchar(' '); 278*7c478bd9Sstevel@tonic-gate print_value(val); 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate if (ret == -1) 281*7c478bd9Sstevel@tonic-gate scfdie(); 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate (void) putchar('\n'); 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 286*7c478bd9Sstevel@tonic-gate (void) scf_value_destroy(val); 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate /* 290*7c478bd9Sstevel@tonic-gate * display_prop() all of the properties in the given property group. Force 291*7c478bd9Sstevel@tonic-gate * types to true so identification will be displayed. 292*7c478bd9Sstevel@tonic-gate */ 293*7c478bd9Sstevel@tonic-gate static void 294*7c478bd9Sstevel@tonic-gate display_pg(scf_propertygroup_t *pg) 295*7c478bd9Sstevel@tonic-gate { 296*7c478bd9Sstevel@tonic-gate scf_property_t *prop; 297*7c478bd9Sstevel@tonic-gate scf_iter_t *iter; 298*7c478bd9Sstevel@tonic-gate int ret; 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate types = 1; /* Always display types for whole propertygroups. */ 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate if ((prop = scf_property_create(hndl)) == NULL || 303*7c478bd9Sstevel@tonic-gate (iter = scf_iter_create(hndl)) == NULL) 304*7c478bd9Sstevel@tonic-gate scfdie(); 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate if (scf_iter_pg_properties(iter, pg) == -1) 307*7c478bd9Sstevel@tonic-gate scfdie(); 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate while ((ret = scf_iter_next_property(iter, prop)) == 1) 310*7c478bd9Sstevel@tonic-gate display_prop(pg, prop); 311*7c478bd9Sstevel@tonic-gate if (ret == -1) 312*7c478bd9Sstevel@tonic-gate scfdie(); 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 315*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate /* 319*7c478bd9Sstevel@tonic-gate * Common code to execute when a nonexistant property is encountered. 320*7c478bd9Sstevel@tonic-gate */ 321*7c478bd9Sstevel@tonic-gate static void 322*7c478bd9Sstevel@tonic-gate noprop_common_action() 323*7c478bd9Sstevel@tonic-gate { 324*7c478bd9Sstevel@tonic-gate if (!PRINT_NOPROP_ERRORS) 325*7c478bd9Sstevel@tonic-gate /* We're not printing errors, so we can cut out early. */ 326*7c478bd9Sstevel@tonic-gate exit(UU_EXIT_FATAL); 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate return_code = UU_EXIT_FATAL; 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate /* 332*7c478bd9Sstevel@tonic-gate * Iterate the properties of a service or an instance when no snapshot 333*7c478bd9Sstevel@tonic-gate * is specified. 334*7c478bd9Sstevel@tonic-gate */ 335*7c478bd9Sstevel@tonic-gate static int 336*7c478bd9Sstevel@tonic-gate scf_iter_entity_pgs(scf_iter_t *iter, scf_entityp_t ent) 337*7c478bd9Sstevel@tonic-gate { 338*7c478bd9Sstevel@tonic-gate int ret = 0; 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate if (ent.type) { 341*7c478bd9Sstevel@tonic-gate /* 342*7c478bd9Sstevel@tonic-gate * If we are displaying properties for a service, 343*7c478bd9Sstevel@tonic-gate * treat it as though it were a composed, current 344*7c478bd9Sstevel@tonic-gate * lookup. (implicit cflag) However, if a snapshot 345*7c478bd9Sstevel@tonic-gate * was specified, fail. 346*7c478bd9Sstevel@tonic-gate */ 347*7c478bd9Sstevel@tonic-gate if (sflag) 348*7c478bd9Sstevel@tonic-gate die(gettext("Only instances have " 349*7c478bd9Sstevel@tonic-gate "snapshots.\n")); 350*7c478bd9Sstevel@tonic-gate ret = scf_iter_service_pgs(iter, ent.u.svc); 351*7c478bd9Sstevel@tonic-gate } else { 352*7c478bd9Sstevel@tonic-gate if (Cflag) 353*7c478bd9Sstevel@tonic-gate ret = scf_iter_instance_pgs(iter, ent.u.inst); 354*7c478bd9Sstevel@tonic-gate else 355*7c478bd9Sstevel@tonic-gate ret = scf_iter_instance_pgs_composed(iter, ent.u.inst, 356*7c478bd9Sstevel@tonic-gate NULL); 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate return (ret); 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate /* 362*7c478bd9Sstevel@tonic-gate * Return a snapshot for the supplied instance and snapshot name. 363*7c478bd9Sstevel@tonic-gate */ 364*7c478bd9Sstevel@tonic-gate static scf_snapshot_t * 365*7c478bd9Sstevel@tonic-gate get_snapshot(const scf_instance_t *inst, const char *snapshot) 366*7c478bd9Sstevel@tonic-gate { 367*7c478bd9Sstevel@tonic-gate scf_snapshot_t *snap = scf_snapshot_create(hndl); 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate if (snap == NULL) 370*7c478bd9Sstevel@tonic-gate scfdie(); 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate if (scf_instance_get_snapshot(inst, snapshot, snap) == -1) { 373*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 374*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 375*7c478bd9Sstevel@tonic-gate die(gettext("Invalid snapshot name.\n")); 376*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 379*7c478bd9Sstevel@tonic-gate if (sflag == 0) { 380*7c478bd9Sstevel@tonic-gate scf_snapshot_destroy(snap); 381*7c478bd9Sstevel@tonic-gate snap = NULL; 382*7c478bd9Sstevel@tonic-gate } else 383*7c478bd9Sstevel@tonic-gate die(gettext("No such snapshot.\n")); 384*7c478bd9Sstevel@tonic-gate break; 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate default: 387*7c478bd9Sstevel@tonic-gate scfdie(); 388*7c478bd9Sstevel@tonic-gate } 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate return (snap); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate /* 395*7c478bd9Sstevel@tonic-gate * Entity (service or instance): If there are -p options, 396*7c478bd9Sstevel@tonic-gate * display_{pg,prop}() the named property groups and/or properties. Otherwise 397*7c478bd9Sstevel@tonic-gate * display_pg() all property groups. 398*7c478bd9Sstevel@tonic-gate */ 399*7c478bd9Sstevel@tonic-gate static void 400*7c478bd9Sstevel@tonic-gate process_ent(scf_entityp_t ent) 401*7c478bd9Sstevel@tonic-gate { 402*7c478bd9Sstevel@tonic-gate scf_snapshot_t *snap = NULL; 403*7c478bd9Sstevel@tonic-gate scf_propertygroup_t *pg; 404*7c478bd9Sstevel@tonic-gate scf_property_t *prop; 405*7c478bd9Sstevel@tonic-gate scf_iter_t *iter; 406*7c478bd9Sstevel@tonic-gate svcprop_prop_node_t *spn; 407*7c478bd9Sstevel@tonic-gate int ret, err; 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate if (uu_list_numnodes(prop_list) == 0) { 410*7c478bd9Sstevel@tonic-gate if (quiet) 411*7c478bd9Sstevel@tonic-gate return; 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate if ((pg = scf_pg_create(hndl)) == NULL || 414*7c478bd9Sstevel@tonic-gate (iter = scf_iter_create(hndl)) == NULL) 415*7c478bd9Sstevel@tonic-gate scfdie(); 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate if (cflag || Cflag || ent.type != ENT_INSTANCE) { 418*7c478bd9Sstevel@tonic-gate if (scf_iter_entity_pgs(iter, ent) == -1) 419*7c478bd9Sstevel@tonic-gate scfdie(); 420*7c478bd9Sstevel@tonic-gate } else { 421*7c478bd9Sstevel@tonic-gate if (snapshot != NULL) 422*7c478bd9Sstevel@tonic-gate snap = get_snapshot(ent.u.inst, snapshot); 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate if (scf_iter_instance_pgs_composed(iter, ent.u.inst, 425*7c478bd9Sstevel@tonic-gate snap) == -1) 426*7c478bd9Sstevel@tonic-gate scfdie(); 427*7c478bd9Sstevel@tonic-gate if (snap) 428*7c478bd9Sstevel@tonic-gate scf_snapshot_destroy(snap); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate while ((ret = scf_iter_next_pg(iter, pg)) == 1) 432*7c478bd9Sstevel@tonic-gate display_pg(pg); 433*7c478bd9Sstevel@tonic-gate if (ret == -1) 434*7c478bd9Sstevel@tonic-gate scfdie(); 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate /* 437*7c478bd9Sstevel@tonic-gate * In normal usage, i.e. against the running snapshot, 438*7c478bd9Sstevel@tonic-gate * we must iterate over the current non-persistent 439*7c478bd9Sstevel@tonic-gate * pg's. 440*7c478bd9Sstevel@tonic-gate */ 441*7c478bd9Sstevel@tonic-gate if (sflag == 0 && snap != NULL) { 442*7c478bd9Sstevel@tonic-gate scf_iter_reset(iter); 443*7c478bd9Sstevel@tonic-gate if (scf_iter_instance_pgs_composed(iter, ent.u.inst, 444*7c478bd9Sstevel@tonic-gate NULL) == -1) 445*7c478bd9Sstevel@tonic-gate scfdie(); 446*7c478bd9Sstevel@tonic-gate while ((ret = scf_iter_next_pg(iter, pg)) == 1) { 447*7c478bd9Sstevel@tonic-gate uint32_t flags; 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate if (scf_pg_get_flags(pg, &flags) == -1) 450*7c478bd9Sstevel@tonic-gate scfdie(); 451*7c478bd9Sstevel@tonic-gate if (flags & SCF_PG_FLAG_NONPERSISTENT) 452*7c478bd9Sstevel@tonic-gate display_pg(pg); 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate if (ret == -1) 456*7c478bd9Sstevel@tonic-gate scfdie(); 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 459*7c478bd9Sstevel@tonic-gate scf_pg_destroy(pg); 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate return; 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate if ((pg = scf_pg_create(hndl)) == NULL || 465*7c478bd9Sstevel@tonic-gate (prop = scf_property_create(hndl)) == NULL) 466*7c478bd9Sstevel@tonic-gate scfdie(); 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate if (ent.type == ENT_INSTANCE && snapshot != NULL) 469*7c478bd9Sstevel@tonic-gate snap = get_snapshot(ent.u.inst, snapshot); 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate for (spn = uu_list_first(prop_list); 472*7c478bd9Sstevel@tonic-gate spn != NULL; 473*7c478bd9Sstevel@tonic-gate spn = uu_list_next(prop_list, spn)) { 474*7c478bd9Sstevel@tonic-gate if (ent.type == ENT_INSTANCE) { 475*7c478bd9Sstevel@tonic-gate if (Cflag) 476*7c478bd9Sstevel@tonic-gate ret = scf_instance_get_pg(ent.u.inst, 477*7c478bd9Sstevel@tonic-gate spn->spn_comp1, pg); 478*7c478bd9Sstevel@tonic-gate else 479*7c478bd9Sstevel@tonic-gate ret = scf_instance_get_pg_composed(ent.u.inst, 480*7c478bd9Sstevel@tonic-gate snap, spn->spn_comp1, pg); 481*7c478bd9Sstevel@tonic-gate err = scf_error(); 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate /* 484*7c478bd9Sstevel@tonic-gate * If we didn't find it in the specified snapshot, use 485*7c478bd9Sstevel@tonic-gate * the current values if the pg is nonpersistent. 486*7c478bd9Sstevel@tonic-gate */ 487*7c478bd9Sstevel@tonic-gate if (ret == -1 && !Cflag &&snap != NULL && err == 488*7c478bd9Sstevel@tonic-gate SCF_ERROR_NOT_FOUND) { 489*7c478bd9Sstevel@tonic-gate ret = scf_instance_get_pg_composed( 490*7c478bd9Sstevel@tonic-gate ent.u.inst, NULL, spn->spn_comp1, 491*7c478bd9Sstevel@tonic-gate pg); 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate if (ret == 0) { 494*7c478bd9Sstevel@tonic-gate uint32_t flags; 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate if (scf_pg_get_flags(pg, &flags) == -1) 497*7c478bd9Sstevel@tonic-gate scfdie(); 498*7c478bd9Sstevel@tonic-gate if ((flags & SCF_PG_FLAG_NONPERSISTENT) 499*7c478bd9Sstevel@tonic-gate == 0) { 500*7c478bd9Sstevel@tonic-gate ret = -1; 501*7c478bd9Sstevel@tonic-gate } 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate } else { 505*7c478bd9Sstevel@tonic-gate /* 506*7c478bd9Sstevel@tonic-gate * If we are displaying properties for a service, 507*7c478bd9Sstevel@tonic-gate * treat it as though it were a composed, current 508*7c478bd9Sstevel@tonic-gate * lookup. (implicit cflag) However, if a snapshot 509*7c478bd9Sstevel@tonic-gate * was specified, fail. 510*7c478bd9Sstevel@tonic-gate */ 511*7c478bd9Sstevel@tonic-gate if (sflag) 512*7c478bd9Sstevel@tonic-gate die(gettext("Only instances have " 513*7c478bd9Sstevel@tonic-gate "snapshots.\n")); 514*7c478bd9Sstevel@tonic-gate ret = scf_entity_get_pg(ent, spn->spn_comp1, pg); 515*7c478bd9Sstevel@tonic-gate err = scf_error(); 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate if (ret == -1) { 518*7c478bd9Sstevel@tonic-gate if (err != SCF_ERROR_NOT_FOUND) 519*7c478bd9Sstevel@tonic-gate scfdie(); 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate if (PRINT_NOPROP_ERRORS) { 522*7c478bd9Sstevel@tonic-gate char *buf; 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate buf = safe_malloc(max_scf_fmri_length + 1); 525*7c478bd9Sstevel@tonic-gate if (scf_entity_to_fmri(ent, buf, 526*7c478bd9Sstevel@tonic-gate max_scf_fmri_length + 1) == -1) 527*7c478bd9Sstevel@tonic-gate scfdie(); 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate uu_warn(gettext("Couldn't find property group " 530*7c478bd9Sstevel@tonic-gate "`%s' for %s `%s'.\n"), spn->spn_comp1, 531*7c478bd9Sstevel@tonic-gate SCF_ENTITY_TYPE_NAME(ent), buf); 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate free(buf); 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate noprop_common_action(); 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate continue; 539*7c478bd9Sstevel@tonic-gate } 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate if (spn->spn_comp2 == NULL) { 542*7c478bd9Sstevel@tonic-gate if (!quiet) 543*7c478bd9Sstevel@tonic-gate display_pg(pg); 544*7c478bd9Sstevel@tonic-gate continue; 545*7c478bd9Sstevel@tonic-gate } 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate if (scf_pg_get_property(pg, spn->spn_comp2, prop) == -1) { 548*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 549*7c478bd9Sstevel@tonic-gate scfdie(); 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate if (PRINT_NOPROP_ERRORS) { 552*7c478bd9Sstevel@tonic-gate char *buf; 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate buf = safe_malloc(max_scf_fmri_length + 1); 555*7c478bd9Sstevel@tonic-gate if (scf_entity_to_fmri(ent, buf, 556*7c478bd9Sstevel@tonic-gate max_scf_fmri_length + 1) == -1) 557*7c478bd9Sstevel@tonic-gate scfdie(); 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate /* FMRI syntax knowledge */ 560*7c478bd9Sstevel@tonic-gate uu_warn(gettext("Couldn't find property " 561*7c478bd9Sstevel@tonic-gate "`%s/%s' for %s `%s'.\n"), spn->spn_comp1, 562*7c478bd9Sstevel@tonic-gate spn->spn_comp2, SCF_ENTITY_TYPE_NAME(ent), 563*7c478bd9Sstevel@tonic-gate buf); 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate free(buf); 566*7c478bd9Sstevel@tonic-gate } 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate noprop_common_action(); 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate continue; 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate if (!quiet) 574*7c478bd9Sstevel@tonic-gate display_prop(pg, prop); 575*7c478bd9Sstevel@tonic-gate } 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 578*7c478bd9Sstevel@tonic-gate scf_pg_destroy(pg); 579*7c478bd9Sstevel@tonic-gate if (snap) 580*7c478bd9Sstevel@tonic-gate scf_snapshot_destroy(snap); 581*7c478bd9Sstevel@tonic-gate } 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate /* 584*7c478bd9Sstevel@tonic-gate * Without -p options, just call display_pg(). Otherwise display_prop() the 585*7c478bd9Sstevel@tonic-gate * named properties of the property group. 586*7c478bd9Sstevel@tonic-gate */ 587*7c478bd9Sstevel@tonic-gate static void 588*7c478bd9Sstevel@tonic-gate process_pg(scf_propertygroup_t *pg) 589*7c478bd9Sstevel@tonic-gate { 590*7c478bd9Sstevel@tonic-gate scf_property_t *prop; 591*7c478bd9Sstevel@tonic-gate svcprop_prop_node_t *spn; 592*7c478bd9Sstevel@tonic-gate 593*7c478bd9Sstevel@tonic-gate if (uu_list_first(prop_list) == NULL) { 594*7c478bd9Sstevel@tonic-gate if (quiet) 595*7c478bd9Sstevel@tonic-gate return; 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate display_pg(pg); 598*7c478bd9Sstevel@tonic-gate return; 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate prop = scf_property_create(hndl); 602*7c478bd9Sstevel@tonic-gate if (prop == NULL) 603*7c478bd9Sstevel@tonic-gate scfdie(); 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate for (spn = uu_list_first(prop_list); 606*7c478bd9Sstevel@tonic-gate spn != NULL; 607*7c478bd9Sstevel@tonic-gate spn = uu_list_next(prop_list, spn)) { 608*7c478bd9Sstevel@tonic-gate if (spn->spn_comp2 != NULL) { 609*7c478bd9Sstevel@tonic-gate char *buf; 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate buf = safe_malloc(max_scf_fmri_length + 1); 612*7c478bd9Sstevel@tonic-gate if (scf_pg_to_fmri(pg, buf, max_scf_fmri_length + 1) == 613*7c478bd9Sstevel@tonic-gate -1) 614*7c478bd9Sstevel@tonic-gate scfdie(); 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("-p argument `%s/%s' " 617*7c478bd9Sstevel@tonic-gate "has too many components for property " 618*7c478bd9Sstevel@tonic-gate "group `%s'.\n"), spn->spn_comp1, spn->spn_comp2, 619*7c478bd9Sstevel@tonic-gate buf); 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate free(buf); 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate if (scf_pg_get_property(pg, spn->spn_comp1, prop) == 0) { 625*7c478bd9Sstevel@tonic-gate if (!quiet) 626*7c478bd9Sstevel@tonic-gate display_prop(pg, prop); 627*7c478bd9Sstevel@tonic-gate continue; 628*7c478bd9Sstevel@tonic-gate } 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 631*7c478bd9Sstevel@tonic-gate scfdie(); 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate if (PRINT_NOPROP_ERRORS) { 634*7c478bd9Sstevel@tonic-gate char *buf; 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate buf = safe_malloc(max_scf_fmri_length + 1); 637*7c478bd9Sstevel@tonic-gate if (scf_pg_to_fmri(pg, buf, max_scf_fmri_length + 1) == 638*7c478bd9Sstevel@tonic-gate -1) 639*7c478bd9Sstevel@tonic-gate scfdie(); 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate uu_warn(gettext("Couldn't find property `%s' in " 642*7c478bd9Sstevel@tonic-gate "property group `%s'.\n"), spn->spn_comp1, buf); 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate free(buf); 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate noprop_common_action(); 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate /* 652*7c478bd9Sstevel@tonic-gate * If there are -p options, show the error. Otherwise just call 653*7c478bd9Sstevel@tonic-gate * display_prop(). 654*7c478bd9Sstevel@tonic-gate */ 655*7c478bd9Sstevel@tonic-gate static void 656*7c478bd9Sstevel@tonic-gate process_prop(scf_propertygroup_t *pg, scf_property_t *prop) 657*7c478bd9Sstevel@tonic-gate { 658*7c478bd9Sstevel@tonic-gate if (uu_list_first(prop_list) != NULL) { 659*7c478bd9Sstevel@tonic-gate uu_warn(gettext("The -p option cannot be used with property " 660*7c478bd9Sstevel@tonic-gate "operands.\n")); 661*7c478bd9Sstevel@tonic-gate usage(); 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate if (quiet) 665*7c478bd9Sstevel@tonic-gate return; 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate display_prop(pg, prop); 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate 670*7c478bd9Sstevel@tonic-gate /* Decode an operand & dispatch. */ 671*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 672*7c478bd9Sstevel@tonic-gate static int 673*7c478bd9Sstevel@tonic-gate process_fmri(void *unused, scf_walkinfo_t *wip) 674*7c478bd9Sstevel@tonic-gate { 675*7c478bd9Sstevel@tonic-gate scf_entityp_t ent; 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate /* Multiple matches imply multiple entities. */ 678*7c478bd9Sstevel@tonic-gate if (wip->count > 1) 679*7c478bd9Sstevel@tonic-gate types = fmris = 1; 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate if (wip->prop != NULL) { 682*7c478bd9Sstevel@tonic-gate process_prop(wip->pg, wip->prop); 683*7c478bd9Sstevel@tonic-gate } else if (wip->pg != NULL) { 684*7c478bd9Sstevel@tonic-gate process_pg(wip->pg); 685*7c478bd9Sstevel@tonic-gate } else if (wip->inst != NULL) { 686*7c478bd9Sstevel@tonic-gate SCF_ENTITY_SET_TO_INSTANCE(ent, wip->inst); 687*7c478bd9Sstevel@tonic-gate process_ent(ent); 688*7c478bd9Sstevel@tonic-gate } else { 689*7c478bd9Sstevel@tonic-gate /* scf_walk_fmri() won't let this happen */ 690*7c478bd9Sstevel@tonic-gate assert(wip->svc != NULL); 691*7c478bd9Sstevel@tonic-gate SCF_ENTITY_SET_TO_SERVICE(ent, wip->svc); 692*7c478bd9Sstevel@tonic-gate process_ent(ent); 693*7c478bd9Sstevel@tonic-gate } 694*7c478bd9Sstevel@tonic-gate 695*7c478bd9Sstevel@tonic-gate return (0); 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate 698*7c478bd9Sstevel@tonic-gate static void 699*7c478bd9Sstevel@tonic-gate add_prop(char *property) 700*7c478bd9Sstevel@tonic-gate { 701*7c478bd9Sstevel@tonic-gate svcprop_prop_node_t *p, *last; 702*7c478bd9Sstevel@tonic-gate char *slash; 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate const char * const invalid_component_emsg = 705*7c478bd9Sstevel@tonic-gate gettext("Invalid component name `%s'.\n"); 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate /* FMRI syntax knowledge. */ 708*7c478bd9Sstevel@tonic-gate slash = strchr(property, '/'); 709*7c478bd9Sstevel@tonic-gate if (slash != NULL) { 710*7c478bd9Sstevel@tonic-gate if (strchr(slash + 1, '/') != NULL) { 711*7c478bd9Sstevel@tonic-gate uu_warn(gettext("-p argument `%s' has too many " 712*7c478bd9Sstevel@tonic-gate "components.\n"), property); 713*7c478bd9Sstevel@tonic-gate usage(); 714*7c478bd9Sstevel@tonic-gate } 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate if (slash != NULL) 718*7c478bd9Sstevel@tonic-gate *slash = '\0'; 719*7c478bd9Sstevel@tonic-gate 720*7c478bd9Sstevel@tonic-gate p = safe_malloc(sizeof (svcprop_prop_node_t)); 721*7c478bd9Sstevel@tonic-gate uu_list_node_init(p, &p->spn_list_node, prop_pool); 722*7c478bd9Sstevel@tonic-gate 723*7c478bd9Sstevel@tonic-gate p->spn_comp1 = property; 724*7c478bd9Sstevel@tonic-gate p->spn_comp2 = (slash == NULL) ? NULL : slash + 1; 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate if (uu_check_name(p->spn_comp1, UU_NAME_DOMAIN) == -1) 727*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, invalid_component_emsg, p->spn_comp1); 728*7c478bd9Sstevel@tonic-gate if (p->spn_comp2 != NULL && 729*7c478bd9Sstevel@tonic-gate uu_check_name(p->spn_comp2, UU_NAME_DOMAIN) == -1) 730*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, invalid_component_emsg, p->spn_comp2); 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate last = uu_list_last(prop_list); 733*7c478bd9Sstevel@tonic-gate if (last != NULL) { 734*7c478bd9Sstevel@tonic-gate if ((last->spn_comp2 == NULL) ^ (p->spn_comp2 == NULL)) { 735*7c478bd9Sstevel@tonic-gate /* 736*7c478bd9Sstevel@tonic-gate * The -p options have mixed numbers of components. 737*7c478bd9Sstevel@tonic-gate * If they both turn out to be valid, then the 738*7c478bd9Sstevel@tonic-gate * single-component ones will specify property groups, 739*7c478bd9Sstevel@tonic-gate * so we need to turn on types to keep the output of 740*7c478bd9Sstevel@tonic-gate * display_prop() consistent with display_pg(). 741*7c478bd9Sstevel@tonic-gate */ 742*7c478bd9Sstevel@tonic-gate types = 1; 743*7c478bd9Sstevel@tonic-gate } 744*7c478bd9Sstevel@tonic-gate } 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate (void) uu_list_insert_after(prop_list, NULL, p); 747*7c478bd9Sstevel@tonic-gate } 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate /* 751*7c478bd9Sstevel@tonic-gate * Wait for a property group or property change. 752*7c478bd9Sstevel@tonic-gate * 753*7c478bd9Sstevel@tonic-gate * Extract a pg and optionally a property name from fmri & prop_list. 754*7c478bd9Sstevel@tonic-gate * _scf_pg_wait() for the pg, and display_pg(pg) or display_prop(pg, prop) 755*7c478bd9Sstevel@tonic-gate * when it returns. 756*7c478bd9Sstevel@tonic-gate */ 757*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 758*7c478bd9Sstevel@tonic-gate static int 759*7c478bd9Sstevel@tonic-gate do_wait(void *unused, scf_walkinfo_t *wip) 760*7c478bd9Sstevel@tonic-gate { 761*7c478bd9Sstevel@tonic-gate scf_property_t *prop; 762*7c478bd9Sstevel@tonic-gate scf_propertygroup_t *lpg, *pg; 763*7c478bd9Sstevel@tonic-gate const char *propname; 764*7c478bd9Sstevel@tonic-gate svcprop_prop_node_t *p; 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate const char *emsg_not_found = gettext("Not found.\n"); 767*7c478bd9Sstevel@tonic-gate 768*7c478bd9Sstevel@tonic-gate if ((lpg = scf_pg_create(hndl)) == NULL || 769*7c478bd9Sstevel@tonic-gate (prop = scf_property_create(hndl)) == NULL) 770*7c478bd9Sstevel@tonic-gate scfdie(); 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate if (wip->prop != NULL) { 773*7c478bd9Sstevel@tonic-gate if (uu_list_numnodes(prop_list) > 0) 774*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("-p cannot be used with " 775*7c478bd9Sstevel@tonic-gate "property FMRIs.\n")); 776*7c478bd9Sstevel@tonic-gate pg = wip->pg; 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate assert(strrchr(wip->fmri, '/') != NULL); 779*7c478bd9Sstevel@tonic-gate propname = strrchr(wip->fmri, '/') + 1; 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate } else if (wip->pg != NULL) { 782*7c478bd9Sstevel@tonic-gate p = uu_list_first(prop_list); 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate if (p != NULL) { 785*7c478bd9Sstevel@tonic-gate if (p->spn_comp2 != NULL) 786*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("-p argument " 787*7c478bd9Sstevel@tonic-gate "\"%s/%s\" has too many components for " 788*7c478bd9Sstevel@tonic-gate "property group %s.\n"), 789*7c478bd9Sstevel@tonic-gate p->spn_comp1, p->spn_comp2, wip->fmri); 790*7c478bd9Sstevel@tonic-gate 791*7c478bd9Sstevel@tonic-gate propname = p->spn_comp1; 792*7c478bd9Sstevel@tonic-gate 793*7c478bd9Sstevel@tonic-gate if (scf_pg_get_property(wip->pg, propname, prop) != 794*7c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 795*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 796*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 797*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 798*7c478bd9Sstevel@tonic-gate gettext("Invalid property name " 799*7c478bd9Sstevel@tonic-gate "\"%s\".\n"), propname); 800*7c478bd9Sstevel@tonic-gate 801*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 802*7c478bd9Sstevel@tonic-gate 803*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 804*7c478bd9Sstevel@tonic-gate die(emsg_not_found); 805*7c478bd9Sstevel@tonic-gate 806*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate default: 809*7c478bd9Sstevel@tonic-gate scfdie(); 810*7c478bd9Sstevel@tonic-gate } 811*7c478bd9Sstevel@tonic-gate } 812*7c478bd9Sstevel@tonic-gate } else { 813*7c478bd9Sstevel@tonic-gate propname = NULL; 814*7c478bd9Sstevel@tonic-gate } 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate pg = wip->pg; 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate } else if (wip->inst != NULL) { 819*7c478bd9Sstevel@tonic-gate 820*7c478bd9Sstevel@tonic-gate p = uu_list_first(prop_list); 821*7c478bd9Sstevel@tonic-gate if (p == NULL) 822*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 823*7c478bd9Sstevel@tonic-gate gettext("Cannot wait for an instance.\n")); 824*7c478bd9Sstevel@tonic-gate 825*7c478bd9Sstevel@tonic-gate if (scf_instance_get_pg(wip->inst, p->spn_comp1, lpg) != 826*7c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 827*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 828*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 829*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("Invalid " 830*7c478bd9Sstevel@tonic-gate "property group name \"%s\".\n"), 831*7c478bd9Sstevel@tonic-gate p->spn_comp1); 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 834*7c478bd9Sstevel@tonic-gate die(emsg_not_found); 835*7c478bd9Sstevel@tonic-gate 836*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 837*7c478bd9Sstevel@tonic-gate 838*7c478bd9Sstevel@tonic-gate default: 839*7c478bd9Sstevel@tonic-gate scfdie(); 840*7c478bd9Sstevel@tonic-gate } 841*7c478bd9Sstevel@tonic-gate } 842*7c478bd9Sstevel@tonic-gate 843*7c478bd9Sstevel@tonic-gate propname = p->spn_comp2; 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate if (propname != NULL) { 846*7c478bd9Sstevel@tonic-gate if (scf_pg_get_property(lpg, propname, prop) != 847*7c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 848*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 849*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 850*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 851*7c478bd9Sstevel@tonic-gate gettext("Invalid property name " 852*7c478bd9Sstevel@tonic-gate "\"%s\".\n"), propname); 853*7c478bd9Sstevel@tonic-gate 854*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 855*7c478bd9Sstevel@tonic-gate die(emsg_not_found); 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 858*7c478bd9Sstevel@tonic-gate 859*7c478bd9Sstevel@tonic-gate default: 860*7c478bd9Sstevel@tonic-gate scfdie(); 861*7c478bd9Sstevel@tonic-gate } 862*7c478bd9Sstevel@tonic-gate } 863*7c478bd9Sstevel@tonic-gate } 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate pg = lpg; 866*7c478bd9Sstevel@tonic-gate 867*7c478bd9Sstevel@tonic-gate } else if (wip->svc != NULL) { 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate p = uu_list_first(prop_list); 870*7c478bd9Sstevel@tonic-gate if (p == NULL) 871*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 872*7c478bd9Sstevel@tonic-gate gettext("Cannot wait for a service.\n")); 873*7c478bd9Sstevel@tonic-gate 874*7c478bd9Sstevel@tonic-gate if (scf_service_get_pg(wip->svc, p->spn_comp1, lpg) != 875*7c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 876*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 877*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 878*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("Invalid " 879*7c478bd9Sstevel@tonic-gate "property group name \"%s\".\n"), 880*7c478bd9Sstevel@tonic-gate p->spn_comp1); 881*7c478bd9Sstevel@tonic-gate 882*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 883*7c478bd9Sstevel@tonic-gate die(emsg_not_found); 884*7c478bd9Sstevel@tonic-gate 885*7c478bd9Sstevel@tonic-gate default: 886*7c478bd9Sstevel@tonic-gate scfdie(); 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate } 889*7c478bd9Sstevel@tonic-gate 890*7c478bd9Sstevel@tonic-gate propname = p->spn_comp2; 891*7c478bd9Sstevel@tonic-gate 892*7c478bd9Sstevel@tonic-gate if (propname != NULL) { 893*7c478bd9Sstevel@tonic-gate if (scf_pg_get_property(lpg, propname, prop) != 894*7c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 895*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 896*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 897*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 898*7c478bd9Sstevel@tonic-gate gettext("Invalid property name " 899*7c478bd9Sstevel@tonic-gate "\"%s\".\n"), propname); 900*7c478bd9Sstevel@tonic-gate 901*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 902*7c478bd9Sstevel@tonic-gate 903*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 904*7c478bd9Sstevel@tonic-gate die(emsg_not_found); 905*7c478bd9Sstevel@tonic-gate 906*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate default: 909*7c478bd9Sstevel@tonic-gate scfdie(); 910*7c478bd9Sstevel@tonic-gate } 911*7c478bd9Sstevel@tonic-gate } 912*7c478bd9Sstevel@tonic-gate } 913*7c478bd9Sstevel@tonic-gate 914*7c478bd9Sstevel@tonic-gate pg = lpg; 915*7c478bd9Sstevel@tonic-gate 916*7c478bd9Sstevel@tonic-gate } else { 917*7c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("FMRI must specify an entity, " 918*7c478bd9Sstevel@tonic-gate "property group, or property.\n")); 919*7c478bd9Sstevel@tonic-gate } 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate for (;;) { 922*7c478bd9Sstevel@tonic-gate int ret; 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate ret = _scf_pg_wait(pg, -1); 925*7c478bd9Sstevel@tonic-gate if (ret != SCF_SUCCESS) 926*7c478bd9Sstevel@tonic-gate scfdie(); 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate ret = scf_pg_update(pg); 929*7c478bd9Sstevel@tonic-gate if (ret < 0) { 930*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_DELETED) 931*7c478bd9Sstevel@tonic-gate scfdie(); 932*7c478bd9Sstevel@tonic-gate 933*7c478bd9Sstevel@tonic-gate die(emsg_not_found); 934*7c478bd9Sstevel@tonic-gate } 935*7c478bd9Sstevel@tonic-gate if (ret == SCF_COMPLETE) 936*7c478bd9Sstevel@tonic-gate break; 937*7c478bd9Sstevel@tonic-gate } 938*7c478bd9Sstevel@tonic-gate 939*7c478bd9Sstevel@tonic-gate if (propname != NULL) { 940*7c478bd9Sstevel@tonic-gate if (scf_pg_get_property(pg, propname, prop) == SCF_SUCCESS) { 941*7c478bd9Sstevel@tonic-gate if (!quiet) 942*7c478bd9Sstevel@tonic-gate display_prop(pg, prop); 943*7c478bd9Sstevel@tonic-gate } else { 944*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 945*7c478bd9Sstevel@tonic-gate scfdie(); 946*7c478bd9Sstevel@tonic-gate 947*7c478bd9Sstevel@tonic-gate if (PRINT_NOPROP_ERRORS) 948*7c478bd9Sstevel@tonic-gate uu_warn(emsg_not_found); 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate return_code = UU_EXIT_FATAL; 951*7c478bd9Sstevel@tonic-gate } 952*7c478bd9Sstevel@tonic-gate } else { 953*7c478bd9Sstevel@tonic-gate if (!quiet) 954*7c478bd9Sstevel@tonic-gate display_pg(pg); 955*7c478bd9Sstevel@tonic-gate } 956*7c478bd9Sstevel@tonic-gate 957*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 958*7c478bd9Sstevel@tonic-gate scf_pg_destroy(lpg); 959*7c478bd9Sstevel@tonic-gate 960*7c478bd9Sstevel@tonic-gate return (0); 961*7c478bd9Sstevel@tonic-gate } 962*7c478bd9Sstevel@tonic-gate 963*7c478bd9Sstevel@tonic-gate /* 964*7c478bd9Sstevel@tonic-gate * These functions replace uu_warn() and uu_die() when the quiet (-q) option is 965*7c478bd9Sstevel@tonic-gate * used, and silently ignore any output. 966*7c478bd9Sstevel@tonic-gate */ 967*7c478bd9Sstevel@tonic-gate 968*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 969*7c478bd9Sstevel@tonic-gate static void 970*7c478bd9Sstevel@tonic-gate quiet_warn(const char *fmt, ...) 971*7c478bd9Sstevel@tonic-gate { 972*7c478bd9Sstevel@tonic-gate /* Do nothing */ 973*7c478bd9Sstevel@tonic-gate } 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 976*7c478bd9Sstevel@tonic-gate static void 977*7c478bd9Sstevel@tonic-gate quiet_die(const char *fmt, ...) 978*7c478bd9Sstevel@tonic-gate { 979*7c478bd9Sstevel@tonic-gate exit(UU_EXIT_FATAL); 980*7c478bd9Sstevel@tonic-gate } 981*7c478bd9Sstevel@tonic-gate 982*7c478bd9Sstevel@tonic-gate int 983*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 984*7c478bd9Sstevel@tonic-gate { 985*7c478bd9Sstevel@tonic-gate int c; 986*7c478bd9Sstevel@tonic-gate scf_walk_callback callback; 987*7c478bd9Sstevel@tonic-gate int flags; 988*7c478bd9Sstevel@tonic-gate int err; 989*7c478bd9Sstevel@tonic-gate 990*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 991*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate return_code = UU_EXIT_OK; 994*7c478bd9Sstevel@tonic-gate 995*7c478bd9Sstevel@tonic-gate (void) uu_setpname(argv[0]); 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate prop_pool = uu_list_pool_create("properties", 998*7c478bd9Sstevel@tonic-gate sizeof (svcprop_prop_node_t), 999*7c478bd9Sstevel@tonic-gate offsetof(svcprop_prop_node_t, spn_list_node), NULL, 0); 1000*7c478bd9Sstevel@tonic-gate if (prop_pool == NULL) 1001*7c478bd9Sstevel@tonic-gate uu_die("%s\n", uu_strerror(uu_error())); 1002*7c478bd9Sstevel@tonic-gate 1003*7c478bd9Sstevel@tonic-gate prop_list = uu_list_create(prop_pool, NULL, 0); 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "Ccfp:qs:tvw")) != -1) { 1006*7c478bd9Sstevel@tonic-gate switch (c) { 1007*7c478bd9Sstevel@tonic-gate case 'C': 1008*7c478bd9Sstevel@tonic-gate if (cflag || sflag || wait) 1009*7c478bd9Sstevel@tonic-gate usage(); /* Not with -c, -s or -w */ 1010*7c478bd9Sstevel@tonic-gate Cflag++; 1011*7c478bd9Sstevel@tonic-gate snapshot = NULL; 1012*7c478bd9Sstevel@tonic-gate break; 1013*7c478bd9Sstevel@tonic-gate 1014*7c478bd9Sstevel@tonic-gate case 'c': 1015*7c478bd9Sstevel@tonic-gate if (Cflag || sflag || wait) 1016*7c478bd9Sstevel@tonic-gate usage(); /* Not with -C, -s or -w */ 1017*7c478bd9Sstevel@tonic-gate cflag++; 1018*7c478bd9Sstevel@tonic-gate snapshot = NULL; 1019*7c478bd9Sstevel@tonic-gate break; 1020*7c478bd9Sstevel@tonic-gate 1021*7c478bd9Sstevel@tonic-gate case 'f': 1022*7c478bd9Sstevel@tonic-gate types = 1; 1023*7c478bd9Sstevel@tonic-gate fmris = 1; 1024*7c478bd9Sstevel@tonic-gate break; 1025*7c478bd9Sstevel@tonic-gate 1026*7c478bd9Sstevel@tonic-gate case 'p': 1027*7c478bd9Sstevel@tonic-gate add_prop(optarg); 1028*7c478bd9Sstevel@tonic-gate break; 1029*7c478bd9Sstevel@tonic-gate 1030*7c478bd9Sstevel@tonic-gate case 'q': 1031*7c478bd9Sstevel@tonic-gate quiet = 1; 1032*7c478bd9Sstevel@tonic-gate warn = quiet_warn; 1033*7c478bd9Sstevel@tonic-gate die = quiet_die; 1034*7c478bd9Sstevel@tonic-gate break; 1035*7c478bd9Sstevel@tonic-gate 1036*7c478bd9Sstevel@tonic-gate case 's': 1037*7c478bd9Sstevel@tonic-gate if (Cflag || cflag || wait) 1038*7c478bd9Sstevel@tonic-gate usage(); /* Not with -C, -c or -w */ 1039*7c478bd9Sstevel@tonic-gate snapshot = optarg; 1040*7c478bd9Sstevel@tonic-gate sflag++; 1041*7c478bd9Sstevel@tonic-gate break; 1042*7c478bd9Sstevel@tonic-gate 1043*7c478bd9Sstevel@tonic-gate case 't': 1044*7c478bd9Sstevel@tonic-gate types = 1; 1045*7c478bd9Sstevel@tonic-gate break; 1046*7c478bd9Sstevel@tonic-gate 1047*7c478bd9Sstevel@tonic-gate case 'v': 1048*7c478bd9Sstevel@tonic-gate verbose = 1; 1049*7c478bd9Sstevel@tonic-gate break; 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gate case 'w': 1052*7c478bd9Sstevel@tonic-gate if (Cflag || cflag || sflag) 1053*7c478bd9Sstevel@tonic-gate usage(); /* Not with -C, -c or -s */ 1054*7c478bd9Sstevel@tonic-gate wait = 1; 1055*7c478bd9Sstevel@tonic-gate break; 1056*7c478bd9Sstevel@tonic-gate 1057*7c478bd9Sstevel@tonic-gate case '?': 1058*7c478bd9Sstevel@tonic-gate switch (optopt) { 1059*7c478bd9Sstevel@tonic-gate case 'p': 1060*7c478bd9Sstevel@tonic-gate usage(); 1061*7c478bd9Sstevel@tonic-gate 1062*7c478bd9Sstevel@tonic-gate default: 1063*7c478bd9Sstevel@tonic-gate break; 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 1067*7c478bd9Sstevel@tonic-gate 1068*7c478bd9Sstevel@tonic-gate default: 1069*7c478bd9Sstevel@tonic-gate usage(); 1070*7c478bd9Sstevel@tonic-gate } 1071*7c478bd9Sstevel@tonic-gate } 1072*7c478bd9Sstevel@tonic-gate 1073*7c478bd9Sstevel@tonic-gate if (optind == argc) 1074*7c478bd9Sstevel@tonic-gate usage(); 1075*7c478bd9Sstevel@tonic-gate 1076*7c478bd9Sstevel@tonic-gate max_scf_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH); 1077*7c478bd9Sstevel@tonic-gate max_scf_value_length = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH); 1078*7c478bd9Sstevel@tonic-gate max_scf_fmri_length = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); 1079*7c478bd9Sstevel@tonic-gate if (max_scf_name_length == -1 || max_scf_value_length == -1 || 1080*7c478bd9Sstevel@tonic-gate max_scf_fmri_length == -1) 1081*7c478bd9Sstevel@tonic-gate scfdie(); 1082*7c478bd9Sstevel@tonic-gate 1083*7c478bd9Sstevel@tonic-gate hndl = scf_handle_create(SCF_VERSION); 1084*7c478bd9Sstevel@tonic-gate if (hndl == NULL) 1085*7c478bd9Sstevel@tonic-gate scfdie(); 1086*7c478bd9Sstevel@tonic-gate if (scf_handle_bind(hndl) == -1) 1087*7c478bd9Sstevel@tonic-gate die(gettext("Could not connect to configuration repository: " 1088*7c478bd9Sstevel@tonic-gate "%s.\n"), scf_strerror(scf_error())); 1089*7c478bd9Sstevel@tonic-gate 1090*7c478bd9Sstevel@tonic-gate flags = SCF_WALK_PROPERTY | SCF_WALK_SERVICE | SCF_WALK_EXPLICIT; 1091*7c478bd9Sstevel@tonic-gate 1092*7c478bd9Sstevel@tonic-gate if (wait) { 1093*7c478bd9Sstevel@tonic-gate if (uu_list_numnodes(prop_list) > 1) 1094*7c478bd9Sstevel@tonic-gate usage(); 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate if (argc - optind > 1) 1097*7c478bd9Sstevel@tonic-gate usage(); 1098*7c478bd9Sstevel@tonic-gate 1099*7c478bd9Sstevel@tonic-gate callback = do_wait; 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate } else { 1102*7c478bd9Sstevel@tonic-gate callback = process_fmri; 1103*7c478bd9Sstevel@tonic-gate 1104*7c478bd9Sstevel@tonic-gate flags |= SCF_WALK_MULTIPLE; 1105*7c478bd9Sstevel@tonic-gate } 1106*7c478bd9Sstevel@tonic-gate 1107*7c478bd9Sstevel@tonic-gate if ((err = scf_walk_fmri(hndl, argc - optind, argv + optind, flags, 1108*7c478bd9Sstevel@tonic-gate callback, NULL, &return_code, warn)) != 0) { 1109*7c478bd9Sstevel@tonic-gate warn(gettext("failed to iterate over instances: %s\n"), 1110*7c478bd9Sstevel@tonic-gate scf_strerror(err)); 1111*7c478bd9Sstevel@tonic-gate return_code = UU_EXIT_FATAL; 1112*7c478bd9Sstevel@tonic-gate } 1113*7c478bd9Sstevel@tonic-gate 1114*7c478bd9Sstevel@tonic-gate scf_handle_destroy(hndl); 1115*7c478bd9Sstevel@tonic-gate 1116*7c478bd9Sstevel@tonic-gate return (return_code); 1117*7c478bd9Sstevel@tonic-gate } 1118