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