17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*3eae19d9Swesolows * Common Development and Distribution License (the "License"). 6*3eae19d9Swesolows * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*3eae19d9Swesolows 227c478bd9Sstevel@tonic-gate /* 23*3eae19d9Swesolows * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * svcprop - report service configuration properties 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <locale.h> 347c478bd9Sstevel@tonic-gate #include <libintl.h> 357c478bd9Sstevel@tonic-gate #include <libscf.h> 367c478bd9Sstevel@tonic-gate #include <libscf_priv.h> 377c478bd9Sstevel@tonic-gate #include <libuutil.h> 387c478bd9Sstevel@tonic-gate #include <stddef.h> 397c478bd9Sstevel@tonic-gate #include <stdio.h> 407c478bd9Sstevel@tonic-gate #include <stdlib.h> 417c478bd9Sstevel@tonic-gate #include <unistd.h> 427c478bd9Sstevel@tonic-gate #include <strings.h> 437c478bd9Sstevel@tonic-gate #include <assert.h> 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN 467c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SUNW_OST_OSCMD" 477c478bd9Sstevel@tonic-gate #endif /* TEXT_DOMAIN */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* 507c478bd9Sstevel@tonic-gate * Error functions. These can change if the quiet (-q) option is used. 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate static void (*warn)(const char *, ...) = uu_warn; 537c478bd9Sstevel@tonic-gate static void (*die)(const char *, ...) = uu_die; 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate /* 567c478bd9Sstevel@tonic-gate * Entity encapsulation. This allows me to treat services and instances 577c478bd9Sstevel@tonic-gate * similarly, and avoid duplicating process_ent(). 587c478bd9Sstevel@tonic-gate */ 597c478bd9Sstevel@tonic-gate typedef struct { 607c478bd9Sstevel@tonic-gate char type; /* !=0: service, 0: instance */ 617c478bd9Sstevel@tonic-gate union { 627c478bd9Sstevel@tonic-gate scf_service_t *svc; 637c478bd9Sstevel@tonic-gate scf_instance_t *inst; 647c478bd9Sstevel@tonic-gate } u; 657c478bd9Sstevel@tonic-gate } scf_entityp_t; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate #define ENT_INSTANCE 0 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #define SCF_ENTITY_SET_TO_SERVICE(ent, s) { ent.type = 1; ent.u.svc = s; } 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate #define SCF_ENTITY_SET_TO_INSTANCE(ent, i) \ 727c478bd9Sstevel@tonic-gate { ent.type = ENT_INSTANCE; ent.u.inst = i; } 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate #define scf_entity_get_pg(ent, name, pg) \ 757c478bd9Sstevel@tonic-gate (ent.type ? scf_service_get_pg(ent.u.svc, name, pg) : \ 767c478bd9Sstevel@tonic-gate scf_instance_get_pg(ent.u.inst, name, pg)) 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #define scf_entity_to_fmri(ent, buf, buf_sz) \ 797c478bd9Sstevel@tonic-gate (ent.type ? scf_service_to_fmri(ent.u.svc, buf, buf_sz) : \ 807c478bd9Sstevel@tonic-gate scf_instance_to_fmri(ent.u.inst, buf, buf_sz)) 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate #define SCF_ENTITY_TYPE_NAME(ent) (ent.type ? "service" : "instance") 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * Data structure for -p arguments. Since they may be name or name/name, we 867c478bd9Sstevel@tonic-gate * just track the components. 877c478bd9Sstevel@tonic-gate */ 887c478bd9Sstevel@tonic-gate typedef struct svcprop_prop_node { 897c478bd9Sstevel@tonic-gate uu_list_node_t spn_list_node; 907c478bd9Sstevel@tonic-gate const char *spn_comp1; 917c478bd9Sstevel@tonic-gate const char *spn_comp2; 927c478bd9Sstevel@tonic-gate } svcprop_prop_node_t; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate static uu_list_pool_t *prop_pool; 957c478bd9Sstevel@tonic-gate static uu_list_t *prop_list; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate static scf_handle_t *hndl; 987c478bd9Sstevel@tonic-gate static ssize_t max_scf_name_length; 997c478bd9Sstevel@tonic-gate static ssize_t max_scf_value_length; 1007c478bd9Sstevel@tonic-gate static ssize_t max_scf_fmri_length; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* Options */ 1037c478bd9Sstevel@tonic-gate static int quiet = 0; /* No output. Nothing found, exit(1) */ 1047c478bd9Sstevel@tonic-gate static int types = 0; /* Display types of properties. */ 1057c478bd9Sstevel@tonic-gate static int verbose = 0; /* Print not found errors to stderr. */ 1067c478bd9Sstevel@tonic-gate static int fmris = 0; /* Display full FMRIs for properties. */ 1077c478bd9Sstevel@tonic-gate static int wait = 0; /* Wait mode. */ 1087c478bd9Sstevel@tonic-gate static char *snapshot = "running"; /* Snapshot to use. */ 1097c478bd9Sstevel@tonic-gate static int Cflag = 0; /* C option supplied */ 1107c478bd9Sstevel@tonic-gate static int cflag = 0; /* c option supplied */ 1117c478bd9Sstevel@tonic-gate static int sflag = 0; /* s option supplied */ 1127c478bd9Sstevel@tonic-gate static int return_code; /* main's return code */ 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate #define PRINT_NOPROP_ERRORS (!quiet || verbose) 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate /* 1177c478bd9Sstevel@tonic-gate * For unexpected libscf errors. The ending newline is necessary to keep 1187c478bd9Sstevel@tonic-gate * uu_die() from appending the errno error. 1197c478bd9Sstevel@tonic-gate */ 1207c478bd9Sstevel@tonic-gate static void 1217c478bd9Sstevel@tonic-gate scfdie() 1227c478bd9Sstevel@tonic-gate { 1237c478bd9Sstevel@tonic-gate die(gettext("Unexpected libscf error: %s. Exiting.\n"), 1247c478bd9Sstevel@tonic-gate scf_strerror(scf_error())); 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate static void * 1287c478bd9Sstevel@tonic-gate safe_malloc(size_t sz) 1297c478bd9Sstevel@tonic-gate { 1307c478bd9Sstevel@tonic-gate void *p; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate p = malloc(sz); 1337c478bd9Sstevel@tonic-gate if (p == NULL) 1347c478bd9Sstevel@tonic-gate die(gettext("Could not allocate memory")); 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate return (p); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate static void 1407c478bd9Sstevel@tonic-gate usage() 1417c478bd9Sstevel@tonic-gate { 1427c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Usage: %1$s [-fqtv] " 1437c478bd9Sstevel@tonic-gate "[-C | -c | -s snapshot] " 1447c478bd9Sstevel@tonic-gate "[-p [name/]name]... \n" 1457c478bd9Sstevel@tonic-gate " {FMRI | pattern}...\n" 1467c478bd9Sstevel@tonic-gate " %1$s -w [-fqtv] [-p [name/]name] " 1477c478bd9Sstevel@tonic-gate "{FMRI | pattern}\n"), uu_getpname()); 1487c478bd9Sstevel@tonic-gate exit(UU_EXIT_USAGE); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate /* 1527c478bd9Sstevel@tonic-gate * Return an allocated copy of str, with the Bourne shell's metacharacters 1537c478bd9Sstevel@tonic-gate * escaped by '\'. 1547c478bd9Sstevel@tonic-gate * 1557c478bd9Sstevel@tonic-gate * What about unicode? 1567c478bd9Sstevel@tonic-gate */ 1577c478bd9Sstevel@tonic-gate static char * 1587c478bd9Sstevel@tonic-gate quote_for_shell(const char *str) 1597c478bd9Sstevel@tonic-gate { 1607c478bd9Sstevel@tonic-gate const char *sp; 1617c478bd9Sstevel@tonic-gate char *dst, *dp; 1627c478bd9Sstevel@tonic-gate size_t dst_len; 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate const char * const metachars = ";&()|^<>\n \t\\\"\'`"; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate if (str[0] == '\0') 1677c478bd9Sstevel@tonic-gate return (strdup("\"\"")); 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate dst_len = 0; 1707c478bd9Sstevel@tonic-gate for (sp = str; *sp != '\0'; ++sp) { 1717c478bd9Sstevel@tonic-gate ++dst_len; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate if (strchr(metachars, *sp) != NULL) 1747c478bd9Sstevel@tonic-gate ++dst_len; 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if (sp - str == dst_len) 1787c478bd9Sstevel@tonic-gate return (strdup(str)); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate dst = safe_malloc(dst_len + 1); 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate for (dp = dst, sp = str; *sp != '\0'; ++dp, ++sp) { 1837c478bd9Sstevel@tonic-gate if (strchr(metachars, *sp) != NULL) 1847c478bd9Sstevel@tonic-gate *dp++ = '\\'; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate *dp = *sp; 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate *dp = '\0'; 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate return (dst); 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate static void 1947c478bd9Sstevel@tonic-gate print_value(scf_value_t *val) 1957c478bd9Sstevel@tonic-gate { 1967c478bd9Sstevel@tonic-gate char *buf, *qbuf; 1977c478bd9Sstevel@tonic-gate ssize_t bufsz, r; 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate bufsz = scf_value_get_as_string(val, NULL, 0) + 1; 2007c478bd9Sstevel@tonic-gate if (bufsz - 1 < 0) 2017c478bd9Sstevel@tonic-gate scfdie(); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate buf = safe_malloc(bufsz); 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate r = scf_value_get_as_string(val, buf, bufsz); 2067c478bd9Sstevel@tonic-gate assert(r + 1 == bufsz); 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate qbuf = quote_for_shell(buf); 2097c478bd9Sstevel@tonic-gate (void) fputs(qbuf, stdout); 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate free(qbuf); 2127c478bd9Sstevel@tonic-gate free(buf); 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate /* 2167c478bd9Sstevel@tonic-gate * Display a property's values on a line. If types is true, prepend 2177c478bd9Sstevel@tonic-gate * identification (the FMRI if fmris is true, pg/prop otherwise) and the type 2187c478bd9Sstevel@tonic-gate * of the property. 2197c478bd9Sstevel@tonic-gate */ 2207c478bd9Sstevel@tonic-gate static void 2217c478bd9Sstevel@tonic-gate display_prop(scf_propertygroup_t *pg, scf_property_t *prop) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate scf_value_t *val; 2247c478bd9Sstevel@tonic-gate scf_iter_t *iter; 225*3eae19d9Swesolows int ret, first, err; 226*3eae19d9Swesolows 227*3eae19d9Swesolows const char * const permission_denied_emsg = 228*3eae19d9Swesolows gettext("Permission denied.\n"); 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate if (types) { 2317c478bd9Sstevel@tonic-gate scf_type_t ty; 2327c478bd9Sstevel@tonic-gate char *buf; 2337c478bd9Sstevel@tonic-gate size_t buf_sz; 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate if (fmris) { 2367c478bd9Sstevel@tonic-gate buf_sz = max_scf_fmri_length + 1; 2377c478bd9Sstevel@tonic-gate buf = safe_malloc(buf_sz); 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate if (scf_property_to_fmri(prop, buf, buf_sz) == -1) 2407c478bd9Sstevel@tonic-gate scfdie(); 2417c478bd9Sstevel@tonic-gate (void) fputs(buf, stdout); 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate free(buf); 2447c478bd9Sstevel@tonic-gate } else { 2457c478bd9Sstevel@tonic-gate buf_sz = max_scf_name_length + 1; 2467c478bd9Sstevel@tonic-gate buf = safe_malloc(buf_sz); 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate if (scf_pg_get_name(pg, buf, buf_sz) < 0) 2497c478bd9Sstevel@tonic-gate scfdie(); 2507c478bd9Sstevel@tonic-gate (void) fputs(buf, stdout); 2517c478bd9Sstevel@tonic-gate (void) putchar('/'); 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate if (scf_property_get_name(prop, buf, buf_sz) < 0) 2547c478bd9Sstevel@tonic-gate scfdie(); 2557c478bd9Sstevel@tonic-gate (void) fputs(buf, stdout); 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate free(buf); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate (void) putchar(' '); 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate if (scf_property_type(prop, &ty) == -1) 2637c478bd9Sstevel@tonic-gate scfdie(); 2647c478bd9Sstevel@tonic-gate (void) fputs(scf_type_to_string(ty), stdout); 2657c478bd9Sstevel@tonic-gate (void) putchar(' '); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate if ((iter = scf_iter_create(hndl)) == NULL || 2697c478bd9Sstevel@tonic-gate (val = scf_value_create(hndl)) == NULL) 2707c478bd9Sstevel@tonic-gate scfdie(); 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate if (scf_iter_property_values(iter, prop) == -1) 2737c478bd9Sstevel@tonic-gate scfdie(); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate first = 1; 2767c478bd9Sstevel@tonic-gate while ((ret = scf_iter_next_value(iter, val)) == 1) { 2777c478bd9Sstevel@tonic-gate if (first) 2787c478bd9Sstevel@tonic-gate first = 0; 2797c478bd9Sstevel@tonic-gate else 2807c478bd9Sstevel@tonic-gate (void) putchar(' '); 2817c478bd9Sstevel@tonic-gate print_value(val); 2827c478bd9Sstevel@tonic-gate } 283*3eae19d9Swesolows if (ret == -1) { 284*3eae19d9Swesolows err = scf_error(); 285*3eae19d9Swesolows if (err == SCF_ERROR_PERMISSION_DENIED) { 286*3eae19d9Swesolows if (uu_list_numnodes(prop_list) > 0) 287*3eae19d9Swesolows die(permission_denied_emsg); 288*3eae19d9Swesolows } else { 289*3eae19d9Swesolows scfdie(); 290*3eae19d9Swesolows } 291*3eae19d9Swesolows } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate (void) putchar('\n'); 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 2967c478bd9Sstevel@tonic-gate (void) scf_value_destroy(val); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate /* 3007c478bd9Sstevel@tonic-gate * display_prop() all of the properties in the given property group. Force 3017c478bd9Sstevel@tonic-gate * types to true so identification will be displayed. 3027c478bd9Sstevel@tonic-gate */ 3037c478bd9Sstevel@tonic-gate static void 3047c478bd9Sstevel@tonic-gate display_pg(scf_propertygroup_t *pg) 3057c478bd9Sstevel@tonic-gate { 3067c478bd9Sstevel@tonic-gate scf_property_t *prop; 3077c478bd9Sstevel@tonic-gate scf_iter_t *iter; 3087c478bd9Sstevel@tonic-gate int ret; 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate types = 1; /* Always display types for whole propertygroups. */ 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate if ((prop = scf_property_create(hndl)) == NULL || 3137c478bd9Sstevel@tonic-gate (iter = scf_iter_create(hndl)) == NULL) 3147c478bd9Sstevel@tonic-gate scfdie(); 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate if (scf_iter_pg_properties(iter, pg) == -1) 3177c478bd9Sstevel@tonic-gate scfdie(); 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate while ((ret = scf_iter_next_property(iter, prop)) == 1) 3207c478bd9Sstevel@tonic-gate display_prop(pg, prop); 3217c478bd9Sstevel@tonic-gate if (ret == -1) 3227c478bd9Sstevel@tonic-gate scfdie(); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 3257c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * Common code to execute when a nonexistant property is encountered. 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate static void 3327c478bd9Sstevel@tonic-gate noprop_common_action() 3337c478bd9Sstevel@tonic-gate { 3347c478bd9Sstevel@tonic-gate if (!PRINT_NOPROP_ERRORS) 3357c478bd9Sstevel@tonic-gate /* We're not printing errors, so we can cut out early. */ 3367c478bd9Sstevel@tonic-gate exit(UU_EXIT_FATAL); 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate return_code = UU_EXIT_FATAL; 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate /* 3427c478bd9Sstevel@tonic-gate * Iterate the properties of a service or an instance when no snapshot 3437c478bd9Sstevel@tonic-gate * is specified. 3447c478bd9Sstevel@tonic-gate */ 3457c478bd9Sstevel@tonic-gate static int 3467c478bd9Sstevel@tonic-gate scf_iter_entity_pgs(scf_iter_t *iter, scf_entityp_t ent) 3477c478bd9Sstevel@tonic-gate { 3487c478bd9Sstevel@tonic-gate int ret = 0; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate if (ent.type) { 3517c478bd9Sstevel@tonic-gate /* 3527c478bd9Sstevel@tonic-gate * If we are displaying properties for a service, 3537c478bd9Sstevel@tonic-gate * treat it as though it were a composed, current 3547c478bd9Sstevel@tonic-gate * lookup. (implicit cflag) However, if a snapshot 3557c478bd9Sstevel@tonic-gate * was specified, fail. 3567c478bd9Sstevel@tonic-gate */ 3577c478bd9Sstevel@tonic-gate if (sflag) 3587c478bd9Sstevel@tonic-gate die(gettext("Only instances have " 3597c478bd9Sstevel@tonic-gate "snapshots.\n")); 3607c478bd9Sstevel@tonic-gate ret = scf_iter_service_pgs(iter, ent.u.svc); 3617c478bd9Sstevel@tonic-gate } else { 3627c478bd9Sstevel@tonic-gate if (Cflag) 3637c478bd9Sstevel@tonic-gate ret = scf_iter_instance_pgs(iter, ent.u.inst); 3647c478bd9Sstevel@tonic-gate else 3657c478bd9Sstevel@tonic-gate ret = scf_iter_instance_pgs_composed(iter, ent.u.inst, 3667c478bd9Sstevel@tonic-gate NULL); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate return (ret); 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* 3727c478bd9Sstevel@tonic-gate * Return a snapshot for the supplied instance and snapshot name. 3737c478bd9Sstevel@tonic-gate */ 3747c478bd9Sstevel@tonic-gate static scf_snapshot_t * 3757c478bd9Sstevel@tonic-gate get_snapshot(const scf_instance_t *inst, const char *snapshot) 3767c478bd9Sstevel@tonic-gate { 3777c478bd9Sstevel@tonic-gate scf_snapshot_t *snap = scf_snapshot_create(hndl); 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate if (snap == NULL) 3807c478bd9Sstevel@tonic-gate scfdie(); 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate if (scf_instance_get_snapshot(inst, snapshot, snap) == -1) { 3837c478bd9Sstevel@tonic-gate switch (scf_error()) { 3847c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 3857c478bd9Sstevel@tonic-gate die(gettext("Invalid snapshot name.\n")); 3867c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 3897c478bd9Sstevel@tonic-gate if (sflag == 0) { 3907c478bd9Sstevel@tonic-gate scf_snapshot_destroy(snap); 3917c478bd9Sstevel@tonic-gate snap = NULL; 3927c478bd9Sstevel@tonic-gate } else 3937c478bd9Sstevel@tonic-gate die(gettext("No such snapshot.\n")); 3947c478bd9Sstevel@tonic-gate break; 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate default: 3977c478bd9Sstevel@tonic-gate scfdie(); 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate return (snap); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate /* 4057c478bd9Sstevel@tonic-gate * Entity (service or instance): If there are -p options, 4067c478bd9Sstevel@tonic-gate * display_{pg,prop}() the named property groups and/or properties. Otherwise 4077c478bd9Sstevel@tonic-gate * display_pg() all property groups. 4087c478bd9Sstevel@tonic-gate */ 4097c478bd9Sstevel@tonic-gate static void 4107c478bd9Sstevel@tonic-gate process_ent(scf_entityp_t ent) 4117c478bd9Sstevel@tonic-gate { 4127c478bd9Sstevel@tonic-gate scf_snapshot_t *snap = NULL; 4137c478bd9Sstevel@tonic-gate scf_propertygroup_t *pg; 4147c478bd9Sstevel@tonic-gate scf_property_t *prop; 4157c478bd9Sstevel@tonic-gate scf_iter_t *iter; 4167c478bd9Sstevel@tonic-gate svcprop_prop_node_t *spn; 4177c478bd9Sstevel@tonic-gate int ret, err; 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate if (uu_list_numnodes(prop_list) == 0) { 4207c478bd9Sstevel@tonic-gate if (quiet) 4217c478bd9Sstevel@tonic-gate return; 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate if ((pg = scf_pg_create(hndl)) == NULL || 4247c478bd9Sstevel@tonic-gate (iter = scf_iter_create(hndl)) == NULL) 4257c478bd9Sstevel@tonic-gate scfdie(); 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate if (cflag || Cflag || ent.type != ENT_INSTANCE) { 4287c478bd9Sstevel@tonic-gate if (scf_iter_entity_pgs(iter, ent) == -1) 4297c478bd9Sstevel@tonic-gate scfdie(); 4307c478bd9Sstevel@tonic-gate } else { 4317c478bd9Sstevel@tonic-gate if (snapshot != NULL) 4327c478bd9Sstevel@tonic-gate snap = get_snapshot(ent.u.inst, snapshot); 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate if (scf_iter_instance_pgs_composed(iter, ent.u.inst, 4357c478bd9Sstevel@tonic-gate snap) == -1) 4367c478bd9Sstevel@tonic-gate scfdie(); 4377c478bd9Sstevel@tonic-gate if (snap) 4387c478bd9Sstevel@tonic-gate scf_snapshot_destroy(snap); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate while ((ret = scf_iter_next_pg(iter, pg)) == 1) 4427c478bd9Sstevel@tonic-gate display_pg(pg); 4437c478bd9Sstevel@tonic-gate if (ret == -1) 4447c478bd9Sstevel@tonic-gate scfdie(); 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate /* 4477c478bd9Sstevel@tonic-gate * In normal usage, i.e. against the running snapshot, 4487c478bd9Sstevel@tonic-gate * we must iterate over the current non-persistent 4497c478bd9Sstevel@tonic-gate * pg's. 4507c478bd9Sstevel@tonic-gate */ 4517c478bd9Sstevel@tonic-gate if (sflag == 0 && snap != NULL) { 4527c478bd9Sstevel@tonic-gate scf_iter_reset(iter); 4537c478bd9Sstevel@tonic-gate if (scf_iter_instance_pgs_composed(iter, ent.u.inst, 4547c478bd9Sstevel@tonic-gate NULL) == -1) 4557c478bd9Sstevel@tonic-gate scfdie(); 4567c478bd9Sstevel@tonic-gate while ((ret = scf_iter_next_pg(iter, pg)) == 1) { 4577c478bd9Sstevel@tonic-gate uint32_t flags; 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate if (scf_pg_get_flags(pg, &flags) == -1) 4607c478bd9Sstevel@tonic-gate scfdie(); 4617c478bd9Sstevel@tonic-gate if (flags & SCF_PG_FLAG_NONPERSISTENT) 4627c478bd9Sstevel@tonic-gate display_pg(pg); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate if (ret == -1) 4667c478bd9Sstevel@tonic-gate scfdie(); 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 4697c478bd9Sstevel@tonic-gate scf_pg_destroy(pg); 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate return; 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate if ((pg = scf_pg_create(hndl)) == NULL || 4757c478bd9Sstevel@tonic-gate (prop = scf_property_create(hndl)) == NULL) 4767c478bd9Sstevel@tonic-gate scfdie(); 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate if (ent.type == ENT_INSTANCE && snapshot != NULL) 4797c478bd9Sstevel@tonic-gate snap = get_snapshot(ent.u.inst, snapshot); 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate for (spn = uu_list_first(prop_list); 4827c478bd9Sstevel@tonic-gate spn != NULL; 4837c478bd9Sstevel@tonic-gate spn = uu_list_next(prop_list, spn)) { 4847c478bd9Sstevel@tonic-gate if (ent.type == ENT_INSTANCE) { 4857c478bd9Sstevel@tonic-gate if (Cflag) 4867c478bd9Sstevel@tonic-gate ret = scf_instance_get_pg(ent.u.inst, 4877c478bd9Sstevel@tonic-gate spn->spn_comp1, pg); 4887c478bd9Sstevel@tonic-gate else 4897c478bd9Sstevel@tonic-gate ret = scf_instance_get_pg_composed(ent.u.inst, 4907c478bd9Sstevel@tonic-gate snap, spn->spn_comp1, pg); 4917c478bd9Sstevel@tonic-gate err = scf_error(); 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate /* 4947c478bd9Sstevel@tonic-gate * If we didn't find it in the specified snapshot, use 4957c478bd9Sstevel@tonic-gate * the current values if the pg is nonpersistent. 4967c478bd9Sstevel@tonic-gate */ 4977c478bd9Sstevel@tonic-gate if (ret == -1 && !Cflag &&snap != NULL && err == 4987c478bd9Sstevel@tonic-gate SCF_ERROR_NOT_FOUND) { 4997c478bd9Sstevel@tonic-gate ret = scf_instance_get_pg_composed( 5007c478bd9Sstevel@tonic-gate ent.u.inst, NULL, spn->spn_comp1, 5017c478bd9Sstevel@tonic-gate pg); 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate if (ret == 0) { 5047c478bd9Sstevel@tonic-gate uint32_t flags; 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate if (scf_pg_get_flags(pg, &flags) == -1) 5077c478bd9Sstevel@tonic-gate scfdie(); 5087c478bd9Sstevel@tonic-gate if ((flags & SCF_PG_FLAG_NONPERSISTENT) 5097c478bd9Sstevel@tonic-gate == 0) { 5107c478bd9Sstevel@tonic-gate ret = -1; 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate } 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate } else { 5157c478bd9Sstevel@tonic-gate /* 5167c478bd9Sstevel@tonic-gate * If we are displaying properties for a service, 5177c478bd9Sstevel@tonic-gate * treat it as though it were a composed, current 5187c478bd9Sstevel@tonic-gate * lookup. (implicit cflag) However, if a snapshot 5197c478bd9Sstevel@tonic-gate * was specified, fail. 5207c478bd9Sstevel@tonic-gate */ 5217c478bd9Sstevel@tonic-gate if (sflag) 5227c478bd9Sstevel@tonic-gate die(gettext("Only instances have " 5237c478bd9Sstevel@tonic-gate "snapshots.\n")); 5247c478bd9Sstevel@tonic-gate ret = scf_entity_get_pg(ent, spn->spn_comp1, pg); 5257c478bd9Sstevel@tonic-gate err = scf_error(); 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate if (ret == -1) { 5287c478bd9Sstevel@tonic-gate if (err != SCF_ERROR_NOT_FOUND) 5297c478bd9Sstevel@tonic-gate scfdie(); 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate if (PRINT_NOPROP_ERRORS) { 5327c478bd9Sstevel@tonic-gate char *buf; 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate buf = safe_malloc(max_scf_fmri_length + 1); 5357c478bd9Sstevel@tonic-gate if (scf_entity_to_fmri(ent, buf, 5367c478bd9Sstevel@tonic-gate max_scf_fmri_length + 1) == -1) 5377c478bd9Sstevel@tonic-gate scfdie(); 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate uu_warn(gettext("Couldn't find property group " 5407c478bd9Sstevel@tonic-gate "`%s' for %s `%s'.\n"), spn->spn_comp1, 5417c478bd9Sstevel@tonic-gate SCF_ENTITY_TYPE_NAME(ent), buf); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate free(buf); 5447c478bd9Sstevel@tonic-gate } 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate noprop_common_action(); 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate continue; 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate if (spn->spn_comp2 == NULL) { 5527c478bd9Sstevel@tonic-gate if (!quiet) 5537c478bd9Sstevel@tonic-gate display_pg(pg); 5547c478bd9Sstevel@tonic-gate continue; 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate if (scf_pg_get_property(pg, spn->spn_comp2, prop) == -1) { 5587c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 5597c478bd9Sstevel@tonic-gate scfdie(); 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate if (PRINT_NOPROP_ERRORS) { 5627c478bd9Sstevel@tonic-gate char *buf; 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate buf = safe_malloc(max_scf_fmri_length + 1); 5657c478bd9Sstevel@tonic-gate if (scf_entity_to_fmri(ent, buf, 5667c478bd9Sstevel@tonic-gate max_scf_fmri_length + 1) == -1) 5677c478bd9Sstevel@tonic-gate scfdie(); 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate /* FMRI syntax knowledge */ 5707c478bd9Sstevel@tonic-gate uu_warn(gettext("Couldn't find property " 5717c478bd9Sstevel@tonic-gate "`%s/%s' for %s `%s'.\n"), spn->spn_comp1, 5727c478bd9Sstevel@tonic-gate spn->spn_comp2, SCF_ENTITY_TYPE_NAME(ent), 5737c478bd9Sstevel@tonic-gate buf); 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate free(buf); 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate noprop_common_action(); 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate continue; 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate if (!quiet) 5847c478bd9Sstevel@tonic-gate display_prop(pg, prop); 5857c478bd9Sstevel@tonic-gate } 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 5887c478bd9Sstevel@tonic-gate scf_pg_destroy(pg); 5897c478bd9Sstevel@tonic-gate if (snap) 5907c478bd9Sstevel@tonic-gate scf_snapshot_destroy(snap); 5917c478bd9Sstevel@tonic-gate } 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate /* 5947c478bd9Sstevel@tonic-gate * Without -p options, just call display_pg(). Otherwise display_prop() the 5957c478bd9Sstevel@tonic-gate * named properties of the property group. 5967c478bd9Sstevel@tonic-gate */ 5977c478bd9Sstevel@tonic-gate static void 5987c478bd9Sstevel@tonic-gate process_pg(scf_propertygroup_t *pg) 5997c478bd9Sstevel@tonic-gate { 6007c478bd9Sstevel@tonic-gate scf_property_t *prop; 6017c478bd9Sstevel@tonic-gate svcprop_prop_node_t *spn; 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate if (uu_list_first(prop_list) == NULL) { 6047c478bd9Sstevel@tonic-gate if (quiet) 6057c478bd9Sstevel@tonic-gate return; 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate display_pg(pg); 6087c478bd9Sstevel@tonic-gate return; 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate prop = scf_property_create(hndl); 6127c478bd9Sstevel@tonic-gate if (prop == NULL) 6137c478bd9Sstevel@tonic-gate scfdie(); 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate for (spn = uu_list_first(prop_list); 6167c478bd9Sstevel@tonic-gate spn != NULL; 6177c478bd9Sstevel@tonic-gate spn = uu_list_next(prop_list, spn)) { 6187c478bd9Sstevel@tonic-gate if (spn->spn_comp2 != NULL) { 6197c478bd9Sstevel@tonic-gate char *buf; 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate buf = safe_malloc(max_scf_fmri_length + 1); 6227c478bd9Sstevel@tonic-gate if (scf_pg_to_fmri(pg, buf, max_scf_fmri_length + 1) == 6237c478bd9Sstevel@tonic-gate -1) 6247c478bd9Sstevel@tonic-gate scfdie(); 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("-p argument `%s/%s' " 6277c478bd9Sstevel@tonic-gate "has too many components for property " 6287c478bd9Sstevel@tonic-gate "group `%s'.\n"), spn->spn_comp1, spn->spn_comp2, 6297c478bd9Sstevel@tonic-gate buf); 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate free(buf); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate if (scf_pg_get_property(pg, spn->spn_comp1, prop) == 0) { 6357c478bd9Sstevel@tonic-gate if (!quiet) 6367c478bd9Sstevel@tonic-gate display_prop(pg, prop); 6377c478bd9Sstevel@tonic-gate continue; 6387c478bd9Sstevel@tonic-gate } 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 6417c478bd9Sstevel@tonic-gate scfdie(); 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate if (PRINT_NOPROP_ERRORS) { 6447c478bd9Sstevel@tonic-gate char *buf; 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate buf = safe_malloc(max_scf_fmri_length + 1); 6477c478bd9Sstevel@tonic-gate if (scf_pg_to_fmri(pg, buf, max_scf_fmri_length + 1) == 6487c478bd9Sstevel@tonic-gate -1) 6497c478bd9Sstevel@tonic-gate scfdie(); 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate uu_warn(gettext("Couldn't find property `%s' in " 6527c478bd9Sstevel@tonic-gate "property group `%s'.\n"), spn->spn_comp1, buf); 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate free(buf); 6557c478bd9Sstevel@tonic-gate } 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate noprop_common_action(); 6587c478bd9Sstevel@tonic-gate } 6597c478bd9Sstevel@tonic-gate } 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate /* 6627c478bd9Sstevel@tonic-gate * If there are -p options, show the error. Otherwise just call 6637c478bd9Sstevel@tonic-gate * display_prop(). 6647c478bd9Sstevel@tonic-gate */ 6657c478bd9Sstevel@tonic-gate static void 6667c478bd9Sstevel@tonic-gate process_prop(scf_propertygroup_t *pg, scf_property_t *prop) 6677c478bd9Sstevel@tonic-gate { 6687c478bd9Sstevel@tonic-gate if (uu_list_first(prop_list) != NULL) { 6697c478bd9Sstevel@tonic-gate uu_warn(gettext("The -p option cannot be used with property " 6707c478bd9Sstevel@tonic-gate "operands.\n")); 6717c478bd9Sstevel@tonic-gate usage(); 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate if (quiet) 6757c478bd9Sstevel@tonic-gate return; 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate display_prop(pg, prop); 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate /* Decode an operand & dispatch. */ 6817c478bd9Sstevel@tonic-gate /* ARGSUSED */ 6827c478bd9Sstevel@tonic-gate static int 6837c478bd9Sstevel@tonic-gate process_fmri(void *unused, scf_walkinfo_t *wip) 6847c478bd9Sstevel@tonic-gate { 6857c478bd9Sstevel@tonic-gate scf_entityp_t ent; 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate /* Multiple matches imply multiple entities. */ 6887c478bd9Sstevel@tonic-gate if (wip->count > 1) 6897c478bd9Sstevel@tonic-gate types = fmris = 1; 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate if (wip->prop != NULL) { 6927c478bd9Sstevel@tonic-gate process_prop(wip->pg, wip->prop); 6937c478bd9Sstevel@tonic-gate } else if (wip->pg != NULL) { 6947c478bd9Sstevel@tonic-gate process_pg(wip->pg); 6957c478bd9Sstevel@tonic-gate } else if (wip->inst != NULL) { 6967c478bd9Sstevel@tonic-gate SCF_ENTITY_SET_TO_INSTANCE(ent, wip->inst); 6977c478bd9Sstevel@tonic-gate process_ent(ent); 6987c478bd9Sstevel@tonic-gate } else { 6997c478bd9Sstevel@tonic-gate /* scf_walk_fmri() won't let this happen */ 7007c478bd9Sstevel@tonic-gate assert(wip->svc != NULL); 7017c478bd9Sstevel@tonic-gate SCF_ENTITY_SET_TO_SERVICE(ent, wip->svc); 7027c478bd9Sstevel@tonic-gate process_ent(ent); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate return (0); 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate static void 7097c478bd9Sstevel@tonic-gate add_prop(char *property) 7107c478bd9Sstevel@tonic-gate { 7117c478bd9Sstevel@tonic-gate svcprop_prop_node_t *p, *last; 7127c478bd9Sstevel@tonic-gate char *slash; 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate const char * const invalid_component_emsg = 7157c478bd9Sstevel@tonic-gate gettext("Invalid component name `%s'.\n"); 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate /* FMRI syntax knowledge. */ 7187c478bd9Sstevel@tonic-gate slash = strchr(property, '/'); 7197c478bd9Sstevel@tonic-gate if (slash != NULL) { 7207c478bd9Sstevel@tonic-gate if (strchr(slash + 1, '/') != NULL) { 7217c478bd9Sstevel@tonic-gate uu_warn(gettext("-p argument `%s' has too many " 7227c478bd9Sstevel@tonic-gate "components.\n"), property); 7237c478bd9Sstevel@tonic-gate usage(); 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate if (slash != NULL) 7287c478bd9Sstevel@tonic-gate *slash = '\0'; 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate p = safe_malloc(sizeof (svcprop_prop_node_t)); 7317c478bd9Sstevel@tonic-gate uu_list_node_init(p, &p->spn_list_node, prop_pool); 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate p->spn_comp1 = property; 7347c478bd9Sstevel@tonic-gate p->spn_comp2 = (slash == NULL) ? NULL : slash + 1; 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate if (uu_check_name(p->spn_comp1, UU_NAME_DOMAIN) == -1) 7377c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, invalid_component_emsg, p->spn_comp1); 7387c478bd9Sstevel@tonic-gate if (p->spn_comp2 != NULL && 7397c478bd9Sstevel@tonic-gate uu_check_name(p->spn_comp2, UU_NAME_DOMAIN) == -1) 7407c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, invalid_component_emsg, p->spn_comp2); 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate last = uu_list_last(prop_list); 7437c478bd9Sstevel@tonic-gate if (last != NULL) { 7447c478bd9Sstevel@tonic-gate if ((last->spn_comp2 == NULL) ^ (p->spn_comp2 == NULL)) { 7457c478bd9Sstevel@tonic-gate /* 7467c478bd9Sstevel@tonic-gate * The -p options have mixed numbers of components. 7477c478bd9Sstevel@tonic-gate * If they both turn out to be valid, then the 7487c478bd9Sstevel@tonic-gate * single-component ones will specify property groups, 7497c478bd9Sstevel@tonic-gate * so we need to turn on types to keep the output of 7507c478bd9Sstevel@tonic-gate * display_prop() consistent with display_pg(). 7517c478bd9Sstevel@tonic-gate */ 7527c478bd9Sstevel@tonic-gate types = 1; 7537c478bd9Sstevel@tonic-gate } 7547c478bd9Sstevel@tonic-gate } 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate (void) uu_list_insert_after(prop_list, NULL, p); 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate /* 7617c478bd9Sstevel@tonic-gate * Wait for a property group or property change. 7627c478bd9Sstevel@tonic-gate * 7637c478bd9Sstevel@tonic-gate * Extract a pg and optionally a property name from fmri & prop_list. 7647c478bd9Sstevel@tonic-gate * _scf_pg_wait() for the pg, and display_pg(pg) or display_prop(pg, prop) 7657c478bd9Sstevel@tonic-gate * when it returns. 7667c478bd9Sstevel@tonic-gate */ 7677c478bd9Sstevel@tonic-gate /* ARGSUSED */ 7687c478bd9Sstevel@tonic-gate static int 7697c478bd9Sstevel@tonic-gate do_wait(void *unused, scf_walkinfo_t *wip) 7707c478bd9Sstevel@tonic-gate { 7717c478bd9Sstevel@tonic-gate scf_property_t *prop; 7727c478bd9Sstevel@tonic-gate scf_propertygroup_t *lpg, *pg; 7737c478bd9Sstevel@tonic-gate const char *propname; 7747c478bd9Sstevel@tonic-gate svcprop_prop_node_t *p; 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate const char *emsg_not_found = gettext("Not found.\n"); 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate if ((lpg = scf_pg_create(hndl)) == NULL || 7797c478bd9Sstevel@tonic-gate (prop = scf_property_create(hndl)) == NULL) 7807c478bd9Sstevel@tonic-gate scfdie(); 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate if (wip->prop != NULL) { 7837c478bd9Sstevel@tonic-gate if (uu_list_numnodes(prop_list) > 0) 7847c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("-p cannot be used with " 7857c478bd9Sstevel@tonic-gate "property FMRIs.\n")); 7867c478bd9Sstevel@tonic-gate pg = wip->pg; 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate assert(strrchr(wip->fmri, '/') != NULL); 7897c478bd9Sstevel@tonic-gate propname = strrchr(wip->fmri, '/') + 1; 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate } else if (wip->pg != NULL) { 7927c478bd9Sstevel@tonic-gate p = uu_list_first(prop_list); 7937c478bd9Sstevel@tonic-gate 7947c478bd9Sstevel@tonic-gate if (p != NULL) { 7957c478bd9Sstevel@tonic-gate if (p->spn_comp2 != NULL) 7967c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("-p argument " 7977c478bd9Sstevel@tonic-gate "\"%s/%s\" has too many components for " 7987c478bd9Sstevel@tonic-gate "property group %s.\n"), 7997c478bd9Sstevel@tonic-gate p->spn_comp1, p->spn_comp2, wip->fmri); 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate propname = p->spn_comp1; 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate if (scf_pg_get_property(wip->pg, propname, prop) != 8047c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 8057c478bd9Sstevel@tonic-gate switch (scf_error()) { 8067c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 8077c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 8087c478bd9Sstevel@tonic-gate gettext("Invalid property name " 8097c478bd9Sstevel@tonic-gate "\"%s\".\n"), propname); 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate /* NOTREACHED */ 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 8147c478bd9Sstevel@tonic-gate die(emsg_not_found); 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate /* NOTREACHED */ 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate default: 8197c478bd9Sstevel@tonic-gate scfdie(); 8207c478bd9Sstevel@tonic-gate } 8217c478bd9Sstevel@tonic-gate } 8227c478bd9Sstevel@tonic-gate } else { 8237c478bd9Sstevel@tonic-gate propname = NULL; 8247c478bd9Sstevel@tonic-gate } 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate pg = wip->pg; 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate } else if (wip->inst != NULL) { 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate p = uu_list_first(prop_list); 8317c478bd9Sstevel@tonic-gate if (p == NULL) 8327c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 8337c478bd9Sstevel@tonic-gate gettext("Cannot wait for an instance.\n")); 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate if (scf_instance_get_pg(wip->inst, p->spn_comp1, lpg) != 8367c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 8377c478bd9Sstevel@tonic-gate switch (scf_error()) { 8387c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 8397c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("Invalid " 8407c478bd9Sstevel@tonic-gate "property group name \"%s\".\n"), 8417c478bd9Sstevel@tonic-gate p->spn_comp1); 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 8447c478bd9Sstevel@tonic-gate die(emsg_not_found); 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gate /* NOTREACHED */ 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate default: 8497c478bd9Sstevel@tonic-gate scfdie(); 8507c478bd9Sstevel@tonic-gate } 8517c478bd9Sstevel@tonic-gate } 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate propname = p->spn_comp2; 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate if (propname != NULL) { 8567c478bd9Sstevel@tonic-gate if (scf_pg_get_property(lpg, propname, prop) != 8577c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 8587c478bd9Sstevel@tonic-gate switch (scf_error()) { 8597c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 8607c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 8617c478bd9Sstevel@tonic-gate gettext("Invalid property name " 8627c478bd9Sstevel@tonic-gate "\"%s\".\n"), propname); 8637c478bd9Sstevel@tonic-gate 8647c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 8657c478bd9Sstevel@tonic-gate die(emsg_not_found); 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate /* NOTREACHED */ 8687c478bd9Sstevel@tonic-gate 8697c478bd9Sstevel@tonic-gate default: 8707c478bd9Sstevel@tonic-gate scfdie(); 8717c478bd9Sstevel@tonic-gate } 8727c478bd9Sstevel@tonic-gate } 8737c478bd9Sstevel@tonic-gate } 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate pg = lpg; 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate } else if (wip->svc != NULL) { 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate p = uu_list_first(prop_list); 8807c478bd9Sstevel@tonic-gate if (p == NULL) 8817c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 8827c478bd9Sstevel@tonic-gate gettext("Cannot wait for a service.\n")); 8837c478bd9Sstevel@tonic-gate 8847c478bd9Sstevel@tonic-gate if (scf_service_get_pg(wip->svc, p->spn_comp1, lpg) != 8857c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 8867c478bd9Sstevel@tonic-gate switch (scf_error()) { 8877c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 8887c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("Invalid " 8897c478bd9Sstevel@tonic-gate "property group name \"%s\".\n"), 8907c478bd9Sstevel@tonic-gate p->spn_comp1); 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 8937c478bd9Sstevel@tonic-gate die(emsg_not_found); 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate default: 8967c478bd9Sstevel@tonic-gate scfdie(); 8977c478bd9Sstevel@tonic-gate } 8987c478bd9Sstevel@tonic-gate } 8997c478bd9Sstevel@tonic-gate 9007c478bd9Sstevel@tonic-gate propname = p->spn_comp2; 9017c478bd9Sstevel@tonic-gate 9027c478bd9Sstevel@tonic-gate if (propname != NULL) { 9037c478bd9Sstevel@tonic-gate if (scf_pg_get_property(lpg, propname, prop) != 9047c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 9057c478bd9Sstevel@tonic-gate switch (scf_error()) { 9067c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 9077c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, 9087c478bd9Sstevel@tonic-gate gettext("Invalid property name " 9097c478bd9Sstevel@tonic-gate "\"%s\".\n"), propname); 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate /* NOTREACHED */ 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 9147c478bd9Sstevel@tonic-gate die(emsg_not_found); 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate /* NOTREACHED */ 9177c478bd9Sstevel@tonic-gate 9187c478bd9Sstevel@tonic-gate default: 9197c478bd9Sstevel@tonic-gate scfdie(); 9207c478bd9Sstevel@tonic-gate } 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate } 9237c478bd9Sstevel@tonic-gate 9247c478bd9Sstevel@tonic-gate pg = lpg; 9257c478bd9Sstevel@tonic-gate 9267c478bd9Sstevel@tonic-gate } else { 9277c478bd9Sstevel@tonic-gate uu_xdie(UU_EXIT_USAGE, gettext("FMRI must specify an entity, " 9287c478bd9Sstevel@tonic-gate "property group, or property.\n")); 9297c478bd9Sstevel@tonic-gate } 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate for (;;) { 9327c478bd9Sstevel@tonic-gate int ret; 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate ret = _scf_pg_wait(pg, -1); 9357c478bd9Sstevel@tonic-gate if (ret != SCF_SUCCESS) 9367c478bd9Sstevel@tonic-gate scfdie(); 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate ret = scf_pg_update(pg); 9397c478bd9Sstevel@tonic-gate if (ret < 0) { 9407c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_DELETED) 9417c478bd9Sstevel@tonic-gate scfdie(); 9427c478bd9Sstevel@tonic-gate 9437c478bd9Sstevel@tonic-gate die(emsg_not_found); 9447c478bd9Sstevel@tonic-gate } 9457c478bd9Sstevel@tonic-gate if (ret == SCF_COMPLETE) 9467c478bd9Sstevel@tonic-gate break; 9477c478bd9Sstevel@tonic-gate } 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate if (propname != NULL) { 9507c478bd9Sstevel@tonic-gate if (scf_pg_get_property(pg, propname, prop) == SCF_SUCCESS) { 9517c478bd9Sstevel@tonic-gate if (!quiet) 9527c478bd9Sstevel@tonic-gate display_prop(pg, prop); 9537c478bd9Sstevel@tonic-gate } else { 9547c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 9557c478bd9Sstevel@tonic-gate scfdie(); 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate if (PRINT_NOPROP_ERRORS) 9587c478bd9Sstevel@tonic-gate uu_warn(emsg_not_found); 9597c478bd9Sstevel@tonic-gate 9607c478bd9Sstevel@tonic-gate return_code = UU_EXIT_FATAL; 9617c478bd9Sstevel@tonic-gate } 9627c478bd9Sstevel@tonic-gate } else { 9637c478bd9Sstevel@tonic-gate if (!quiet) 9647c478bd9Sstevel@tonic-gate display_pg(pg); 9657c478bd9Sstevel@tonic-gate } 9667c478bd9Sstevel@tonic-gate 9677c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 9687c478bd9Sstevel@tonic-gate scf_pg_destroy(lpg); 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate return (0); 9717c478bd9Sstevel@tonic-gate } 9727c478bd9Sstevel@tonic-gate 9737c478bd9Sstevel@tonic-gate /* 9747c478bd9Sstevel@tonic-gate * These functions replace uu_warn() and uu_die() when the quiet (-q) option is 9757c478bd9Sstevel@tonic-gate * used, and silently ignore any output. 9767c478bd9Sstevel@tonic-gate */ 9777c478bd9Sstevel@tonic-gate 9787c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 9797c478bd9Sstevel@tonic-gate static void 9807c478bd9Sstevel@tonic-gate quiet_warn(const char *fmt, ...) 9817c478bd9Sstevel@tonic-gate { 9827c478bd9Sstevel@tonic-gate /* Do nothing */ 9837c478bd9Sstevel@tonic-gate } 9847c478bd9Sstevel@tonic-gate 9857c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 9867c478bd9Sstevel@tonic-gate static void 9877c478bd9Sstevel@tonic-gate quiet_die(const char *fmt, ...) 9887c478bd9Sstevel@tonic-gate { 9897c478bd9Sstevel@tonic-gate exit(UU_EXIT_FATAL); 9907c478bd9Sstevel@tonic-gate } 9917c478bd9Sstevel@tonic-gate 9927c478bd9Sstevel@tonic-gate int 9937c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 9947c478bd9Sstevel@tonic-gate { 9957c478bd9Sstevel@tonic-gate int c; 9967c478bd9Sstevel@tonic-gate scf_walk_callback callback; 9977c478bd9Sstevel@tonic-gate int flags; 9987c478bd9Sstevel@tonic-gate int err; 9997c478bd9Sstevel@tonic-gate 10007c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 10017c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate return_code = UU_EXIT_OK; 10047c478bd9Sstevel@tonic-gate 10057c478bd9Sstevel@tonic-gate (void) uu_setpname(argv[0]); 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate prop_pool = uu_list_pool_create("properties", 10087c478bd9Sstevel@tonic-gate sizeof (svcprop_prop_node_t), 10097c478bd9Sstevel@tonic-gate offsetof(svcprop_prop_node_t, spn_list_node), NULL, 0); 10107c478bd9Sstevel@tonic-gate if (prop_pool == NULL) 10117c478bd9Sstevel@tonic-gate uu_die("%s\n", uu_strerror(uu_error())); 10127c478bd9Sstevel@tonic-gate 10137c478bd9Sstevel@tonic-gate prop_list = uu_list_create(prop_pool, NULL, 0); 10147c478bd9Sstevel@tonic-gate 10157c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "Ccfp:qs:tvw")) != -1) { 10167c478bd9Sstevel@tonic-gate switch (c) { 10177c478bd9Sstevel@tonic-gate case 'C': 10187c478bd9Sstevel@tonic-gate if (cflag || sflag || wait) 10197c478bd9Sstevel@tonic-gate usage(); /* Not with -c, -s or -w */ 10207c478bd9Sstevel@tonic-gate Cflag++; 10217c478bd9Sstevel@tonic-gate snapshot = NULL; 10227c478bd9Sstevel@tonic-gate break; 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate case 'c': 10257c478bd9Sstevel@tonic-gate if (Cflag || sflag || wait) 10267c478bd9Sstevel@tonic-gate usage(); /* Not with -C, -s or -w */ 10277c478bd9Sstevel@tonic-gate cflag++; 10287c478bd9Sstevel@tonic-gate snapshot = NULL; 10297c478bd9Sstevel@tonic-gate break; 10307c478bd9Sstevel@tonic-gate 10317c478bd9Sstevel@tonic-gate case 'f': 10327c478bd9Sstevel@tonic-gate types = 1; 10337c478bd9Sstevel@tonic-gate fmris = 1; 10347c478bd9Sstevel@tonic-gate break; 10357c478bd9Sstevel@tonic-gate 10367c478bd9Sstevel@tonic-gate case 'p': 10377c478bd9Sstevel@tonic-gate add_prop(optarg); 10387c478bd9Sstevel@tonic-gate break; 10397c478bd9Sstevel@tonic-gate 10407c478bd9Sstevel@tonic-gate case 'q': 10417c478bd9Sstevel@tonic-gate quiet = 1; 10427c478bd9Sstevel@tonic-gate warn = quiet_warn; 10437c478bd9Sstevel@tonic-gate die = quiet_die; 10447c478bd9Sstevel@tonic-gate break; 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate case 's': 10477c478bd9Sstevel@tonic-gate if (Cflag || cflag || wait) 10487c478bd9Sstevel@tonic-gate usage(); /* Not with -C, -c or -w */ 10497c478bd9Sstevel@tonic-gate snapshot = optarg; 10507c478bd9Sstevel@tonic-gate sflag++; 10517c478bd9Sstevel@tonic-gate break; 10527c478bd9Sstevel@tonic-gate 10537c478bd9Sstevel@tonic-gate case 't': 10547c478bd9Sstevel@tonic-gate types = 1; 10557c478bd9Sstevel@tonic-gate break; 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate case 'v': 10587c478bd9Sstevel@tonic-gate verbose = 1; 10597c478bd9Sstevel@tonic-gate break; 10607c478bd9Sstevel@tonic-gate 10617c478bd9Sstevel@tonic-gate case 'w': 10627c478bd9Sstevel@tonic-gate if (Cflag || cflag || sflag) 10637c478bd9Sstevel@tonic-gate usage(); /* Not with -C, -c or -s */ 10647c478bd9Sstevel@tonic-gate wait = 1; 10657c478bd9Sstevel@tonic-gate break; 10667c478bd9Sstevel@tonic-gate 10677c478bd9Sstevel@tonic-gate case '?': 10687c478bd9Sstevel@tonic-gate switch (optopt) { 10697c478bd9Sstevel@tonic-gate case 'p': 10707c478bd9Sstevel@tonic-gate usage(); 10717c478bd9Sstevel@tonic-gate 10727c478bd9Sstevel@tonic-gate default: 10737c478bd9Sstevel@tonic-gate break; 10747c478bd9Sstevel@tonic-gate } 10757c478bd9Sstevel@tonic-gate 10767c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 10777c478bd9Sstevel@tonic-gate 10787c478bd9Sstevel@tonic-gate default: 10797c478bd9Sstevel@tonic-gate usage(); 10807c478bd9Sstevel@tonic-gate } 10817c478bd9Sstevel@tonic-gate } 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate if (optind == argc) 10847c478bd9Sstevel@tonic-gate usage(); 10857c478bd9Sstevel@tonic-gate 10867c478bd9Sstevel@tonic-gate max_scf_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH); 10877c478bd9Sstevel@tonic-gate max_scf_value_length = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH); 10887c478bd9Sstevel@tonic-gate max_scf_fmri_length = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); 10897c478bd9Sstevel@tonic-gate if (max_scf_name_length == -1 || max_scf_value_length == -1 || 10907c478bd9Sstevel@tonic-gate max_scf_fmri_length == -1) 10917c478bd9Sstevel@tonic-gate scfdie(); 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate hndl = scf_handle_create(SCF_VERSION); 10947c478bd9Sstevel@tonic-gate if (hndl == NULL) 10957c478bd9Sstevel@tonic-gate scfdie(); 10967c478bd9Sstevel@tonic-gate if (scf_handle_bind(hndl) == -1) 10977c478bd9Sstevel@tonic-gate die(gettext("Could not connect to configuration repository: " 10987c478bd9Sstevel@tonic-gate "%s.\n"), scf_strerror(scf_error())); 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate flags = SCF_WALK_PROPERTY | SCF_WALK_SERVICE | SCF_WALK_EXPLICIT; 11017c478bd9Sstevel@tonic-gate 11027c478bd9Sstevel@tonic-gate if (wait) { 11037c478bd9Sstevel@tonic-gate if (uu_list_numnodes(prop_list) > 1) 11047c478bd9Sstevel@tonic-gate usage(); 11057c478bd9Sstevel@tonic-gate 11067c478bd9Sstevel@tonic-gate if (argc - optind > 1) 11077c478bd9Sstevel@tonic-gate usage(); 11087c478bd9Sstevel@tonic-gate 11097c478bd9Sstevel@tonic-gate callback = do_wait; 11107c478bd9Sstevel@tonic-gate 11117c478bd9Sstevel@tonic-gate } else { 11127c478bd9Sstevel@tonic-gate callback = process_fmri; 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate flags |= SCF_WALK_MULTIPLE; 11157c478bd9Sstevel@tonic-gate } 11167c478bd9Sstevel@tonic-gate 11177c478bd9Sstevel@tonic-gate if ((err = scf_walk_fmri(hndl, argc - optind, argv + optind, flags, 11187c478bd9Sstevel@tonic-gate callback, NULL, &return_code, warn)) != 0) { 11197c478bd9Sstevel@tonic-gate warn(gettext("failed to iterate over instances: %s\n"), 11207c478bd9Sstevel@tonic-gate scf_strerror(err)); 11217c478bd9Sstevel@tonic-gate return_code = UU_EXIT_FATAL; 11227c478bd9Sstevel@tonic-gate } 11237c478bd9Sstevel@tonic-gate 11247c478bd9Sstevel@tonic-gate scf_handle_destroy(hndl); 11257c478bd9Sstevel@tonic-gate 11267c478bd9Sstevel@tonic-gate return (return_code); 11277c478bd9Sstevel@tonic-gate } 1128