1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include "libscf_impl.h" 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #include <libuutil.h> 32*7c478bd9Sstevel@tonic-gate #include <stdio.h> 33*7c478bd9Sstevel@tonic-gate #include <strings.h> 34*7c478bd9Sstevel@tonic-gate #include <string.h> 35*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 36*7c478bd9Sstevel@tonic-gate #include "midlevel_impl.h" 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #ifndef NDEBUG 40*7c478bd9Sstevel@tonic-gate #define bad_error(func, err) { \ 41*7c478bd9Sstevel@tonic-gate uu_warn("%s:%d: %s failed with unexpected error %d. Aborting.\n", \ 42*7c478bd9Sstevel@tonic-gate __FILE__, __LINE__, func, err); \ 43*7c478bd9Sstevel@tonic-gate abort(); \ 44*7c478bd9Sstevel@tonic-gate } 45*7c478bd9Sstevel@tonic-gate #else 46*7c478bd9Sstevel@tonic-gate #define bad_error(func, err) abort() 47*7c478bd9Sstevel@tonic-gate #endif 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate /* 50*7c478bd9Sstevel@tonic-gate * Internal private function that creates and binds a handle. 51*7c478bd9Sstevel@tonic-gate */ 52*7c478bd9Sstevel@tonic-gate static scf_handle_t * 53*7c478bd9Sstevel@tonic-gate handle_create(void) 54*7c478bd9Sstevel@tonic-gate { 55*7c478bd9Sstevel@tonic-gate scf_handle_t *h; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate h = scf_handle_create(SCF_VERSION); 58*7c478bd9Sstevel@tonic-gate if (h == NULL) 59*7c478bd9Sstevel@tonic-gate return (NULL); 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate if (scf_handle_bind(h) == -1) { 62*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 63*7c478bd9Sstevel@tonic-gate return (NULL); 64*7c478bd9Sstevel@tonic-gate } 65*7c478bd9Sstevel@tonic-gate return (h); 66*7c478bd9Sstevel@tonic-gate } 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate /* 69*7c478bd9Sstevel@tonic-gate * Given a base service FMRI and the names of a property group and property, 70*7c478bd9Sstevel@tonic-gate * assemble_fmri() merges them into a property FMRI. Note that if the base 71*7c478bd9Sstevel@tonic-gate * FMRI is NULL, assemble_fmri() gets the base FMRI from scf_myname(). 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate static char * 75*7c478bd9Sstevel@tonic-gate assemble_fmri(scf_handle_t *h, const char *base, const char *pg, 76*7c478bd9Sstevel@tonic-gate const char *prop) 77*7c478bd9Sstevel@tonic-gate { 78*7c478bd9Sstevel@tonic-gate size_t fmri_sz, pglen; 79*7c478bd9Sstevel@tonic-gate ssize_t baselen; 80*7c478bd9Sstevel@tonic-gate char *fmri_buf; 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate if (prop == NULL) { 83*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 84*7c478bd9Sstevel@tonic-gate return (NULL); 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate if (pg == NULL) 88*7c478bd9Sstevel@tonic-gate pglen = strlen(SCF_PG_APP_DEFAULT); 89*7c478bd9Sstevel@tonic-gate else 90*7c478bd9Sstevel@tonic-gate pglen = strlen(pg); 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate if (base == NULL) { 93*7c478bd9Sstevel@tonic-gate if ((baselen = scf_myname(h, NULL, 0)) == -1) 94*7c478bd9Sstevel@tonic-gate return (NULL); 95*7c478bd9Sstevel@tonic-gate } else { 96*7c478bd9Sstevel@tonic-gate baselen = strlen(base); 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate fmri_sz = baselen + sizeof (SCF_FMRI_PROPERTYGRP_PREFIX) - 1 + 100*7c478bd9Sstevel@tonic-gate pglen + sizeof (SCF_FMRI_PROPERTY_PREFIX) - 1 + 101*7c478bd9Sstevel@tonic-gate strlen(prop) + 1; 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate if ((fmri_buf = malloc(fmri_sz)) == NULL) { 104*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 105*7c478bd9Sstevel@tonic-gate return (NULL); 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate if (base == NULL) { 109*7c478bd9Sstevel@tonic-gate if (scf_myname(h, fmri_buf, fmri_sz) == -1) { 110*7c478bd9Sstevel@tonic-gate free(fmri_buf); 111*7c478bd9Sstevel@tonic-gate return (NULL); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate } else { 114*7c478bd9Sstevel@tonic-gate (void) strcpy(fmri_buf, base); 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate (void) strcat(fmri_buf, SCF_FMRI_PROPERTYGRP_PREFIX); 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate if (pg == NULL) 120*7c478bd9Sstevel@tonic-gate (void) strcat(fmri_buf, SCF_PG_APP_DEFAULT); 121*7c478bd9Sstevel@tonic-gate else 122*7c478bd9Sstevel@tonic-gate (void) strcat(fmri_buf, pg); 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate (void) strcat(fmri_buf, SCF_FMRI_PROPERTY_PREFIX); 125*7c478bd9Sstevel@tonic-gate (void) strcat(fmri_buf, prop); 126*7c478bd9Sstevel@tonic-gate return (fmri_buf); 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate /* 130*7c478bd9Sstevel@tonic-gate * Given a property, this function allocates and fills an scf_simple_prop_t 131*7c478bd9Sstevel@tonic-gate * with the data it contains. 132*7c478bd9Sstevel@tonic-gate */ 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate static scf_simple_prop_t * 135*7c478bd9Sstevel@tonic-gate fill_prop(scf_property_t *prop, const char *pgname, const char *propname, 136*7c478bd9Sstevel@tonic-gate scf_handle_t *h) 137*7c478bd9Sstevel@tonic-gate { 138*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *ret; 139*7c478bd9Sstevel@tonic-gate scf_iter_t *iter; 140*7c478bd9Sstevel@tonic-gate scf_value_t *val; 141*7c478bd9Sstevel@tonic-gate int iterret, i; 142*7c478bd9Sstevel@tonic-gate ssize_t valsize, numvals; 143*7c478bd9Sstevel@tonic-gate union scf_simple_prop_val *vallist = NULL, *vallist_backup = NULL; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate if ((ret = malloc(sizeof (*ret))) == NULL) { 146*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 147*7c478bd9Sstevel@tonic-gate return (NULL); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate ret->pr_next = NULL; 151*7c478bd9Sstevel@tonic-gate ret->pr_pg = NULL; 152*7c478bd9Sstevel@tonic-gate ret->pr_iter = 0; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate if (pgname == NULL) 155*7c478bd9Sstevel@tonic-gate ret->pr_pgname = strdup(SCF_PG_APP_DEFAULT); 156*7c478bd9Sstevel@tonic-gate else 157*7c478bd9Sstevel@tonic-gate ret->pr_pgname = strdup(pgname); 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate if (ret->pr_pgname == NULL) { 160*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 161*7c478bd9Sstevel@tonic-gate free(ret); 162*7c478bd9Sstevel@tonic-gate return (NULL); 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate if ((ret->pr_propname = strdup(propname)) == NULL) { 166*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 167*7c478bd9Sstevel@tonic-gate free(ret->pr_pgname); 168*7c478bd9Sstevel@tonic-gate free(ret); 169*7c478bd9Sstevel@tonic-gate return (NULL); 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate if (scf_property_type(prop, &ret->pr_type) == -1) 173*7c478bd9Sstevel@tonic-gate goto error3; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate if ((iter = scf_iter_create(h)) == NULL) 176*7c478bd9Sstevel@tonic-gate goto error3; 177*7c478bd9Sstevel@tonic-gate if ((val = scf_value_create(h)) == NULL) { 178*7c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 179*7c478bd9Sstevel@tonic-gate goto error3; 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate if (scf_iter_property_values(iter, prop) == -1) 183*7c478bd9Sstevel@tonic-gate goto error1; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate for (numvals = 0; (iterret = scf_iter_next_value(iter, val)) == 1; 186*7c478bd9Sstevel@tonic-gate numvals++) { 187*7c478bd9Sstevel@tonic-gate vallist_backup = vallist; 188*7c478bd9Sstevel@tonic-gate if ((vallist = realloc(vallist, (numvals + 1) * 189*7c478bd9Sstevel@tonic-gate sizeof (*vallist))) == NULL) { 190*7c478bd9Sstevel@tonic-gate vallist = vallist_backup; 191*7c478bd9Sstevel@tonic-gate goto error1; 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate switch (ret->pr_type) { 195*7c478bd9Sstevel@tonic-gate case SCF_TYPE_BOOLEAN: 196*7c478bd9Sstevel@tonic-gate if (scf_value_get_boolean(val, 197*7c478bd9Sstevel@tonic-gate &vallist[numvals].pv_bool) == -1) 198*7c478bd9Sstevel@tonic-gate goto error1; 199*7c478bd9Sstevel@tonic-gate break; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate case SCF_TYPE_COUNT: 202*7c478bd9Sstevel@tonic-gate if (scf_value_get_count(val, 203*7c478bd9Sstevel@tonic-gate &vallist[numvals].pv_uint) == -1) 204*7c478bd9Sstevel@tonic-gate goto error1; 205*7c478bd9Sstevel@tonic-gate break; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate case SCF_TYPE_INTEGER: 208*7c478bd9Sstevel@tonic-gate if (scf_value_get_integer(val, 209*7c478bd9Sstevel@tonic-gate &vallist[numvals].pv_int) == -1) 210*7c478bd9Sstevel@tonic-gate goto error1; 211*7c478bd9Sstevel@tonic-gate break; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate case SCF_TYPE_TIME: 214*7c478bd9Sstevel@tonic-gate if (scf_value_get_time(val, 215*7c478bd9Sstevel@tonic-gate &vallist[numvals].pv_time.t_sec, 216*7c478bd9Sstevel@tonic-gate &vallist[numvals].pv_time.t_nsec) == -1) 217*7c478bd9Sstevel@tonic-gate goto error1; 218*7c478bd9Sstevel@tonic-gate break; 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate case SCF_TYPE_ASTRING: 221*7c478bd9Sstevel@tonic-gate vallist[numvals].pv_str = NULL; 222*7c478bd9Sstevel@tonic-gate if ((valsize = scf_value_get_astring(val, NULL, 0)) == 223*7c478bd9Sstevel@tonic-gate -1) 224*7c478bd9Sstevel@tonic-gate goto error1; 225*7c478bd9Sstevel@tonic-gate if ((vallist[numvals].pv_str = malloc(valsize+1)) == 226*7c478bd9Sstevel@tonic-gate NULL) { 227*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 228*7c478bd9Sstevel@tonic-gate goto error1; 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate if (scf_value_get_astring(val, 231*7c478bd9Sstevel@tonic-gate vallist[numvals].pv_str, valsize+1) == -1) { 232*7c478bd9Sstevel@tonic-gate free(vallist[numvals].pv_str); 233*7c478bd9Sstevel@tonic-gate goto error1; 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate break; 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate case SCF_TYPE_USTRING: 238*7c478bd9Sstevel@tonic-gate case SCF_TYPE_HOST: 239*7c478bd9Sstevel@tonic-gate case SCF_TYPE_HOSTNAME: 240*7c478bd9Sstevel@tonic-gate case SCF_TYPE_NET_ADDR_V4: 241*7c478bd9Sstevel@tonic-gate case SCF_TYPE_NET_ADDR_V6: 242*7c478bd9Sstevel@tonic-gate case SCF_TYPE_URI: 243*7c478bd9Sstevel@tonic-gate case SCF_TYPE_FMRI: 244*7c478bd9Sstevel@tonic-gate vallist[numvals].pv_str = NULL; 245*7c478bd9Sstevel@tonic-gate if ((valsize = scf_value_get_ustring(val, NULL, 0)) == 246*7c478bd9Sstevel@tonic-gate -1) 247*7c478bd9Sstevel@tonic-gate goto error1; 248*7c478bd9Sstevel@tonic-gate if ((vallist[numvals].pv_str = malloc(valsize+1)) == 249*7c478bd9Sstevel@tonic-gate NULL) { 250*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 251*7c478bd9Sstevel@tonic-gate goto error1; 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate if (scf_value_get_ustring(val, 254*7c478bd9Sstevel@tonic-gate vallist[numvals].pv_str, valsize+1) == -1) { 255*7c478bd9Sstevel@tonic-gate free(vallist[numvals].pv_str); 256*7c478bd9Sstevel@tonic-gate goto error1; 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate break; 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate case SCF_TYPE_OPAQUE: 261*7c478bd9Sstevel@tonic-gate vallist[numvals].pv_opaque.o_value = NULL; 262*7c478bd9Sstevel@tonic-gate if ((valsize = scf_value_get_opaque(val, NULL, 0)) == 263*7c478bd9Sstevel@tonic-gate -1) 264*7c478bd9Sstevel@tonic-gate goto error1; 265*7c478bd9Sstevel@tonic-gate if ((vallist[numvals].pv_opaque.o_value = 266*7c478bd9Sstevel@tonic-gate malloc(valsize)) == NULL) { 267*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 268*7c478bd9Sstevel@tonic-gate goto error1; 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate vallist[numvals].pv_opaque.o_size = valsize; 271*7c478bd9Sstevel@tonic-gate if (scf_value_get_opaque(val, 272*7c478bd9Sstevel@tonic-gate vallist[numvals].pv_opaque.o_value, 273*7c478bd9Sstevel@tonic-gate valsize) == -1) { 274*7c478bd9Sstevel@tonic-gate free(vallist[numvals].pv_opaque.o_value); 275*7c478bd9Sstevel@tonic-gate goto error1; 276*7c478bd9Sstevel@tonic-gate } 277*7c478bd9Sstevel@tonic-gate break; 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate default: 280*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 281*7c478bd9Sstevel@tonic-gate goto error1; 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate if (iterret == -1) { 287*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 288*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 289*7c478bd9Sstevel@tonic-gate goto error1; 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate ret->pr_vallist = vallist; 293*7c478bd9Sstevel@tonic-gate ret->pr_numvalues = numvals; 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 296*7c478bd9Sstevel@tonic-gate (void) scf_value_destroy(val); 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate return (ret); 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate /* 301*7c478bd9Sstevel@tonic-gate * Exit point for a successful call. Below this line are exit points 302*7c478bd9Sstevel@tonic-gate * for failures at various stages during the function. 303*7c478bd9Sstevel@tonic-gate */ 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate error1: 306*7c478bd9Sstevel@tonic-gate if (vallist == NULL) 307*7c478bd9Sstevel@tonic-gate goto error2; 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate switch (ret->pr_type) { 310*7c478bd9Sstevel@tonic-gate case SCF_TYPE_ASTRING: 311*7c478bd9Sstevel@tonic-gate case SCF_TYPE_USTRING: 312*7c478bd9Sstevel@tonic-gate case SCF_TYPE_HOST: 313*7c478bd9Sstevel@tonic-gate case SCF_TYPE_HOSTNAME: 314*7c478bd9Sstevel@tonic-gate case SCF_TYPE_NET_ADDR_V4: 315*7c478bd9Sstevel@tonic-gate case SCF_TYPE_NET_ADDR_V6: 316*7c478bd9Sstevel@tonic-gate case SCF_TYPE_URI: 317*7c478bd9Sstevel@tonic-gate case SCF_TYPE_FMRI: { 318*7c478bd9Sstevel@tonic-gate for (i = 0; i < numvals; i++) { 319*7c478bd9Sstevel@tonic-gate free(vallist[i].pv_str); 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate break; 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate case SCF_TYPE_OPAQUE: { 324*7c478bd9Sstevel@tonic-gate for (i = 0; i < numvals; i++) { 325*7c478bd9Sstevel@tonic-gate free(vallist[i].pv_opaque.o_value); 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate break; 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate default: 330*7c478bd9Sstevel@tonic-gate break; 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate free(vallist); 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate error2: 336*7c478bd9Sstevel@tonic-gate scf_iter_destroy(iter); 337*7c478bd9Sstevel@tonic-gate (void) scf_value_destroy(val); 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate error3: 340*7c478bd9Sstevel@tonic-gate free(ret->pr_pgname); 341*7c478bd9Sstevel@tonic-gate free(ret->pr_propname); 342*7c478bd9Sstevel@tonic-gate free(ret); 343*7c478bd9Sstevel@tonic-gate return (NULL); 344*7c478bd9Sstevel@tonic-gate } 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate /* 347*7c478bd9Sstevel@tonic-gate * insert_app_props iterates over a property iterator, getting all the 348*7c478bd9Sstevel@tonic-gate * properties from a property group, and adding or overwriting them into 349*7c478bd9Sstevel@tonic-gate * a simple_app_props_t. This is used by scf_simple_app_props_get to provide 350*7c478bd9Sstevel@tonic-gate * service/instance composition while filling the app_props_t. 351*7c478bd9Sstevel@tonic-gate * insert_app_props iterates over a single property group. 352*7c478bd9Sstevel@tonic-gate */ 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate static int 355*7c478bd9Sstevel@tonic-gate insert_app_props(scf_iter_t *propiter, char *pgname, char *propname, struct 356*7c478bd9Sstevel@tonic-gate scf_simple_pg *thispg, scf_property_t *prop, size_t namelen, 357*7c478bd9Sstevel@tonic-gate scf_handle_t *h) 358*7c478bd9Sstevel@tonic-gate { 359*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *thisprop, *prevprop, *newprop; 360*7c478bd9Sstevel@tonic-gate uint8_t found; 361*7c478bd9Sstevel@tonic-gate int propiter_ret; 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate while ((propiter_ret = scf_iter_next_property(propiter, prop)) == 1) { 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate if (scf_property_get_name(prop, propname, namelen) < 0) { 366*7c478bd9Sstevel@tonic-gate if (scf_error() == SCF_ERROR_NOT_SET) 367*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 368*7c478bd9Sstevel@tonic-gate return (-1); 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate thisprop = thispg->pg_proplist; 372*7c478bd9Sstevel@tonic-gate prevprop = thispg->pg_proplist; 373*7c478bd9Sstevel@tonic-gate found = 0; 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate while ((thisprop != NULL) && (!found)) { 376*7c478bd9Sstevel@tonic-gate if (strcmp(thisprop->pr_propname, propname) == 0) { 377*7c478bd9Sstevel@tonic-gate found = 1; 378*7c478bd9Sstevel@tonic-gate if ((newprop = fill_prop(prop, pgname, 379*7c478bd9Sstevel@tonic-gate propname, h)) == NULL) 380*7c478bd9Sstevel@tonic-gate return (-1); 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate if (thisprop == thispg->pg_proplist) 383*7c478bd9Sstevel@tonic-gate thispg->pg_proplist = newprop; 384*7c478bd9Sstevel@tonic-gate else 385*7c478bd9Sstevel@tonic-gate prevprop->pr_next = newprop; 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate newprop->pr_pg = thispg; 388*7c478bd9Sstevel@tonic-gate newprop->pr_next = thisprop->pr_next; 389*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(thisprop); 390*7c478bd9Sstevel@tonic-gate thisprop = NULL; 391*7c478bd9Sstevel@tonic-gate } else { 392*7c478bd9Sstevel@tonic-gate if (thisprop != thispg->pg_proplist) 393*7c478bd9Sstevel@tonic-gate prevprop = prevprop->pr_next; 394*7c478bd9Sstevel@tonic-gate thisprop = thisprop->pr_next; 395*7c478bd9Sstevel@tonic-gate } 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate if (!found) { 399*7c478bd9Sstevel@tonic-gate if ((newprop = fill_prop(prop, pgname, propname, h)) == 400*7c478bd9Sstevel@tonic-gate NULL) 401*7c478bd9Sstevel@tonic-gate return (-1); 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate if (thispg->pg_proplist == NULL) 404*7c478bd9Sstevel@tonic-gate thispg->pg_proplist = newprop; 405*7c478bd9Sstevel@tonic-gate else 406*7c478bd9Sstevel@tonic-gate prevprop->pr_next = newprop; 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate newprop->pr_pg = thispg; 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate if (propiter_ret == -1) { 413*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 414*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 415*7c478bd9Sstevel@tonic-gate return (-1); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate return (0); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate /* 423*7c478bd9Sstevel@tonic-gate * Sets up e in tx to set pname's values. Returns 0 on success or -1 on 424*7c478bd9Sstevel@tonic-gate * failure, with scf_error() set to 425*7c478bd9Sstevel@tonic-gate * SCF_ERROR_HANDLE_MISMATCH - tx & e are derived from different handles 426*7c478bd9Sstevel@tonic-gate * SCF_ERROR_INVALID_ARGUMENT - pname or ty are invalid 427*7c478bd9Sstevel@tonic-gate * SCF_ERROR_NOT_BOUND - handle is not bound 428*7c478bd9Sstevel@tonic-gate * SCF_ERROR_CONNECTION_BROKEN - connection was broken 429*7c478bd9Sstevel@tonic-gate * SCF_ERROR_NOT_SET - tx has not been started 430*7c478bd9Sstevel@tonic-gate * SCF_ERROR_DELETED - the pg tx was started on was deleted 431*7c478bd9Sstevel@tonic-gate */ 432*7c478bd9Sstevel@tonic-gate static int 433*7c478bd9Sstevel@tonic-gate transaction_property_set(scf_transaction_t *tx, scf_transaction_entry_t *e, 434*7c478bd9Sstevel@tonic-gate const char *pname, scf_type_t ty) 435*7c478bd9Sstevel@tonic-gate { 436*7c478bd9Sstevel@tonic-gate for (;;) { 437*7c478bd9Sstevel@tonic-gate if (scf_transaction_property_change_type(tx, e, pname, ty) == 0) 438*7c478bd9Sstevel@tonic-gate return (0); 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 441*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 442*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 443*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 444*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 445*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 446*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 447*7c478bd9Sstevel@tonic-gate default: 448*7c478bd9Sstevel@tonic-gate return (-1); 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 451*7c478bd9Sstevel@tonic-gate break; 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate 454*7c478bd9Sstevel@tonic-gate if (scf_transaction_property_new(tx, e, pname, ty) == 0) 455*7c478bd9Sstevel@tonic-gate return (0); 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 458*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 459*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 460*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 461*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 462*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 463*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 464*7c478bd9Sstevel@tonic-gate default: 465*7c478bd9Sstevel@tonic-gate return (-1); 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate case SCF_ERROR_EXISTS: 468*7c478bd9Sstevel@tonic-gate break; 469*7c478bd9Sstevel@tonic-gate } 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate static int 474*7c478bd9Sstevel@tonic-gate get_inst_enabled(const scf_instance_t *inst, const char *pgname) 475*7c478bd9Sstevel@tonic-gate { 476*7c478bd9Sstevel@tonic-gate scf_propertygroup_t *gpg = NULL; 477*7c478bd9Sstevel@tonic-gate scf_property_t *eprop = NULL; 478*7c478bd9Sstevel@tonic-gate scf_value_t *v = NULL; 479*7c478bd9Sstevel@tonic-gate scf_handle_t *h = NULL; 480*7c478bd9Sstevel@tonic-gate uint8_t enabled; 481*7c478bd9Sstevel@tonic-gate int ret = -1; 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate if ((h = scf_instance_handle(inst)) == NULL) 484*7c478bd9Sstevel@tonic-gate return (-1); 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate if ((gpg = scf_pg_create(h)) == NULL || 487*7c478bd9Sstevel@tonic-gate (eprop = scf_property_create(h)) == NULL || 488*7c478bd9Sstevel@tonic-gate (v = scf_value_create(h)) == NULL) 489*7c478bd9Sstevel@tonic-gate goto out; 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate if (scf_instance_get_pg(inst, pgname, gpg) || 492*7c478bd9Sstevel@tonic-gate scf_pg_get_property(gpg, SCF_PROPERTY_ENABLED, eprop) || 493*7c478bd9Sstevel@tonic-gate scf_property_get_value(eprop, v) || 494*7c478bd9Sstevel@tonic-gate scf_value_get_boolean(v, &enabled)) 495*7c478bd9Sstevel@tonic-gate goto out; 496*7c478bd9Sstevel@tonic-gate ret = enabled; 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate out: 499*7c478bd9Sstevel@tonic-gate scf_pg_destroy(gpg); 500*7c478bd9Sstevel@tonic-gate scf_property_destroy(eprop); 501*7c478bd9Sstevel@tonic-gate scf_value_destroy(v); 502*7c478bd9Sstevel@tonic-gate return (ret); 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate /* 506*7c478bd9Sstevel@tonic-gate * set_inst_enabled() is a "master" enable/disable call that takes the 507*7c478bd9Sstevel@tonic-gate * instance and the desired state for the enabled bit in the instance's 508*7c478bd9Sstevel@tonic-gate * named property group. If the group doesn't exist, it's created with the 509*7c478bd9Sstevel@tonic-gate * given flags. Called by smf_{dis,en}able_instance(). 510*7c478bd9Sstevel@tonic-gate */ 511*7c478bd9Sstevel@tonic-gate static int 512*7c478bd9Sstevel@tonic-gate set_inst_enabled(const scf_instance_t *inst, uint8_t desired, 513*7c478bd9Sstevel@tonic-gate const char *pgname, uint32_t pgflags) 514*7c478bd9Sstevel@tonic-gate { 515*7c478bd9Sstevel@tonic-gate scf_transaction_t *tx = NULL; 516*7c478bd9Sstevel@tonic-gate scf_transaction_entry_t *ent = NULL; 517*7c478bd9Sstevel@tonic-gate scf_propertygroup_t *gpg = NULL; 518*7c478bd9Sstevel@tonic-gate scf_property_t *eprop = NULL; 519*7c478bd9Sstevel@tonic-gate scf_value_t *v = NULL; 520*7c478bd9Sstevel@tonic-gate scf_handle_t *h = NULL; 521*7c478bd9Sstevel@tonic-gate int ret = -1; 522*7c478bd9Sstevel@tonic-gate int committed; 523*7c478bd9Sstevel@tonic-gate uint8_t b; 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate if ((h = scf_instance_handle(inst)) == NULL) 526*7c478bd9Sstevel@tonic-gate return (-1); 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate if ((gpg = scf_pg_create(h)) == NULL || 529*7c478bd9Sstevel@tonic-gate (eprop = scf_property_create(h)) == NULL || 530*7c478bd9Sstevel@tonic-gate (v = scf_value_create(h)) == NULL || 531*7c478bd9Sstevel@tonic-gate (tx = scf_transaction_create(h)) == NULL || 532*7c478bd9Sstevel@tonic-gate (ent = scf_entry_create(h)) == NULL) 533*7c478bd9Sstevel@tonic-gate goto out; 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate get: 536*7c478bd9Sstevel@tonic-gate if (scf_instance_get_pg(inst, pgname, gpg) == -1) { 537*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 538*7c478bd9Sstevel@tonic-gate goto out; 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate if (scf_instance_add_pg(inst, pgname, SCF_GROUP_FRAMEWORK, 541*7c478bd9Sstevel@tonic-gate pgflags, gpg) == -1) { 542*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_EXISTS) 543*7c478bd9Sstevel@tonic-gate goto out; 544*7c478bd9Sstevel@tonic-gate goto get; 545*7c478bd9Sstevel@tonic-gate } 546*7c478bd9Sstevel@tonic-gate } 547*7c478bd9Sstevel@tonic-gate if (scf_pg_get_property(gpg, SCF_PROPERTY_ENABLED, eprop) == -1) { 548*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 549*7c478bd9Sstevel@tonic-gate goto out; 550*7c478bd9Sstevel@tonic-gate else 551*7c478bd9Sstevel@tonic-gate goto set; 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate /* 555*7c478bd9Sstevel@tonic-gate * If it's already set the way we want, forgo the transaction. 556*7c478bd9Sstevel@tonic-gate */ 557*7c478bd9Sstevel@tonic-gate if (scf_property_get_value(eprop, v) == -1) { 558*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 559*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONSTRAINT_VIOLATED: 560*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 561*7c478bd9Sstevel@tonic-gate /* Misconfigured, so set anyway. */ 562*7c478bd9Sstevel@tonic-gate goto set; 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate default: 565*7c478bd9Sstevel@tonic-gate goto out; 566*7c478bd9Sstevel@tonic-gate } 567*7c478bd9Sstevel@tonic-gate } 568*7c478bd9Sstevel@tonic-gate if (scf_value_get_boolean(v, &b) == -1) { 569*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_TYPE_MISMATCH) 570*7c478bd9Sstevel@tonic-gate goto out; 571*7c478bd9Sstevel@tonic-gate goto set; 572*7c478bd9Sstevel@tonic-gate } 573*7c478bd9Sstevel@tonic-gate if (b == desired) { 574*7c478bd9Sstevel@tonic-gate ret = 0; 575*7c478bd9Sstevel@tonic-gate goto out; 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate 578*7c478bd9Sstevel@tonic-gate set: 579*7c478bd9Sstevel@tonic-gate do { 580*7c478bd9Sstevel@tonic-gate if (scf_transaction_start(tx, gpg) == -1) 581*7c478bd9Sstevel@tonic-gate goto out; 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate if (transaction_property_set(tx, ent, SCF_PROPERTY_ENABLED, 584*7c478bd9Sstevel@tonic-gate SCF_TYPE_BOOLEAN) != 0) { 585*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 586*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 587*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 588*7c478bd9Sstevel@tonic-gate default: 589*7c478bd9Sstevel@tonic-gate goto out; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 592*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 593*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 594*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 595*7c478bd9Sstevel@tonic-gate bad_error("transaction_property_set", 596*7c478bd9Sstevel@tonic-gate scf_error()); 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate scf_value_set_boolean(v, desired); 601*7c478bd9Sstevel@tonic-gate if (scf_entry_add_value(ent, v) == -1) 602*7c478bd9Sstevel@tonic-gate goto out; 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate committed = scf_transaction_commit(tx); 605*7c478bd9Sstevel@tonic-gate if (committed == -1) 606*7c478bd9Sstevel@tonic-gate goto out; 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate scf_transaction_reset(tx); 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate if (committed == 0) { /* out-of-sync */ 611*7c478bd9Sstevel@tonic-gate if (scf_pg_update(gpg) == -1) 612*7c478bd9Sstevel@tonic-gate goto out; 613*7c478bd9Sstevel@tonic-gate } 614*7c478bd9Sstevel@tonic-gate } while (committed == 0); 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate ret = 0; 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate out: 619*7c478bd9Sstevel@tonic-gate scf_value_destroy(v); 620*7c478bd9Sstevel@tonic-gate scf_entry_destroy(ent); 621*7c478bd9Sstevel@tonic-gate scf_transaction_destroy(tx); 622*7c478bd9Sstevel@tonic-gate scf_property_destroy(eprop); 623*7c478bd9Sstevel@tonic-gate scf_pg_destroy(gpg); 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate return (ret); 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate static int 629*7c478bd9Sstevel@tonic-gate delete_inst_enabled(const scf_instance_t *inst, const char *pgname) 630*7c478bd9Sstevel@tonic-gate { 631*7c478bd9Sstevel@tonic-gate scf_transaction_t *tx = NULL; 632*7c478bd9Sstevel@tonic-gate scf_transaction_entry_t *ent = NULL; 633*7c478bd9Sstevel@tonic-gate scf_propertygroup_t *gpg = NULL; 634*7c478bd9Sstevel@tonic-gate scf_handle_t *h = NULL; 635*7c478bd9Sstevel@tonic-gate int ret = -1; 636*7c478bd9Sstevel@tonic-gate int committed; 637*7c478bd9Sstevel@tonic-gate 638*7c478bd9Sstevel@tonic-gate if ((h = scf_instance_handle(inst)) == NULL) 639*7c478bd9Sstevel@tonic-gate return (-1); 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate if ((gpg = scf_pg_create(h)) == NULL || 642*7c478bd9Sstevel@tonic-gate (tx = scf_transaction_create(h)) == NULL || 643*7c478bd9Sstevel@tonic-gate (ent = scf_entry_create(h)) == NULL) 644*7c478bd9Sstevel@tonic-gate goto out; 645*7c478bd9Sstevel@tonic-gate 646*7c478bd9Sstevel@tonic-gate if (scf_instance_get_pg(inst, pgname, gpg) != 0) 647*7c478bd9Sstevel@tonic-gate goto error; 648*7c478bd9Sstevel@tonic-gate do { 649*7c478bd9Sstevel@tonic-gate if (scf_transaction_start(tx, gpg) == -1 || 650*7c478bd9Sstevel@tonic-gate scf_transaction_property_delete(tx, ent, 651*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_ENABLED) == -1 || 652*7c478bd9Sstevel@tonic-gate (committed = scf_transaction_commit(tx)) == -1) 653*7c478bd9Sstevel@tonic-gate goto error; 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate scf_transaction_reset(tx); 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate if (committed == 0 && scf_pg_update(gpg) == -1) 658*7c478bd9Sstevel@tonic-gate goto error; 659*7c478bd9Sstevel@tonic-gate } while (committed == 0); 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate ret = 0; 662*7c478bd9Sstevel@tonic-gate goto out; 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate error: 665*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 666*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 667*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 668*7c478bd9Sstevel@tonic-gate /* success */ 669*7c478bd9Sstevel@tonic-gate ret = 0; 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate out: 673*7c478bd9Sstevel@tonic-gate scf_entry_destroy(ent); 674*7c478bd9Sstevel@tonic-gate scf_transaction_destroy(tx); 675*7c478bd9Sstevel@tonic-gate scf_pg_destroy(gpg); 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate return (ret); 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate /* 681*7c478bd9Sstevel@tonic-gate * Returns 0 on success or -1 on failure. On failure leaves scf_error() set to 682*7c478bd9Sstevel@tonic-gate * SCF_ERROR_HANDLE_DESTROYED - inst's handle has been destroyed 683*7c478bd9Sstevel@tonic-gate * SCF_ERROR_NOT_BOUND - inst's handle is not bound 684*7c478bd9Sstevel@tonic-gate * SCF_ERROR_CONNECTION_BROKEN - the repository connection was broken 685*7c478bd9Sstevel@tonic-gate * SCF_ERROR_NOT_SET - inst is not set 686*7c478bd9Sstevel@tonic-gate * SCF_ERROR_DELETED - inst was deleted 687*7c478bd9Sstevel@tonic-gate * SCF_ERROR_PERMISSION_DENIED 688*7c478bd9Sstevel@tonic-gate * SCF_ERROR_BACKEND_ACCESS 689*7c478bd9Sstevel@tonic-gate * SCF_ERROR_BACKEND_READONLY 690*7c478bd9Sstevel@tonic-gate */ 691*7c478bd9Sstevel@tonic-gate static int 692*7c478bd9Sstevel@tonic-gate set_inst_action_inst(scf_instance_t *inst, const char *action) 693*7c478bd9Sstevel@tonic-gate { 694*7c478bd9Sstevel@tonic-gate scf_handle_t *h; 695*7c478bd9Sstevel@tonic-gate scf_transaction_t *tx = NULL; 696*7c478bd9Sstevel@tonic-gate scf_transaction_entry_t *ent = NULL; 697*7c478bd9Sstevel@tonic-gate scf_propertygroup_t *pg = NULL; 698*7c478bd9Sstevel@tonic-gate scf_property_t *prop = NULL; 699*7c478bd9Sstevel@tonic-gate scf_value_t *v = NULL; 700*7c478bd9Sstevel@tonic-gate int trans, ret = -1; 701*7c478bd9Sstevel@tonic-gate int64_t t; 702*7c478bd9Sstevel@tonic-gate hrtime_t timestamp; 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate if ((h = scf_instance_handle(inst)) == NULL || 705*7c478bd9Sstevel@tonic-gate (pg = scf_pg_create(h)) == NULL || 706*7c478bd9Sstevel@tonic-gate (prop = scf_property_create(h)) == NULL || 707*7c478bd9Sstevel@tonic-gate (v = scf_value_create(h)) == NULL || 708*7c478bd9Sstevel@tonic-gate (tx = scf_transaction_create(h)) == NULL || 709*7c478bd9Sstevel@tonic-gate (ent = scf_entry_create(h)) == NULL) 710*7c478bd9Sstevel@tonic-gate goto out; 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate get: 713*7c478bd9Sstevel@tonic-gate if (scf_instance_get_pg(inst, SCF_PG_RESTARTER_ACTIONS, pg) == -1) { 714*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 715*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 716*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 717*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 718*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 719*7c478bd9Sstevel@tonic-gate default: 720*7c478bd9Sstevel@tonic-gate goto out; 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 723*7c478bd9Sstevel@tonic-gate break; 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 726*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 727*7c478bd9Sstevel@tonic-gate bad_error("scf_instance_get_pg", scf_error()); 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate /* Try creating the restarter_actions property group. */ 731*7c478bd9Sstevel@tonic-gate add: 732*7c478bd9Sstevel@tonic-gate if (scf_instance_add_pg(inst, SCF_PG_RESTARTER_ACTIONS, 733*7c478bd9Sstevel@tonic-gate SCF_PG_RESTARTER_ACTIONS_TYPE, 734*7c478bd9Sstevel@tonic-gate SCF_PG_RESTARTER_ACTIONS_FLAGS, pg) == -1) { 735*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 736*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 737*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 738*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 739*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 740*7c478bd9Sstevel@tonic-gate case SCF_ERROR_PERMISSION_DENIED: 741*7c478bd9Sstevel@tonic-gate case SCF_ERROR_BACKEND_ACCESS: 742*7c478bd9Sstevel@tonic-gate case SCF_ERROR_BACKEND_READONLY: 743*7c478bd9Sstevel@tonic-gate default: 744*7c478bd9Sstevel@tonic-gate goto out; 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate case SCF_ERROR_EXISTS: 747*7c478bd9Sstevel@tonic-gate goto get; 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 750*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 751*7c478bd9Sstevel@tonic-gate bad_error("scf_instance_add_pg", scf_error()); 752*7c478bd9Sstevel@tonic-gate } 753*7c478bd9Sstevel@tonic-gate } 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate 756*7c478bd9Sstevel@tonic-gate for (;;) { 757*7c478bd9Sstevel@tonic-gate timestamp = gethrtime(); 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate if (scf_pg_get_property(pg, action, prop) != 0) { 760*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 761*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 762*7c478bd9Sstevel@tonic-gate default: 763*7c478bd9Sstevel@tonic-gate goto out; 764*7c478bd9Sstevel@tonic-gate 765*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 766*7c478bd9Sstevel@tonic-gate goto add; 767*7c478bd9Sstevel@tonic-gate 768*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 769*7c478bd9Sstevel@tonic-gate break; 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 772*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 773*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 774*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 775*7c478bd9Sstevel@tonic-gate bad_error("scf_pg_get_property", scf_error()); 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate } else if (scf_property_get_value(prop, v) != 0) { 778*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 779*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 780*7c478bd9Sstevel@tonic-gate default: 781*7c478bd9Sstevel@tonic-gate goto out; 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 784*7c478bd9Sstevel@tonic-gate goto add; 785*7c478bd9Sstevel@tonic-gate 786*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONSTRAINT_VIOLATED: 787*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 788*7c478bd9Sstevel@tonic-gate break; 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 791*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 792*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 793*7c478bd9Sstevel@tonic-gate bad_error("scf_property_get_value", 794*7c478bd9Sstevel@tonic-gate scf_error()); 795*7c478bd9Sstevel@tonic-gate } 796*7c478bd9Sstevel@tonic-gate } else if (scf_value_get_integer(v, &t) != 0) { 797*7c478bd9Sstevel@tonic-gate bad_error("scf_value_get_integer", scf_error()); 798*7c478bd9Sstevel@tonic-gate } else if (t > timestamp) { 799*7c478bd9Sstevel@tonic-gate break; 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate if (scf_transaction_start(tx, pg) == -1) { 803*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 804*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 805*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 806*7c478bd9Sstevel@tonic-gate case SCF_ERROR_PERMISSION_DENIED: 807*7c478bd9Sstevel@tonic-gate case SCF_ERROR_BACKEND_ACCESS: 808*7c478bd9Sstevel@tonic-gate case SCF_ERROR_BACKEND_READONLY: 809*7c478bd9Sstevel@tonic-gate default: 810*7c478bd9Sstevel@tonic-gate goto out; 811*7c478bd9Sstevel@tonic-gate 812*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 813*7c478bd9Sstevel@tonic-gate goto add; 814*7c478bd9Sstevel@tonic-gate 815*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 816*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 817*7c478bd9Sstevel@tonic-gate case SCF_ERROR_IN_USE: 818*7c478bd9Sstevel@tonic-gate bad_error("scf_transaction_start", scf_error()); 819*7c478bd9Sstevel@tonic-gate } 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate if (transaction_property_set(tx, ent, action, 823*7c478bd9Sstevel@tonic-gate SCF_TYPE_INTEGER) != 0) { 824*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 825*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 826*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 827*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 828*7c478bd9Sstevel@tonic-gate default: 829*7c478bd9Sstevel@tonic-gate goto out; 830*7c478bd9Sstevel@tonic-gate 831*7c478bd9Sstevel@tonic-gate case SCF_ERROR_HANDLE_MISMATCH: 832*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 833*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 834*7c478bd9Sstevel@tonic-gate bad_error("transaction_property_set", 835*7c478bd9Sstevel@tonic-gate scf_error()); 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate } 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate scf_value_set_integer(v, timestamp); 840*7c478bd9Sstevel@tonic-gate if (scf_entry_add_value(ent, v) == -1) 841*7c478bd9Sstevel@tonic-gate bad_error("scf_entry_add_value", scf_error()); 842*7c478bd9Sstevel@tonic-gate 843*7c478bd9Sstevel@tonic-gate trans = scf_transaction_commit(tx); 844*7c478bd9Sstevel@tonic-gate if (trans == 1) 845*7c478bd9Sstevel@tonic-gate break; 846*7c478bd9Sstevel@tonic-gate 847*7c478bd9Sstevel@tonic-gate if (trans != 0) { 848*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 849*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 850*7c478bd9Sstevel@tonic-gate case SCF_ERROR_PERMISSION_DENIED: 851*7c478bd9Sstevel@tonic-gate case SCF_ERROR_BACKEND_ACCESS: 852*7c478bd9Sstevel@tonic-gate case SCF_ERROR_BACKEND_READONLY: 853*7c478bd9Sstevel@tonic-gate default: 854*7c478bd9Sstevel@tonic-gate goto out; 855*7c478bd9Sstevel@tonic-gate 856*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 857*7c478bd9Sstevel@tonic-gate scf_transaction_reset(tx); 858*7c478bd9Sstevel@tonic-gate goto add; 859*7c478bd9Sstevel@tonic-gate 860*7c478bd9Sstevel@tonic-gate case SCF_ERROR_INVALID_ARGUMENT: 861*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 862*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 863*7c478bd9Sstevel@tonic-gate bad_error("scf_transaction_commit", 864*7c478bd9Sstevel@tonic-gate scf_error()); 865*7c478bd9Sstevel@tonic-gate } 866*7c478bd9Sstevel@tonic-gate } 867*7c478bd9Sstevel@tonic-gate 868*7c478bd9Sstevel@tonic-gate scf_transaction_reset(tx); 869*7c478bd9Sstevel@tonic-gate if (scf_pg_update(pg) != 0) { 870*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 871*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONNECTION_BROKEN: 872*7c478bd9Sstevel@tonic-gate default: 873*7c478bd9Sstevel@tonic-gate goto out; 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate case SCF_ERROR_DELETED: 876*7c478bd9Sstevel@tonic-gate goto add; 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_SET: 879*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_BOUND: 880*7c478bd9Sstevel@tonic-gate bad_error("scf_pg_update", scf_error()); 881*7c478bd9Sstevel@tonic-gate } 882*7c478bd9Sstevel@tonic-gate } 883*7c478bd9Sstevel@tonic-gate } 884*7c478bd9Sstevel@tonic-gate 885*7c478bd9Sstevel@tonic-gate ret = 0; 886*7c478bd9Sstevel@tonic-gate 887*7c478bd9Sstevel@tonic-gate out: 888*7c478bd9Sstevel@tonic-gate scf_value_destroy(v); 889*7c478bd9Sstevel@tonic-gate scf_entry_destroy(ent); 890*7c478bd9Sstevel@tonic-gate scf_transaction_destroy(tx); 891*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 892*7c478bd9Sstevel@tonic-gate scf_pg_destroy(pg); 893*7c478bd9Sstevel@tonic-gate return (ret); 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate 896*7c478bd9Sstevel@tonic-gate static int 897*7c478bd9Sstevel@tonic-gate set_inst_action(const char *fmri, const char *action) 898*7c478bd9Sstevel@tonic-gate { 899*7c478bd9Sstevel@tonic-gate scf_handle_t *h; 900*7c478bd9Sstevel@tonic-gate scf_instance_t *inst; 901*7c478bd9Sstevel@tonic-gate int ret = -1; 902*7c478bd9Sstevel@tonic-gate 903*7c478bd9Sstevel@tonic-gate h = handle_create(); 904*7c478bd9Sstevel@tonic-gate if (h == NULL) 905*7c478bd9Sstevel@tonic-gate return (-1); 906*7c478bd9Sstevel@tonic-gate 907*7c478bd9Sstevel@tonic-gate inst = scf_instance_create(h); 908*7c478bd9Sstevel@tonic-gate 909*7c478bd9Sstevel@tonic-gate if (inst != NULL) { 910*7c478bd9Sstevel@tonic-gate if (scf_handle_decode_fmri(h, fmri, NULL, NULL, inst, NULL, 911*7c478bd9Sstevel@tonic-gate NULL, SCF_DECODE_FMRI_EXACT) == 0) 912*7c478bd9Sstevel@tonic-gate ret = set_inst_action_inst(inst, action); 913*7c478bd9Sstevel@tonic-gate else if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) 914*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 915*7c478bd9Sstevel@tonic-gate 916*7c478bd9Sstevel@tonic-gate scf_instance_destroy(inst); 917*7c478bd9Sstevel@tonic-gate } 918*7c478bd9Sstevel@tonic-gate 919*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate return (ret); 922*7c478bd9Sstevel@tonic-gate } 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate 925*7c478bd9Sstevel@tonic-gate /* 926*7c478bd9Sstevel@tonic-gate * get_inst_state() gets the state string from an instance, and returns 927*7c478bd9Sstevel@tonic-gate * the SCF_STATE_* constant that coincides with the instance's current state. 928*7c478bd9Sstevel@tonic-gate */ 929*7c478bd9Sstevel@tonic-gate 930*7c478bd9Sstevel@tonic-gate static int 931*7c478bd9Sstevel@tonic-gate get_inst_state(scf_instance_t *inst, scf_handle_t *h) 932*7c478bd9Sstevel@tonic-gate { 933*7c478bd9Sstevel@tonic-gate scf_propertygroup_t *pg = NULL; 934*7c478bd9Sstevel@tonic-gate scf_property_t *prop = NULL; 935*7c478bd9Sstevel@tonic-gate scf_value_t *val = NULL; 936*7c478bd9Sstevel@tonic-gate char state[MAX_SCF_STATE_STRING_SZ]; 937*7c478bd9Sstevel@tonic-gate int ret = -1; 938*7c478bd9Sstevel@tonic-gate 939*7c478bd9Sstevel@tonic-gate if (((pg = scf_pg_create(h)) == NULL) || 940*7c478bd9Sstevel@tonic-gate ((prop = scf_property_create(h)) == NULL) || 941*7c478bd9Sstevel@tonic-gate ((val = scf_value_create(h)) == NULL)) 942*7c478bd9Sstevel@tonic-gate goto out; 943*7c478bd9Sstevel@tonic-gate 944*7c478bd9Sstevel@tonic-gate /* Pull the state property from the instance */ 945*7c478bd9Sstevel@tonic-gate 946*7c478bd9Sstevel@tonic-gate if (scf_instance_get_pg(inst, SCF_PG_RESTARTER, pg) == -1 || 947*7c478bd9Sstevel@tonic-gate scf_pg_get_property(pg, SCF_PROPERTY_STATE, prop) == -1 || 948*7c478bd9Sstevel@tonic-gate scf_property_get_value(prop, val) == -1) { 949*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 950*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 951*7c478bd9Sstevel@tonic-gate goto out; 952*7c478bd9Sstevel@tonic-gate } 953*7c478bd9Sstevel@tonic-gate 954*7c478bd9Sstevel@tonic-gate if (scf_value_get_astring(val, state, sizeof (state)) <= 0) { 955*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 956*7c478bd9Sstevel@tonic-gate goto out; 957*7c478bd9Sstevel@tonic-gate } 958*7c478bd9Sstevel@tonic-gate 959*7c478bd9Sstevel@tonic-gate if (strcmp(state, SCF_STATE_STRING_UNINIT) == 0) { 960*7c478bd9Sstevel@tonic-gate ret = SCF_STATE_UNINIT; 961*7c478bd9Sstevel@tonic-gate } else if (strcmp(state, SCF_STATE_STRING_MAINT) == 0) { 962*7c478bd9Sstevel@tonic-gate ret = SCF_STATE_MAINT; 963*7c478bd9Sstevel@tonic-gate } else if (strcmp(state, SCF_STATE_STRING_OFFLINE) == 0) { 964*7c478bd9Sstevel@tonic-gate ret = SCF_STATE_OFFLINE; 965*7c478bd9Sstevel@tonic-gate } else if (strcmp(state, SCF_STATE_STRING_DISABLED) == 0) { 966*7c478bd9Sstevel@tonic-gate ret = SCF_STATE_DISABLED; 967*7c478bd9Sstevel@tonic-gate } else if (strcmp(state, SCF_STATE_STRING_ONLINE) == 0) { 968*7c478bd9Sstevel@tonic-gate ret = SCF_STATE_ONLINE; 969*7c478bd9Sstevel@tonic-gate } else if (strcmp(state, SCF_STATE_STRING_DEGRADED) == 0) { 970*7c478bd9Sstevel@tonic-gate ret = SCF_STATE_DEGRADED; 971*7c478bd9Sstevel@tonic-gate } 972*7c478bd9Sstevel@tonic-gate 973*7c478bd9Sstevel@tonic-gate out: 974*7c478bd9Sstevel@tonic-gate scf_pg_destroy(pg); 975*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 976*7c478bd9Sstevel@tonic-gate (void) scf_value_destroy(val); 977*7c478bd9Sstevel@tonic-gate 978*7c478bd9Sstevel@tonic-gate return (ret); 979*7c478bd9Sstevel@tonic-gate } 980*7c478bd9Sstevel@tonic-gate 981*7c478bd9Sstevel@tonic-gate /* 982*7c478bd9Sstevel@tonic-gate * Sets an instance to be enabled or disabled after reboot, using the 983*7c478bd9Sstevel@tonic-gate * temporary (overriding) general_ovr property group to reflect the 984*7c478bd9Sstevel@tonic-gate * present state, if it is different. 985*7c478bd9Sstevel@tonic-gate */ 986*7c478bd9Sstevel@tonic-gate static int 987*7c478bd9Sstevel@tonic-gate set_inst_enabled_atboot(scf_instance_t *inst, uint8_t desired) 988*7c478bd9Sstevel@tonic-gate { 989*7c478bd9Sstevel@tonic-gate int enabled; 990*7c478bd9Sstevel@tonic-gate int persistent; 991*7c478bd9Sstevel@tonic-gate int ret = -1; 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate if ((persistent = get_inst_enabled(inst, SCF_PG_GENERAL)) < 0) { 994*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_NOT_FOUND) 995*7c478bd9Sstevel@tonic-gate goto out; 996*7c478bd9Sstevel@tonic-gate persistent = B_FALSE; 997*7c478bd9Sstevel@tonic-gate } 998*7c478bd9Sstevel@tonic-gate if ((enabled = get_inst_enabled(inst, SCF_PG_GENERAL_OVR)) < 0) { 999*7c478bd9Sstevel@tonic-gate enabled = persistent; 1000*7c478bd9Sstevel@tonic-gate if (persistent != desired) { 1001*7c478bd9Sstevel@tonic-gate /* 1002*7c478bd9Sstevel@tonic-gate * Temporarily store the present enabled state. 1003*7c478bd9Sstevel@tonic-gate */ 1004*7c478bd9Sstevel@tonic-gate if (set_inst_enabled(inst, persistent, 1005*7c478bd9Sstevel@tonic-gate SCF_PG_GENERAL_OVR, SCF_PG_GENERAL_OVR_FLAGS)) 1006*7c478bd9Sstevel@tonic-gate goto out; 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate } 1009*7c478bd9Sstevel@tonic-gate if (persistent != desired) 1010*7c478bd9Sstevel@tonic-gate if (set_inst_enabled(inst, desired, SCF_PG_GENERAL, 1011*7c478bd9Sstevel@tonic-gate SCF_PG_GENERAL_FLAGS)) 1012*7c478bd9Sstevel@tonic-gate goto out; 1013*7c478bd9Sstevel@tonic-gate if (enabled == desired) 1014*7c478bd9Sstevel@tonic-gate ret = delete_inst_enabled(inst, SCF_PG_GENERAL_OVR); 1015*7c478bd9Sstevel@tonic-gate else 1016*7c478bd9Sstevel@tonic-gate ret = 0; 1017*7c478bd9Sstevel@tonic-gate 1018*7c478bd9Sstevel@tonic-gate out: 1019*7c478bd9Sstevel@tonic-gate return (ret); 1020*7c478bd9Sstevel@tonic-gate } 1021*7c478bd9Sstevel@tonic-gate 1022*7c478bd9Sstevel@tonic-gate static int 1023*7c478bd9Sstevel@tonic-gate set_inst_enabled_flags(const char *fmri, int flags, uint8_t desired) 1024*7c478bd9Sstevel@tonic-gate { 1025*7c478bd9Sstevel@tonic-gate int ret = -1; 1026*7c478bd9Sstevel@tonic-gate scf_handle_t *h; 1027*7c478bd9Sstevel@tonic-gate scf_instance_t *inst; 1028*7c478bd9Sstevel@tonic-gate 1029*7c478bd9Sstevel@tonic-gate if (flags & ~(SMF_TEMPORARY | SMF_AT_NEXT_BOOT) || 1030*7c478bd9Sstevel@tonic-gate flags & SMF_TEMPORARY && flags & SMF_AT_NEXT_BOOT) { 1031*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 1032*7c478bd9Sstevel@tonic-gate return (ret); 1033*7c478bd9Sstevel@tonic-gate } 1034*7c478bd9Sstevel@tonic-gate 1035*7c478bd9Sstevel@tonic-gate if ((h = handle_create()) == NULL) 1036*7c478bd9Sstevel@tonic-gate return (ret); 1037*7c478bd9Sstevel@tonic-gate 1038*7c478bd9Sstevel@tonic-gate if ((inst = scf_instance_create(h)) == NULL) { 1039*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1040*7c478bd9Sstevel@tonic-gate return (ret); 1041*7c478bd9Sstevel@tonic-gate } 1042*7c478bd9Sstevel@tonic-gate 1043*7c478bd9Sstevel@tonic-gate if (scf_handle_decode_fmri(h, fmri, NULL, NULL, inst, NULL, NULL, 1044*7c478bd9Sstevel@tonic-gate SCF_DECODE_FMRI_EXACT) == -1) { 1045*7c478bd9Sstevel@tonic-gate if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) 1046*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 1047*7c478bd9Sstevel@tonic-gate goto out; 1048*7c478bd9Sstevel@tonic-gate } 1049*7c478bd9Sstevel@tonic-gate 1050*7c478bd9Sstevel@tonic-gate if (flags & SMF_AT_NEXT_BOOT) { 1051*7c478bd9Sstevel@tonic-gate ret = set_inst_enabled_atboot(inst, desired); 1052*7c478bd9Sstevel@tonic-gate } else { 1053*7c478bd9Sstevel@tonic-gate if (set_inst_enabled(inst, desired, flags & SMF_TEMPORARY ? 1054*7c478bd9Sstevel@tonic-gate SCF_PG_GENERAL_OVR : SCF_PG_GENERAL, flags & SMF_TEMPORARY ? 1055*7c478bd9Sstevel@tonic-gate SCF_PG_GENERAL_OVR_FLAGS : SCF_PG_GENERAL_FLAGS)) 1056*7c478bd9Sstevel@tonic-gate goto out; 1057*7c478bd9Sstevel@tonic-gate 1058*7c478bd9Sstevel@tonic-gate /* 1059*7c478bd9Sstevel@tonic-gate * Make the persistent value effective by deleting the 1060*7c478bd9Sstevel@tonic-gate * temporary one. 1061*7c478bd9Sstevel@tonic-gate */ 1062*7c478bd9Sstevel@tonic-gate if (flags & SMF_TEMPORARY) 1063*7c478bd9Sstevel@tonic-gate ret = 0; 1064*7c478bd9Sstevel@tonic-gate else 1065*7c478bd9Sstevel@tonic-gate ret = delete_inst_enabled(inst, SCF_PG_GENERAL_OVR); 1066*7c478bd9Sstevel@tonic-gate } 1067*7c478bd9Sstevel@tonic-gate 1068*7c478bd9Sstevel@tonic-gate out: 1069*7c478bd9Sstevel@tonic-gate scf_instance_destroy(inst); 1070*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1071*7c478bd9Sstevel@tonic-gate return (ret); 1072*7c478bd9Sstevel@tonic-gate } 1073*7c478bd9Sstevel@tonic-gate 1074*7c478bd9Sstevel@tonic-gate int 1075*7c478bd9Sstevel@tonic-gate smf_enable_instance(const char *fmri, int flags) 1076*7c478bd9Sstevel@tonic-gate { 1077*7c478bd9Sstevel@tonic-gate return (set_inst_enabled_flags(fmri, flags, B_TRUE)); 1078*7c478bd9Sstevel@tonic-gate } 1079*7c478bd9Sstevel@tonic-gate 1080*7c478bd9Sstevel@tonic-gate int 1081*7c478bd9Sstevel@tonic-gate smf_disable_instance(const char *fmri, int flags) 1082*7c478bd9Sstevel@tonic-gate { 1083*7c478bd9Sstevel@tonic-gate return (set_inst_enabled_flags(fmri, flags, B_FALSE)); 1084*7c478bd9Sstevel@tonic-gate } 1085*7c478bd9Sstevel@tonic-gate 1086*7c478bd9Sstevel@tonic-gate int 1087*7c478bd9Sstevel@tonic-gate _smf_refresh_instance_i(scf_instance_t *inst) 1088*7c478bd9Sstevel@tonic-gate { 1089*7c478bd9Sstevel@tonic-gate return (set_inst_action_inst(inst, SCF_PROPERTY_REFRESH)); 1090*7c478bd9Sstevel@tonic-gate } 1091*7c478bd9Sstevel@tonic-gate 1092*7c478bd9Sstevel@tonic-gate int 1093*7c478bd9Sstevel@tonic-gate smf_refresh_instance(const char *instance) 1094*7c478bd9Sstevel@tonic-gate { 1095*7c478bd9Sstevel@tonic-gate return (set_inst_action(instance, SCF_PROPERTY_REFRESH)); 1096*7c478bd9Sstevel@tonic-gate } 1097*7c478bd9Sstevel@tonic-gate 1098*7c478bd9Sstevel@tonic-gate int 1099*7c478bd9Sstevel@tonic-gate smf_restart_instance(const char *instance) 1100*7c478bd9Sstevel@tonic-gate { 1101*7c478bd9Sstevel@tonic-gate return (set_inst_action(instance, SCF_PROPERTY_RESTART)); 1102*7c478bd9Sstevel@tonic-gate } 1103*7c478bd9Sstevel@tonic-gate 1104*7c478bd9Sstevel@tonic-gate int 1105*7c478bd9Sstevel@tonic-gate smf_maintain_instance(const char *instance, int flags) 1106*7c478bd9Sstevel@tonic-gate { 1107*7c478bd9Sstevel@tonic-gate if (flags & SMF_TEMPORARY) 1108*7c478bd9Sstevel@tonic-gate return (set_inst_action(instance, 1109*7c478bd9Sstevel@tonic-gate (flags & SMF_IMMEDIATE) ? 1110*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_MAINT_ON_IMMTEMP : 1111*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_MAINT_ON_TEMPORARY)); 1112*7c478bd9Sstevel@tonic-gate else 1113*7c478bd9Sstevel@tonic-gate return (set_inst_action(instance, 1114*7c478bd9Sstevel@tonic-gate (flags & SMF_IMMEDIATE) ? 1115*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_MAINT_ON_IMMEDIATE : 1116*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_MAINT_ON)); 1117*7c478bd9Sstevel@tonic-gate } 1118*7c478bd9Sstevel@tonic-gate 1119*7c478bd9Sstevel@tonic-gate int 1120*7c478bd9Sstevel@tonic-gate smf_degrade_instance(const char *instance, int flags) 1121*7c478bd9Sstevel@tonic-gate { 1122*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *prop; 1123*7c478bd9Sstevel@tonic-gate const char *state_str; 1124*7c478bd9Sstevel@tonic-gate 1125*7c478bd9Sstevel@tonic-gate if (flags & SMF_TEMPORARY) 1126*7c478bd9Sstevel@tonic-gate return (scf_set_error(SCF_ERROR_INVALID_ARGUMENT)); 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate if ((prop = scf_simple_prop_get(NULL, instance, SCF_PG_RESTARTER, 1129*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_STATE)) == NULL) 1130*7c478bd9Sstevel@tonic-gate return (SCF_FAILED); 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) { 1133*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 1134*7c478bd9Sstevel@tonic-gate return (SCF_FAILED); 1135*7c478bd9Sstevel@tonic-gate } 1136*7c478bd9Sstevel@tonic-gate 1137*7c478bd9Sstevel@tonic-gate if (strcmp(state_str, SCF_STATE_STRING_ONLINE) != 0) { 1138*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 1139*7c478bd9Sstevel@tonic-gate return (scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED)); 1140*7c478bd9Sstevel@tonic-gate } 1141*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 1142*7c478bd9Sstevel@tonic-gate 1143*7c478bd9Sstevel@tonic-gate return (set_inst_action(instance, (flags & SMF_IMMEDIATE) ? 1144*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_DEGRADE_IMMEDIATE : SCF_PROPERTY_DEGRADED)); 1145*7c478bd9Sstevel@tonic-gate } 1146*7c478bd9Sstevel@tonic-gate 1147*7c478bd9Sstevel@tonic-gate int 1148*7c478bd9Sstevel@tonic-gate smf_restore_instance(const char *instance) 1149*7c478bd9Sstevel@tonic-gate { 1150*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *prop; 1151*7c478bd9Sstevel@tonic-gate const char *state_str; 1152*7c478bd9Sstevel@tonic-gate int ret; 1153*7c478bd9Sstevel@tonic-gate 1154*7c478bd9Sstevel@tonic-gate if ((prop = scf_simple_prop_get(NULL, instance, SCF_PG_RESTARTER, 1155*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_STATE)) == NULL) 1156*7c478bd9Sstevel@tonic-gate return (SCF_FAILED); 1157*7c478bd9Sstevel@tonic-gate 1158*7c478bd9Sstevel@tonic-gate if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) { 1159*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 1160*7c478bd9Sstevel@tonic-gate return (SCF_FAILED); 1161*7c478bd9Sstevel@tonic-gate } 1162*7c478bd9Sstevel@tonic-gate 1163*7c478bd9Sstevel@tonic-gate if (strcmp(state_str, SCF_STATE_STRING_MAINT) == 0) { 1164*7c478bd9Sstevel@tonic-gate ret = set_inst_action(instance, SCF_PROPERTY_MAINT_OFF); 1165*7c478bd9Sstevel@tonic-gate } else if (strcmp(state_str, SCF_STATE_STRING_DEGRADED) == 0) { 1166*7c478bd9Sstevel@tonic-gate ret = set_inst_action(instance, SCF_PROPERTY_RESTORE); 1167*7c478bd9Sstevel@tonic-gate } else { 1168*7c478bd9Sstevel@tonic-gate ret = scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED); 1169*7c478bd9Sstevel@tonic-gate } 1170*7c478bd9Sstevel@tonic-gate 1171*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 1172*7c478bd9Sstevel@tonic-gate return (ret); 1173*7c478bd9Sstevel@tonic-gate } 1174*7c478bd9Sstevel@tonic-gate 1175*7c478bd9Sstevel@tonic-gate char * 1176*7c478bd9Sstevel@tonic-gate smf_get_state(const char *instance) 1177*7c478bd9Sstevel@tonic-gate { 1178*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *prop; 1179*7c478bd9Sstevel@tonic-gate const char *state_str; 1180*7c478bd9Sstevel@tonic-gate char *ret; 1181*7c478bd9Sstevel@tonic-gate 1182*7c478bd9Sstevel@tonic-gate if ((prop = scf_simple_prop_get(NULL, instance, SCF_PG_RESTARTER, 1183*7c478bd9Sstevel@tonic-gate SCF_PROPERTY_STATE)) == NULL) 1184*7c478bd9Sstevel@tonic-gate return (NULL); 1185*7c478bd9Sstevel@tonic-gate 1186*7c478bd9Sstevel@tonic-gate if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) { 1187*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 1188*7c478bd9Sstevel@tonic-gate return (NULL); 1189*7c478bd9Sstevel@tonic-gate } 1190*7c478bd9Sstevel@tonic-gate 1191*7c478bd9Sstevel@tonic-gate if ((ret = strdup(state_str)) == NULL) 1192*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1193*7c478bd9Sstevel@tonic-gate 1194*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(prop); 1195*7c478bd9Sstevel@tonic-gate return (ret); 1196*7c478bd9Sstevel@tonic-gate } 1197*7c478bd9Sstevel@tonic-gate 1198*7c478bd9Sstevel@tonic-gate int 1199*7c478bd9Sstevel@tonic-gate scf_simple_walk_instances(uint_t state_flags, void *private, 1200*7c478bd9Sstevel@tonic-gate int (*inst_callback)(scf_handle_t *, scf_instance_t *, void *)) 1201*7c478bd9Sstevel@tonic-gate { 1202*7c478bd9Sstevel@tonic-gate scf_scope_t *scope = NULL; 1203*7c478bd9Sstevel@tonic-gate scf_service_t *svc = NULL; 1204*7c478bd9Sstevel@tonic-gate scf_instance_t *inst = NULL; 1205*7c478bd9Sstevel@tonic-gate scf_iter_t *svc_iter = NULL, *inst_iter = NULL; 1206*7c478bd9Sstevel@tonic-gate scf_handle_t *h = NULL; 1207*7c478bd9Sstevel@tonic-gate int ret = SCF_FAILED; 1208*7c478bd9Sstevel@tonic-gate int svc_iter_ret, inst_iter_ret; 1209*7c478bd9Sstevel@tonic-gate int inst_state; 1210*7c478bd9Sstevel@tonic-gate 1211*7c478bd9Sstevel@tonic-gate if ((h = handle_create()) == NULL) 1212*7c478bd9Sstevel@tonic-gate return (ret); 1213*7c478bd9Sstevel@tonic-gate 1214*7c478bd9Sstevel@tonic-gate if (((scope = scf_scope_create(h)) == NULL) || 1215*7c478bd9Sstevel@tonic-gate ((svc = scf_service_create(h)) == NULL) || 1216*7c478bd9Sstevel@tonic-gate ((inst = scf_instance_create(h)) == NULL) || 1217*7c478bd9Sstevel@tonic-gate ((svc_iter = scf_iter_create(h)) == NULL) || 1218*7c478bd9Sstevel@tonic-gate ((inst_iter = scf_iter_create(h)) == NULL)) 1219*7c478bd9Sstevel@tonic-gate goto out; 1220*7c478bd9Sstevel@tonic-gate 1221*7c478bd9Sstevel@tonic-gate /* 1222*7c478bd9Sstevel@tonic-gate * Get the local scope, and set up nested iteration through every 1223*7c478bd9Sstevel@tonic-gate * local service, and every instance of every service. 1224*7c478bd9Sstevel@tonic-gate */ 1225*7c478bd9Sstevel@tonic-gate 1226*7c478bd9Sstevel@tonic-gate if ((scf_handle_get_local_scope(h, scope) != SCF_SUCCESS) || 1227*7c478bd9Sstevel@tonic-gate (scf_iter_scope_services(svc_iter, scope) != SCF_SUCCESS)) 1228*7c478bd9Sstevel@tonic-gate goto out; 1229*7c478bd9Sstevel@tonic-gate 1230*7c478bd9Sstevel@tonic-gate while ((svc_iter_ret = scf_iter_next_service(svc_iter, svc)) > 0) { 1231*7c478bd9Sstevel@tonic-gate 1232*7c478bd9Sstevel@tonic-gate if ((scf_iter_service_instances(inst_iter, svc)) != 1233*7c478bd9Sstevel@tonic-gate SCF_SUCCESS) 1234*7c478bd9Sstevel@tonic-gate goto out; 1235*7c478bd9Sstevel@tonic-gate 1236*7c478bd9Sstevel@tonic-gate while ((inst_iter_ret = 1237*7c478bd9Sstevel@tonic-gate scf_iter_next_instance(inst_iter, inst)) > 0) { 1238*7c478bd9Sstevel@tonic-gate /* 1239*7c478bd9Sstevel@tonic-gate * If get_inst_state fails from an internal error, 1240*7c478bd9Sstevel@tonic-gate * IE, being unable to get the property group or 1241*7c478bd9Sstevel@tonic-gate * property containing the state of the instance, 1242*7c478bd9Sstevel@tonic-gate * we continue instead of failing, as this might just 1243*7c478bd9Sstevel@tonic-gate * be an improperly configured instance. 1244*7c478bd9Sstevel@tonic-gate */ 1245*7c478bd9Sstevel@tonic-gate if ((inst_state = get_inst_state(inst, h)) == -1) { 1246*7c478bd9Sstevel@tonic-gate if (scf_error() == SCF_ERROR_INTERNAL) { 1247*7c478bd9Sstevel@tonic-gate continue; 1248*7c478bd9Sstevel@tonic-gate } else { 1249*7c478bd9Sstevel@tonic-gate goto out; 1250*7c478bd9Sstevel@tonic-gate } 1251*7c478bd9Sstevel@tonic-gate } 1252*7c478bd9Sstevel@tonic-gate 1253*7c478bd9Sstevel@tonic-gate if ((uint_t)inst_state & state_flags) { 1254*7c478bd9Sstevel@tonic-gate if (inst_callback(h, inst, private) != 1255*7c478bd9Sstevel@tonic-gate SCF_SUCCESS) { 1256*7c478bd9Sstevel@tonic-gate (void) scf_set_error( 1257*7c478bd9Sstevel@tonic-gate SCF_ERROR_CALLBACK_FAILED); 1258*7c478bd9Sstevel@tonic-gate goto out; 1259*7c478bd9Sstevel@tonic-gate } 1260*7c478bd9Sstevel@tonic-gate } 1261*7c478bd9Sstevel@tonic-gate } 1262*7c478bd9Sstevel@tonic-gate 1263*7c478bd9Sstevel@tonic-gate if (inst_iter_ret == -1) 1264*7c478bd9Sstevel@tonic-gate goto out; 1265*7c478bd9Sstevel@tonic-gate scf_iter_reset(inst_iter); 1266*7c478bd9Sstevel@tonic-gate } 1267*7c478bd9Sstevel@tonic-gate 1268*7c478bd9Sstevel@tonic-gate if (svc_iter_ret != -1) 1269*7c478bd9Sstevel@tonic-gate ret = SCF_SUCCESS; 1270*7c478bd9Sstevel@tonic-gate 1271*7c478bd9Sstevel@tonic-gate out: 1272*7c478bd9Sstevel@tonic-gate scf_scope_destroy(scope); 1273*7c478bd9Sstevel@tonic-gate scf_service_destroy(svc); 1274*7c478bd9Sstevel@tonic-gate scf_instance_destroy(inst); 1275*7c478bd9Sstevel@tonic-gate scf_iter_destroy(svc_iter); 1276*7c478bd9Sstevel@tonic-gate scf_iter_destroy(inst_iter); 1277*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1278*7c478bd9Sstevel@tonic-gate 1279*7c478bd9Sstevel@tonic-gate return (ret); 1280*7c478bd9Sstevel@tonic-gate } 1281*7c478bd9Sstevel@tonic-gate 1282*7c478bd9Sstevel@tonic-gate 1283*7c478bd9Sstevel@tonic-gate scf_simple_prop_t * 1284*7c478bd9Sstevel@tonic-gate scf_simple_prop_get(scf_handle_t *hin, const char *instance, const char *pgname, 1285*7c478bd9Sstevel@tonic-gate const char *propname) 1286*7c478bd9Sstevel@tonic-gate { 1287*7c478bd9Sstevel@tonic-gate char *fmri_buf, *svcfmri = NULL; 1288*7c478bd9Sstevel@tonic-gate ssize_t fmri_sz; 1289*7c478bd9Sstevel@tonic-gate scf_property_t *prop = NULL; 1290*7c478bd9Sstevel@tonic-gate scf_service_t *svc = NULL; 1291*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *ret; 1292*7c478bd9Sstevel@tonic-gate scf_handle_t *h = NULL; 1293*7c478bd9Sstevel@tonic-gate boolean_t local_h = B_TRUE; 1294*7c478bd9Sstevel@tonic-gate 1295*7c478bd9Sstevel@tonic-gate /* If the user passed in a handle, use it. */ 1296*7c478bd9Sstevel@tonic-gate if (hin != NULL) { 1297*7c478bd9Sstevel@tonic-gate h = hin; 1298*7c478bd9Sstevel@tonic-gate local_h = B_FALSE; 1299*7c478bd9Sstevel@tonic-gate } 1300*7c478bd9Sstevel@tonic-gate 1301*7c478bd9Sstevel@tonic-gate if (local_h && ((h = handle_create()) == NULL)) 1302*7c478bd9Sstevel@tonic-gate return (NULL); 1303*7c478bd9Sstevel@tonic-gate 1304*7c478bd9Sstevel@tonic-gate if ((fmri_buf = assemble_fmri(h, instance, pgname, propname)) == NULL) { 1305*7c478bd9Sstevel@tonic-gate if (local_h) 1306*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1307*7c478bd9Sstevel@tonic-gate return (NULL); 1308*7c478bd9Sstevel@tonic-gate } 1309*7c478bd9Sstevel@tonic-gate 1310*7c478bd9Sstevel@tonic-gate if ((svc = scf_service_create(h)) == NULL || 1311*7c478bd9Sstevel@tonic-gate (prop = scf_property_create(h)) == NULL) 1312*7c478bd9Sstevel@tonic-gate goto error1; 1313*7c478bd9Sstevel@tonic-gate if (scf_handle_decode_fmri(h, fmri_buf, NULL, NULL, NULL, NULL, prop, 1314*7c478bd9Sstevel@tonic-gate SCF_DECODE_FMRI_REQUIRE_INSTANCE) == -1) { 1315*7c478bd9Sstevel@tonic-gate switch (scf_error()) { 1316*7c478bd9Sstevel@tonic-gate /* 1317*7c478bd9Sstevel@tonic-gate * If the property isn't found in the instance, we grab the 1318*7c478bd9Sstevel@tonic-gate * underlying service, create an FMRI out of it, and then 1319*7c478bd9Sstevel@tonic-gate * query the datastore again at the service level for the 1320*7c478bd9Sstevel@tonic-gate * property. 1321*7c478bd9Sstevel@tonic-gate */ 1322*7c478bd9Sstevel@tonic-gate case SCF_ERROR_NOT_FOUND: 1323*7c478bd9Sstevel@tonic-gate if (scf_handle_decode_fmri(h, fmri_buf, NULL, svc, 1324*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL, SCF_DECODE_FMRI_TRUNCATE) == -1) 1325*7c478bd9Sstevel@tonic-gate goto error1; 1326*7c478bd9Sstevel@tonic-gate if ((fmri_sz = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH)) == 1327*7c478bd9Sstevel@tonic-gate -1) { 1328*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1329*7c478bd9Sstevel@tonic-gate goto error1; 1330*7c478bd9Sstevel@tonic-gate } 1331*7c478bd9Sstevel@tonic-gate if (scf_service_to_fmri(svc, fmri_buf, fmri_sz) == -1) 1332*7c478bd9Sstevel@tonic-gate goto error1; 1333*7c478bd9Sstevel@tonic-gate if ((svcfmri = assemble_fmri(h, fmri_buf, pgname, 1334*7c478bd9Sstevel@tonic-gate propname)) == NULL) 1335*7c478bd9Sstevel@tonic-gate goto error1; 1336*7c478bd9Sstevel@tonic-gate if (scf_handle_decode_fmri(h, svcfmri, NULL, NULL, 1337*7c478bd9Sstevel@tonic-gate NULL, NULL, prop, 0) == -1) { 1338*7c478bd9Sstevel@tonic-gate free(svcfmri); 1339*7c478bd9Sstevel@tonic-gate goto error1; 1340*7c478bd9Sstevel@tonic-gate } 1341*7c478bd9Sstevel@tonic-gate free(svcfmri); 1342*7c478bd9Sstevel@tonic-gate break; 1343*7c478bd9Sstevel@tonic-gate case SCF_ERROR_CONSTRAINT_VIOLATED: 1344*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 1345*7c478bd9Sstevel@tonic-gate default: 1346*7c478bd9Sstevel@tonic-gate goto error1; 1347*7c478bd9Sstevel@tonic-gate } 1348*7c478bd9Sstevel@tonic-gate } 1349*7c478bd9Sstevel@tonic-gate /* 1350*7c478bd9Sstevel@tonic-gate * At this point, we've successfully pulled the property from the 1351*7c478bd9Sstevel@tonic-gate * datastore, and simply need to copy its innards into an 1352*7c478bd9Sstevel@tonic-gate * scf_simple_prop_t. 1353*7c478bd9Sstevel@tonic-gate */ 1354*7c478bd9Sstevel@tonic-gate if ((ret = fill_prop(prop, pgname, propname, h)) == NULL) 1355*7c478bd9Sstevel@tonic-gate goto error1; 1356*7c478bd9Sstevel@tonic-gate 1357*7c478bd9Sstevel@tonic-gate scf_service_destroy(svc); 1358*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 1359*7c478bd9Sstevel@tonic-gate free(fmri_buf); 1360*7c478bd9Sstevel@tonic-gate if (local_h) 1361*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1362*7c478bd9Sstevel@tonic-gate return (ret); 1363*7c478bd9Sstevel@tonic-gate 1364*7c478bd9Sstevel@tonic-gate /* 1365*7c478bd9Sstevel@tonic-gate * Exit point for a successful call. Below this line are exit points 1366*7c478bd9Sstevel@tonic-gate * for failures at various stages during the function. 1367*7c478bd9Sstevel@tonic-gate */ 1368*7c478bd9Sstevel@tonic-gate 1369*7c478bd9Sstevel@tonic-gate error1: 1370*7c478bd9Sstevel@tonic-gate scf_service_destroy(svc); 1371*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 1372*7c478bd9Sstevel@tonic-gate error2: 1373*7c478bd9Sstevel@tonic-gate free(fmri_buf); 1374*7c478bd9Sstevel@tonic-gate if (local_h) 1375*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1376*7c478bd9Sstevel@tonic-gate return (NULL); 1377*7c478bd9Sstevel@tonic-gate } 1378*7c478bd9Sstevel@tonic-gate 1379*7c478bd9Sstevel@tonic-gate 1380*7c478bd9Sstevel@tonic-gate void 1381*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(scf_simple_prop_t *prop) 1382*7c478bd9Sstevel@tonic-gate { 1383*7c478bd9Sstevel@tonic-gate int i; 1384*7c478bd9Sstevel@tonic-gate 1385*7c478bd9Sstevel@tonic-gate if (prop == NULL) 1386*7c478bd9Sstevel@tonic-gate return; 1387*7c478bd9Sstevel@tonic-gate 1388*7c478bd9Sstevel@tonic-gate free(prop->pr_propname); 1389*7c478bd9Sstevel@tonic-gate free(prop->pr_pgname); 1390*7c478bd9Sstevel@tonic-gate switch (prop->pr_type) { 1391*7c478bd9Sstevel@tonic-gate case SCF_TYPE_OPAQUE: { 1392*7c478bd9Sstevel@tonic-gate for (i = 0; i < prop->pr_numvalues; i++) { 1393*7c478bd9Sstevel@tonic-gate free(prop->pr_vallist[i].pv_opaque.o_value); 1394*7c478bd9Sstevel@tonic-gate } 1395*7c478bd9Sstevel@tonic-gate break; 1396*7c478bd9Sstevel@tonic-gate } 1397*7c478bd9Sstevel@tonic-gate case SCF_TYPE_ASTRING: 1398*7c478bd9Sstevel@tonic-gate case SCF_TYPE_USTRING: 1399*7c478bd9Sstevel@tonic-gate case SCF_TYPE_HOST: 1400*7c478bd9Sstevel@tonic-gate case SCF_TYPE_HOSTNAME: 1401*7c478bd9Sstevel@tonic-gate case SCF_TYPE_NET_ADDR_V4: 1402*7c478bd9Sstevel@tonic-gate case SCF_TYPE_NET_ADDR_V6: 1403*7c478bd9Sstevel@tonic-gate case SCF_TYPE_URI: 1404*7c478bd9Sstevel@tonic-gate case SCF_TYPE_FMRI: { 1405*7c478bd9Sstevel@tonic-gate for (i = 0; i < prop->pr_numvalues; i++) { 1406*7c478bd9Sstevel@tonic-gate free(prop->pr_vallist[i].pv_str); 1407*7c478bd9Sstevel@tonic-gate } 1408*7c478bd9Sstevel@tonic-gate break; 1409*7c478bd9Sstevel@tonic-gate } 1410*7c478bd9Sstevel@tonic-gate default: 1411*7c478bd9Sstevel@tonic-gate break; 1412*7c478bd9Sstevel@tonic-gate } 1413*7c478bd9Sstevel@tonic-gate free(prop->pr_vallist); 1414*7c478bd9Sstevel@tonic-gate free(prop); 1415*7c478bd9Sstevel@tonic-gate } 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate 1418*7c478bd9Sstevel@tonic-gate scf_simple_app_props_t * 1419*7c478bd9Sstevel@tonic-gate scf_simple_app_props_get(scf_handle_t *hin, const char *inst_fmri) 1420*7c478bd9Sstevel@tonic-gate { 1421*7c478bd9Sstevel@tonic-gate scf_instance_t *inst = NULL; 1422*7c478bd9Sstevel@tonic-gate scf_service_t *svc = NULL; 1423*7c478bd9Sstevel@tonic-gate scf_propertygroup_t *pg = NULL; 1424*7c478bd9Sstevel@tonic-gate scf_property_t *prop = NULL; 1425*7c478bd9Sstevel@tonic-gate scf_simple_app_props_t *ret = NULL; 1426*7c478bd9Sstevel@tonic-gate scf_iter_t *pgiter = NULL, *propiter = NULL; 1427*7c478bd9Sstevel@tonic-gate struct scf_simple_pg *thispg = NULL, *nextpg; 1428*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *thisprop, *nextprop; 1429*7c478bd9Sstevel@tonic-gate scf_handle_t *h = NULL; 1430*7c478bd9Sstevel@tonic-gate int pgiter_ret, propiter_ret; 1431*7c478bd9Sstevel@tonic-gate ssize_t namelen; 1432*7c478bd9Sstevel@tonic-gate char *propname = NULL, *pgname = NULL, *sys_fmri; 1433*7c478bd9Sstevel@tonic-gate uint8_t found; 1434*7c478bd9Sstevel@tonic-gate boolean_t local_h = B_TRUE; 1435*7c478bd9Sstevel@tonic-gate 1436*7c478bd9Sstevel@tonic-gate /* If the user passed in a handle, use it. */ 1437*7c478bd9Sstevel@tonic-gate if (hin != NULL) { 1438*7c478bd9Sstevel@tonic-gate h = hin; 1439*7c478bd9Sstevel@tonic-gate local_h = B_FALSE; 1440*7c478bd9Sstevel@tonic-gate } 1441*7c478bd9Sstevel@tonic-gate 1442*7c478bd9Sstevel@tonic-gate if (local_h && ((h = handle_create()) == NULL)) 1443*7c478bd9Sstevel@tonic-gate return (NULL); 1444*7c478bd9Sstevel@tonic-gate 1445*7c478bd9Sstevel@tonic-gate if (inst_fmri == NULL) { 1446*7c478bd9Sstevel@tonic-gate if ((namelen = scf_myname(h, NULL, 0)) == -1) { 1447*7c478bd9Sstevel@tonic-gate if (local_h) 1448*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1449*7c478bd9Sstevel@tonic-gate return (NULL); 1450*7c478bd9Sstevel@tonic-gate } 1451*7c478bd9Sstevel@tonic-gate if ((sys_fmri = malloc(namelen + 1)) == NULL) { 1452*7c478bd9Sstevel@tonic-gate if (local_h) 1453*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1454*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1455*7c478bd9Sstevel@tonic-gate return (NULL); 1456*7c478bd9Sstevel@tonic-gate } 1457*7c478bd9Sstevel@tonic-gate if (scf_myname(h, sys_fmri, namelen + 1) == -1) { 1458*7c478bd9Sstevel@tonic-gate if (local_h) 1459*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1460*7c478bd9Sstevel@tonic-gate free(sys_fmri); 1461*7c478bd9Sstevel@tonic-gate return (NULL); 1462*7c478bd9Sstevel@tonic-gate } 1463*7c478bd9Sstevel@tonic-gate } else { 1464*7c478bd9Sstevel@tonic-gate sys_fmri = strdup(inst_fmri); 1465*7c478bd9Sstevel@tonic-gate } 1466*7c478bd9Sstevel@tonic-gate 1467*7c478bd9Sstevel@tonic-gate if ((namelen = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH)) == -1) { 1468*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1469*7c478bd9Sstevel@tonic-gate return (NULL); 1470*7c478bd9Sstevel@tonic-gate } 1471*7c478bd9Sstevel@tonic-gate 1472*7c478bd9Sstevel@tonic-gate if ((inst = scf_instance_create(h)) == NULL || 1473*7c478bd9Sstevel@tonic-gate (svc = scf_service_create(h)) == NULL || 1474*7c478bd9Sstevel@tonic-gate (pgiter = scf_iter_create(h)) == NULL || 1475*7c478bd9Sstevel@tonic-gate (propiter = scf_iter_create(h)) == NULL || 1476*7c478bd9Sstevel@tonic-gate (pg = scf_pg_create(h)) == NULL || 1477*7c478bd9Sstevel@tonic-gate (prop = scf_property_create(h)) == NULL) 1478*7c478bd9Sstevel@tonic-gate goto error2; 1479*7c478bd9Sstevel@tonic-gate 1480*7c478bd9Sstevel@tonic-gate if (scf_handle_decode_fmri(h, sys_fmri, NULL, svc, inst, NULL, NULL, 1481*7c478bd9Sstevel@tonic-gate SCF_DECODE_FMRI_REQUIRE_INSTANCE) == -1) { 1482*7c478bd9Sstevel@tonic-gate if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) 1483*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 1484*7c478bd9Sstevel@tonic-gate goto error2; 1485*7c478bd9Sstevel@tonic-gate } 1486*7c478bd9Sstevel@tonic-gate 1487*7c478bd9Sstevel@tonic-gate if ((ret = malloc(sizeof (*ret))) == NULL || 1488*7c478bd9Sstevel@tonic-gate (thispg = malloc(sizeof (*thispg))) == NULL || 1489*7c478bd9Sstevel@tonic-gate (propname = malloc(namelen)) == NULL || 1490*7c478bd9Sstevel@tonic-gate (pgname = malloc(namelen)) == NULL) { 1491*7c478bd9Sstevel@tonic-gate free(thispg); 1492*7c478bd9Sstevel@tonic-gate free(ret); 1493*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1494*7c478bd9Sstevel@tonic-gate goto error2; 1495*7c478bd9Sstevel@tonic-gate } 1496*7c478bd9Sstevel@tonic-gate 1497*7c478bd9Sstevel@tonic-gate ret->ap_fmri = sys_fmri; 1498*7c478bd9Sstevel@tonic-gate thispg->pg_name = NULL; 1499*7c478bd9Sstevel@tonic-gate thispg->pg_proplist = NULL; 1500*7c478bd9Sstevel@tonic-gate thispg->pg_next = NULL; 1501*7c478bd9Sstevel@tonic-gate ret->ap_pglist = thispg; 1502*7c478bd9Sstevel@tonic-gate 1503*7c478bd9Sstevel@tonic-gate if (scf_iter_service_pgs_typed(pgiter, svc, SCF_GROUP_APPLICATION) != 1504*7c478bd9Sstevel@tonic-gate 0) { 1505*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 1506*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1507*7c478bd9Sstevel@tonic-gate goto error1; 1508*7c478bd9Sstevel@tonic-gate } 1509*7c478bd9Sstevel@tonic-gate 1510*7c478bd9Sstevel@tonic-gate while ((pgiter_ret = scf_iter_next_pg(pgiter, pg)) == 1) { 1511*7c478bd9Sstevel@tonic-gate if (thispg->pg_name != NULL) { 1512*7c478bd9Sstevel@tonic-gate if ((nextpg = malloc(sizeof (*nextpg))) == NULL) { 1513*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1514*7c478bd9Sstevel@tonic-gate goto error1; 1515*7c478bd9Sstevel@tonic-gate } 1516*7c478bd9Sstevel@tonic-gate thispg->pg_next = nextpg; 1517*7c478bd9Sstevel@tonic-gate thispg = nextpg; 1518*7c478bd9Sstevel@tonic-gate } else { 1519*7c478bd9Sstevel@tonic-gate /* This is the first iteration */ 1520*7c478bd9Sstevel@tonic-gate nextpg = thispg; 1521*7c478bd9Sstevel@tonic-gate } 1522*7c478bd9Sstevel@tonic-gate 1523*7c478bd9Sstevel@tonic-gate if ((nextpg->pg_name = malloc(namelen)) == NULL) { 1524*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1525*7c478bd9Sstevel@tonic-gate goto error1; 1526*7c478bd9Sstevel@tonic-gate } 1527*7c478bd9Sstevel@tonic-gate 1528*7c478bd9Sstevel@tonic-gate if (scf_pg_get_name(pg, nextpg->pg_name, namelen) < 0) { 1529*7c478bd9Sstevel@tonic-gate if (scf_error() == SCF_ERROR_NOT_SET) 1530*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1531*7c478bd9Sstevel@tonic-gate goto error1; 1532*7c478bd9Sstevel@tonic-gate } 1533*7c478bd9Sstevel@tonic-gate 1534*7c478bd9Sstevel@tonic-gate nextpg->pg_next = NULL; 1535*7c478bd9Sstevel@tonic-gate nextpg->pg_proplist = NULL; 1536*7c478bd9Sstevel@tonic-gate thisprop = NULL; 1537*7c478bd9Sstevel@tonic-gate 1538*7c478bd9Sstevel@tonic-gate scf_iter_reset(propiter); 1539*7c478bd9Sstevel@tonic-gate 1540*7c478bd9Sstevel@tonic-gate if (scf_iter_pg_properties(propiter, pg) != 0) { 1541*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 1542*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1543*7c478bd9Sstevel@tonic-gate goto error1; 1544*7c478bd9Sstevel@tonic-gate } 1545*7c478bd9Sstevel@tonic-gate 1546*7c478bd9Sstevel@tonic-gate while ((propiter_ret = scf_iter_next_property(propiter, prop)) 1547*7c478bd9Sstevel@tonic-gate == 1) { 1548*7c478bd9Sstevel@tonic-gate if (scf_property_get_name(prop, propname, namelen) < 1549*7c478bd9Sstevel@tonic-gate 0) { 1550*7c478bd9Sstevel@tonic-gate if (scf_error() == SCF_ERROR_NOT_SET) 1551*7c478bd9Sstevel@tonic-gate (void) scf_set_error( 1552*7c478bd9Sstevel@tonic-gate SCF_ERROR_INTERNAL); 1553*7c478bd9Sstevel@tonic-gate goto error1; 1554*7c478bd9Sstevel@tonic-gate } 1555*7c478bd9Sstevel@tonic-gate if (thisprop != NULL) { 1556*7c478bd9Sstevel@tonic-gate if ((nextprop = fill_prop(prop, 1557*7c478bd9Sstevel@tonic-gate nextpg->pg_name, propname, h)) == NULL) 1558*7c478bd9Sstevel@tonic-gate goto error1; 1559*7c478bd9Sstevel@tonic-gate thisprop->pr_next = nextprop; 1560*7c478bd9Sstevel@tonic-gate thisprop = nextprop; 1561*7c478bd9Sstevel@tonic-gate } else { 1562*7c478bd9Sstevel@tonic-gate /* This is the first iteration */ 1563*7c478bd9Sstevel@tonic-gate if ((thisprop = fill_prop(prop, 1564*7c478bd9Sstevel@tonic-gate nextpg->pg_name, propname, h)) == NULL) 1565*7c478bd9Sstevel@tonic-gate goto error1; 1566*7c478bd9Sstevel@tonic-gate nextpg->pg_proplist = thisprop; 1567*7c478bd9Sstevel@tonic-gate nextprop = thisprop; 1568*7c478bd9Sstevel@tonic-gate } 1569*7c478bd9Sstevel@tonic-gate nextprop->pr_pg = nextpg; 1570*7c478bd9Sstevel@tonic-gate nextprop->pr_next = NULL; 1571*7c478bd9Sstevel@tonic-gate } 1572*7c478bd9Sstevel@tonic-gate 1573*7c478bd9Sstevel@tonic-gate if (propiter_ret == -1) { 1574*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 1575*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1576*7c478bd9Sstevel@tonic-gate goto error1; 1577*7c478bd9Sstevel@tonic-gate } 1578*7c478bd9Sstevel@tonic-gate } 1579*7c478bd9Sstevel@tonic-gate 1580*7c478bd9Sstevel@tonic-gate if (pgiter_ret == -1) { 1581*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 1582*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1583*7c478bd9Sstevel@tonic-gate goto error1; 1584*7c478bd9Sstevel@tonic-gate } 1585*7c478bd9Sstevel@tonic-gate 1586*7c478bd9Sstevel@tonic-gate /* 1587*7c478bd9Sstevel@tonic-gate * At this point, we've filled the scf_simple_app_props_t with all the 1588*7c478bd9Sstevel@tonic-gate * properties at the service level. Now we iterate over all the 1589*7c478bd9Sstevel@tonic-gate * properties at the instance level, overwriting any duplicate 1590*7c478bd9Sstevel@tonic-gate * properties, in order to provide service/instance composition. 1591*7c478bd9Sstevel@tonic-gate */ 1592*7c478bd9Sstevel@tonic-gate 1593*7c478bd9Sstevel@tonic-gate scf_iter_reset(pgiter); 1594*7c478bd9Sstevel@tonic-gate scf_iter_reset(propiter); 1595*7c478bd9Sstevel@tonic-gate 1596*7c478bd9Sstevel@tonic-gate if (scf_iter_instance_pgs_typed(pgiter, inst, SCF_GROUP_APPLICATION) 1597*7c478bd9Sstevel@tonic-gate != 0) { 1598*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 1599*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1600*7c478bd9Sstevel@tonic-gate goto error1; 1601*7c478bd9Sstevel@tonic-gate } 1602*7c478bd9Sstevel@tonic-gate 1603*7c478bd9Sstevel@tonic-gate while ((pgiter_ret = scf_iter_next_pg(pgiter, pg)) == 1) { 1604*7c478bd9Sstevel@tonic-gate 1605*7c478bd9Sstevel@tonic-gate thispg = ret->ap_pglist; 1606*7c478bd9Sstevel@tonic-gate found = 0; 1607*7c478bd9Sstevel@tonic-gate 1608*7c478bd9Sstevel@tonic-gate /* 1609*7c478bd9Sstevel@tonic-gate * Find either the end of the list, so we can append the 1610*7c478bd9Sstevel@tonic-gate * property group, or an existing property group that matches 1611*7c478bd9Sstevel@tonic-gate * it, so we can insert/overwrite its properties. 1612*7c478bd9Sstevel@tonic-gate */ 1613*7c478bd9Sstevel@tonic-gate 1614*7c478bd9Sstevel@tonic-gate if (scf_pg_get_name(pg, pgname, namelen) < 0) { 1615*7c478bd9Sstevel@tonic-gate if (scf_error() == SCF_ERROR_NOT_SET) 1616*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1617*7c478bd9Sstevel@tonic-gate goto error1; 1618*7c478bd9Sstevel@tonic-gate } 1619*7c478bd9Sstevel@tonic-gate 1620*7c478bd9Sstevel@tonic-gate while ((thispg != NULL) && (thispg->pg_name != NULL)) { 1621*7c478bd9Sstevel@tonic-gate if (strcmp(thispg->pg_name, pgname) == 0) { 1622*7c478bd9Sstevel@tonic-gate found = 1; 1623*7c478bd9Sstevel@tonic-gate break; 1624*7c478bd9Sstevel@tonic-gate } 1625*7c478bd9Sstevel@tonic-gate if (thispg->pg_next == NULL) 1626*7c478bd9Sstevel@tonic-gate break; 1627*7c478bd9Sstevel@tonic-gate 1628*7c478bd9Sstevel@tonic-gate thispg = thispg->pg_next; 1629*7c478bd9Sstevel@tonic-gate } 1630*7c478bd9Sstevel@tonic-gate 1631*7c478bd9Sstevel@tonic-gate scf_iter_reset(propiter); 1632*7c478bd9Sstevel@tonic-gate 1633*7c478bd9Sstevel@tonic-gate if (scf_iter_pg_properties(propiter, pg) != 0) { 1634*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 1635*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1636*7c478bd9Sstevel@tonic-gate goto error1; 1637*7c478bd9Sstevel@tonic-gate } 1638*7c478bd9Sstevel@tonic-gate 1639*7c478bd9Sstevel@tonic-gate if (found) { 1640*7c478bd9Sstevel@tonic-gate /* 1641*7c478bd9Sstevel@tonic-gate * insert_app_props inserts or overwrites the 1642*7c478bd9Sstevel@tonic-gate * properties in thispg. 1643*7c478bd9Sstevel@tonic-gate */ 1644*7c478bd9Sstevel@tonic-gate 1645*7c478bd9Sstevel@tonic-gate if (insert_app_props(propiter, pgname, propname, 1646*7c478bd9Sstevel@tonic-gate thispg, prop, namelen, h) == -1) 1647*7c478bd9Sstevel@tonic-gate goto error1; 1648*7c478bd9Sstevel@tonic-gate 1649*7c478bd9Sstevel@tonic-gate } else { 1650*7c478bd9Sstevel@tonic-gate /* 1651*7c478bd9Sstevel@tonic-gate * If the property group wasn't found, we're adding 1652*7c478bd9Sstevel@tonic-gate * a newly allocated property group to the end of the 1653*7c478bd9Sstevel@tonic-gate * list. 1654*7c478bd9Sstevel@tonic-gate */ 1655*7c478bd9Sstevel@tonic-gate 1656*7c478bd9Sstevel@tonic-gate if ((nextpg = malloc(sizeof (*nextpg))) == NULL) { 1657*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1658*7c478bd9Sstevel@tonic-gate goto error1; 1659*7c478bd9Sstevel@tonic-gate } 1660*7c478bd9Sstevel@tonic-gate nextpg->pg_next = NULL; 1661*7c478bd9Sstevel@tonic-gate nextpg->pg_proplist = NULL; 1662*7c478bd9Sstevel@tonic-gate thisprop = NULL; 1663*7c478bd9Sstevel@tonic-gate 1664*7c478bd9Sstevel@tonic-gate if ((nextpg->pg_name = strdup(pgname)) == NULL) { 1665*7c478bd9Sstevel@tonic-gate free(nextpg); 1666*7c478bd9Sstevel@tonic-gate goto error1; 1667*7c478bd9Sstevel@tonic-gate } 1668*7c478bd9Sstevel@tonic-gate 1669*7c478bd9Sstevel@tonic-gate if (thispg->pg_name == NULL) { 1670*7c478bd9Sstevel@tonic-gate free(thispg); 1671*7c478bd9Sstevel@tonic-gate ret->ap_pglist = nextpg; 1672*7c478bd9Sstevel@tonic-gate } else { 1673*7c478bd9Sstevel@tonic-gate thispg->pg_next = nextpg; 1674*7c478bd9Sstevel@tonic-gate } 1675*7c478bd9Sstevel@tonic-gate 1676*7c478bd9Sstevel@tonic-gate while ((propiter_ret = 1677*7c478bd9Sstevel@tonic-gate scf_iter_next_property(propiter, prop)) == 1) { 1678*7c478bd9Sstevel@tonic-gate if (scf_property_get_name(prop, propname, 1679*7c478bd9Sstevel@tonic-gate namelen) < 0) { 1680*7c478bd9Sstevel@tonic-gate if (scf_error() == SCF_ERROR_NOT_SET) 1681*7c478bd9Sstevel@tonic-gate (void) scf_set_error( 1682*7c478bd9Sstevel@tonic-gate SCF_ERROR_INTERNAL); 1683*7c478bd9Sstevel@tonic-gate goto error1; 1684*7c478bd9Sstevel@tonic-gate } 1685*7c478bd9Sstevel@tonic-gate if (thisprop != NULL) { 1686*7c478bd9Sstevel@tonic-gate if ((nextprop = fill_prop(prop, 1687*7c478bd9Sstevel@tonic-gate pgname, propname, h)) == 1688*7c478bd9Sstevel@tonic-gate NULL) 1689*7c478bd9Sstevel@tonic-gate goto error1; 1690*7c478bd9Sstevel@tonic-gate thisprop->pr_next = nextprop; 1691*7c478bd9Sstevel@tonic-gate thisprop = nextprop; 1692*7c478bd9Sstevel@tonic-gate } else { 1693*7c478bd9Sstevel@tonic-gate /* This is the first iteration */ 1694*7c478bd9Sstevel@tonic-gate if ((thisprop = fill_prop(prop, 1695*7c478bd9Sstevel@tonic-gate pgname, propname, h)) == 1696*7c478bd9Sstevel@tonic-gate NULL) 1697*7c478bd9Sstevel@tonic-gate goto error1; 1698*7c478bd9Sstevel@tonic-gate nextpg->pg_proplist = thisprop; 1699*7c478bd9Sstevel@tonic-gate nextprop = thisprop; 1700*7c478bd9Sstevel@tonic-gate } 1701*7c478bd9Sstevel@tonic-gate nextprop->pr_pg = nextpg; 1702*7c478bd9Sstevel@tonic-gate nextprop->pr_next = NULL; 1703*7c478bd9Sstevel@tonic-gate } 1704*7c478bd9Sstevel@tonic-gate 1705*7c478bd9Sstevel@tonic-gate if (propiter_ret == -1) { 1706*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 1707*7c478bd9Sstevel@tonic-gate (void) scf_set_error( 1708*7c478bd9Sstevel@tonic-gate SCF_ERROR_INTERNAL); 1709*7c478bd9Sstevel@tonic-gate goto error1; 1710*7c478bd9Sstevel@tonic-gate } 1711*7c478bd9Sstevel@tonic-gate } 1712*7c478bd9Sstevel@tonic-gate 1713*7c478bd9Sstevel@tonic-gate } 1714*7c478bd9Sstevel@tonic-gate 1715*7c478bd9Sstevel@tonic-gate if (pgiter_ret == -1) { 1716*7c478bd9Sstevel@tonic-gate if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) 1717*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_INTERNAL); 1718*7c478bd9Sstevel@tonic-gate goto error1; 1719*7c478bd9Sstevel@tonic-gate } 1720*7c478bd9Sstevel@tonic-gate 1721*7c478bd9Sstevel@tonic-gate scf_iter_destroy(pgiter); 1722*7c478bd9Sstevel@tonic-gate scf_iter_destroy(propiter); 1723*7c478bd9Sstevel@tonic-gate scf_pg_destroy(pg); 1724*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 1725*7c478bd9Sstevel@tonic-gate scf_instance_destroy(inst); 1726*7c478bd9Sstevel@tonic-gate scf_service_destroy(svc); 1727*7c478bd9Sstevel@tonic-gate free(propname); 1728*7c478bd9Sstevel@tonic-gate free(pgname); 1729*7c478bd9Sstevel@tonic-gate if (local_h) 1730*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1731*7c478bd9Sstevel@tonic-gate 1732*7c478bd9Sstevel@tonic-gate if (ret->ap_pglist->pg_name == NULL) 1733*7c478bd9Sstevel@tonic-gate return (NULL); 1734*7c478bd9Sstevel@tonic-gate 1735*7c478bd9Sstevel@tonic-gate return (ret); 1736*7c478bd9Sstevel@tonic-gate 1737*7c478bd9Sstevel@tonic-gate /* 1738*7c478bd9Sstevel@tonic-gate * Exit point for a successful call. Below this line are exit points 1739*7c478bd9Sstevel@tonic-gate * for failures at various stages during the function. 1740*7c478bd9Sstevel@tonic-gate */ 1741*7c478bd9Sstevel@tonic-gate 1742*7c478bd9Sstevel@tonic-gate error1: 1743*7c478bd9Sstevel@tonic-gate scf_simple_app_props_free(ret); 1744*7c478bd9Sstevel@tonic-gate 1745*7c478bd9Sstevel@tonic-gate error2: 1746*7c478bd9Sstevel@tonic-gate scf_iter_destroy(pgiter); 1747*7c478bd9Sstevel@tonic-gate scf_iter_destroy(propiter); 1748*7c478bd9Sstevel@tonic-gate scf_pg_destroy(pg); 1749*7c478bd9Sstevel@tonic-gate scf_property_destroy(prop); 1750*7c478bd9Sstevel@tonic-gate scf_instance_destroy(inst); 1751*7c478bd9Sstevel@tonic-gate scf_service_destroy(svc); 1752*7c478bd9Sstevel@tonic-gate free(propname); 1753*7c478bd9Sstevel@tonic-gate free(pgname); 1754*7c478bd9Sstevel@tonic-gate if (local_h) 1755*7c478bd9Sstevel@tonic-gate scf_handle_destroy(h); 1756*7c478bd9Sstevel@tonic-gate return (NULL); 1757*7c478bd9Sstevel@tonic-gate } 1758*7c478bd9Sstevel@tonic-gate 1759*7c478bd9Sstevel@tonic-gate 1760*7c478bd9Sstevel@tonic-gate void 1761*7c478bd9Sstevel@tonic-gate scf_simple_app_props_free(scf_simple_app_props_t *propblock) 1762*7c478bd9Sstevel@tonic-gate { 1763*7c478bd9Sstevel@tonic-gate struct scf_simple_pg *pgthis, *pgnext; 1764*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *propthis, *propnext; 1765*7c478bd9Sstevel@tonic-gate 1766*7c478bd9Sstevel@tonic-gate if ((propblock == NULL) || (propblock->ap_pglist == NULL)) 1767*7c478bd9Sstevel@tonic-gate return; 1768*7c478bd9Sstevel@tonic-gate 1769*7c478bd9Sstevel@tonic-gate for (pgthis = propblock->ap_pglist; pgthis != NULL; pgthis = pgnext) { 1770*7c478bd9Sstevel@tonic-gate pgnext = pgthis->pg_next; 1771*7c478bd9Sstevel@tonic-gate 1772*7c478bd9Sstevel@tonic-gate propthis = pgthis->pg_proplist; 1773*7c478bd9Sstevel@tonic-gate 1774*7c478bd9Sstevel@tonic-gate while (propthis != NULL) { 1775*7c478bd9Sstevel@tonic-gate propnext = propthis->pr_next; 1776*7c478bd9Sstevel@tonic-gate scf_simple_prop_free(propthis); 1777*7c478bd9Sstevel@tonic-gate propthis = propnext; 1778*7c478bd9Sstevel@tonic-gate } 1779*7c478bd9Sstevel@tonic-gate 1780*7c478bd9Sstevel@tonic-gate free(pgthis->pg_name); 1781*7c478bd9Sstevel@tonic-gate free(pgthis); 1782*7c478bd9Sstevel@tonic-gate } 1783*7c478bd9Sstevel@tonic-gate 1784*7c478bd9Sstevel@tonic-gate free(propblock->ap_fmri); 1785*7c478bd9Sstevel@tonic-gate free(propblock); 1786*7c478bd9Sstevel@tonic-gate } 1787*7c478bd9Sstevel@tonic-gate 1788*7c478bd9Sstevel@tonic-gate const scf_simple_prop_t * 1789*7c478bd9Sstevel@tonic-gate scf_simple_app_props_next(const scf_simple_app_props_t *propblock, 1790*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *last) 1791*7c478bd9Sstevel@tonic-gate { 1792*7c478bd9Sstevel@tonic-gate struct scf_simple_pg *this; 1793*7c478bd9Sstevel@tonic-gate 1794*7c478bd9Sstevel@tonic-gate if (propblock == NULL) { 1795*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NOT_SET); 1796*7c478bd9Sstevel@tonic-gate return (NULL); 1797*7c478bd9Sstevel@tonic-gate } 1798*7c478bd9Sstevel@tonic-gate 1799*7c478bd9Sstevel@tonic-gate this = propblock->ap_pglist; 1800*7c478bd9Sstevel@tonic-gate 1801*7c478bd9Sstevel@tonic-gate /* 1802*7c478bd9Sstevel@tonic-gate * We're looking for the first property in this block if last is 1803*7c478bd9Sstevel@tonic-gate * NULL 1804*7c478bd9Sstevel@tonic-gate */ 1805*7c478bd9Sstevel@tonic-gate 1806*7c478bd9Sstevel@tonic-gate if (last == NULL) { 1807*7c478bd9Sstevel@tonic-gate /* An empty pglist is legal, it just means no properties */ 1808*7c478bd9Sstevel@tonic-gate if (this == NULL) { 1809*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NONE); 1810*7c478bd9Sstevel@tonic-gate return (NULL); 1811*7c478bd9Sstevel@tonic-gate } 1812*7c478bd9Sstevel@tonic-gate /* 1813*7c478bd9Sstevel@tonic-gate * Walk until we find a pg with a property in it, or we run 1814*7c478bd9Sstevel@tonic-gate * out of property groups. 1815*7c478bd9Sstevel@tonic-gate */ 1816*7c478bd9Sstevel@tonic-gate while ((this->pg_proplist == NULL) && (this->pg_next != NULL)) 1817*7c478bd9Sstevel@tonic-gate this = this->pg_next; 1818*7c478bd9Sstevel@tonic-gate 1819*7c478bd9Sstevel@tonic-gate if (this->pg_proplist == NULL) { 1820*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NONE); 1821*7c478bd9Sstevel@tonic-gate return (NULL); 1822*7c478bd9Sstevel@tonic-gate } 1823*7c478bd9Sstevel@tonic-gate 1824*7c478bd9Sstevel@tonic-gate return (this->pg_proplist); 1825*7c478bd9Sstevel@tonic-gate 1826*7c478bd9Sstevel@tonic-gate } 1827*7c478bd9Sstevel@tonic-gate /* 1828*7c478bd9Sstevel@tonic-gate * If last isn't NULL, then return the next prop in the property group, 1829*7c478bd9Sstevel@tonic-gate * or walk the property groups until we find another property, or 1830*7c478bd9Sstevel@tonic-gate * run out of property groups. 1831*7c478bd9Sstevel@tonic-gate */ 1832*7c478bd9Sstevel@tonic-gate if (last->pr_next != NULL) 1833*7c478bd9Sstevel@tonic-gate return (last->pr_next); 1834*7c478bd9Sstevel@tonic-gate 1835*7c478bd9Sstevel@tonic-gate if (last->pr_pg->pg_next == NULL) { 1836*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NONE); 1837*7c478bd9Sstevel@tonic-gate return (NULL); 1838*7c478bd9Sstevel@tonic-gate } 1839*7c478bd9Sstevel@tonic-gate 1840*7c478bd9Sstevel@tonic-gate this = last->pr_pg->pg_next; 1841*7c478bd9Sstevel@tonic-gate 1842*7c478bd9Sstevel@tonic-gate while ((this->pg_proplist == NULL) && (this->pg_next != NULL)) 1843*7c478bd9Sstevel@tonic-gate this = this->pg_next; 1844*7c478bd9Sstevel@tonic-gate 1845*7c478bd9Sstevel@tonic-gate if (this->pg_proplist == NULL) { 1846*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NONE); 1847*7c478bd9Sstevel@tonic-gate return (NULL); 1848*7c478bd9Sstevel@tonic-gate } 1849*7c478bd9Sstevel@tonic-gate 1850*7c478bd9Sstevel@tonic-gate return (this->pg_proplist); 1851*7c478bd9Sstevel@tonic-gate } 1852*7c478bd9Sstevel@tonic-gate 1853*7c478bd9Sstevel@tonic-gate const scf_simple_prop_t * 1854*7c478bd9Sstevel@tonic-gate scf_simple_app_props_search(const scf_simple_app_props_t *propblock, 1855*7c478bd9Sstevel@tonic-gate const char *pgname, const char *propname) 1856*7c478bd9Sstevel@tonic-gate { 1857*7c478bd9Sstevel@tonic-gate struct scf_simple_pg *pg; 1858*7c478bd9Sstevel@tonic-gate scf_simple_prop_t *prop; 1859*7c478bd9Sstevel@tonic-gate 1860*7c478bd9Sstevel@tonic-gate if ((propblock == NULL) || (propname == NULL)) { 1861*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NOT_SET); 1862*7c478bd9Sstevel@tonic-gate return (NULL); 1863*7c478bd9Sstevel@tonic-gate } 1864*7c478bd9Sstevel@tonic-gate 1865*7c478bd9Sstevel@tonic-gate pg = propblock->ap_pglist; 1866*7c478bd9Sstevel@tonic-gate 1867*7c478bd9Sstevel@tonic-gate /* 1868*7c478bd9Sstevel@tonic-gate * If pgname is NULL, we're searching the default application 1869*7c478bd9Sstevel@tonic-gate * property group, otherwise we look for the specified group. 1870*7c478bd9Sstevel@tonic-gate */ 1871*7c478bd9Sstevel@tonic-gate if (pgname == NULL) { 1872*7c478bd9Sstevel@tonic-gate while ((pg != NULL) && 1873*7c478bd9Sstevel@tonic-gate (strcmp(SCF_PG_APP_DEFAULT, pg->pg_name) != 0)) 1874*7c478bd9Sstevel@tonic-gate pg = pg->pg_next; 1875*7c478bd9Sstevel@tonic-gate } else { 1876*7c478bd9Sstevel@tonic-gate while ((pg != NULL) && (strcmp(pgname, pg->pg_name) != 0)) 1877*7c478bd9Sstevel@tonic-gate pg = pg->pg_next; 1878*7c478bd9Sstevel@tonic-gate } 1879*7c478bd9Sstevel@tonic-gate 1880*7c478bd9Sstevel@tonic-gate if (pg == NULL) { 1881*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NOT_FOUND); 1882*7c478bd9Sstevel@tonic-gate return (NULL); 1883*7c478bd9Sstevel@tonic-gate } 1884*7c478bd9Sstevel@tonic-gate 1885*7c478bd9Sstevel@tonic-gate prop = pg->pg_proplist; 1886*7c478bd9Sstevel@tonic-gate 1887*7c478bd9Sstevel@tonic-gate while ((prop != NULL) && (strcmp(propname, prop->pr_propname) != 0)) 1888*7c478bd9Sstevel@tonic-gate prop = prop->pr_next; 1889*7c478bd9Sstevel@tonic-gate 1890*7c478bd9Sstevel@tonic-gate if (prop == NULL) { 1891*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NOT_FOUND); 1892*7c478bd9Sstevel@tonic-gate return (NULL); 1893*7c478bd9Sstevel@tonic-gate } 1894*7c478bd9Sstevel@tonic-gate 1895*7c478bd9Sstevel@tonic-gate return (prop); 1896*7c478bd9Sstevel@tonic-gate } 1897*7c478bd9Sstevel@tonic-gate 1898*7c478bd9Sstevel@tonic-gate void 1899*7c478bd9Sstevel@tonic-gate scf_simple_prop_next_reset(scf_simple_prop_t *prop) 1900*7c478bd9Sstevel@tonic-gate { 1901*7c478bd9Sstevel@tonic-gate if (prop == NULL) 1902*7c478bd9Sstevel@tonic-gate return; 1903*7c478bd9Sstevel@tonic-gate prop->pr_iter = 0; 1904*7c478bd9Sstevel@tonic-gate } 1905*7c478bd9Sstevel@tonic-gate 1906*7c478bd9Sstevel@tonic-gate ssize_t 1907*7c478bd9Sstevel@tonic-gate scf_simple_prop_numvalues(const scf_simple_prop_t *prop) 1908*7c478bd9Sstevel@tonic-gate { 1909*7c478bd9Sstevel@tonic-gate if (prop == NULL) 1910*7c478bd9Sstevel@tonic-gate return (scf_set_error(SCF_ERROR_NOT_SET)); 1911*7c478bd9Sstevel@tonic-gate 1912*7c478bd9Sstevel@tonic-gate return (prop->pr_numvalues); 1913*7c478bd9Sstevel@tonic-gate } 1914*7c478bd9Sstevel@tonic-gate 1915*7c478bd9Sstevel@tonic-gate 1916*7c478bd9Sstevel@tonic-gate scf_type_t 1917*7c478bd9Sstevel@tonic-gate scf_simple_prop_type(const scf_simple_prop_t *prop) 1918*7c478bd9Sstevel@tonic-gate { 1919*7c478bd9Sstevel@tonic-gate if (prop == NULL) 1920*7c478bd9Sstevel@tonic-gate return (scf_set_error(SCF_ERROR_NOT_SET)); 1921*7c478bd9Sstevel@tonic-gate 1922*7c478bd9Sstevel@tonic-gate return (prop->pr_type); 1923*7c478bd9Sstevel@tonic-gate } 1924*7c478bd9Sstevel@tonic-gate 1925*7c478bd9Sstevel@tonic-gate 1926*7c478bd9Sstevel@tonic-gate char * 1927*7c478bd9Sstevel@tonic-gate scf_simple_prop_name(const scf_simple_prop_t *prop) 1928*7c478bd9Sstevel@tonic-gate { 1929*7c478bd9Sstevel@tonic-gate if ((prop == NULL) || (prop->pr_propname == NULL)) { 1930*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NOT_SET); 1931*7c478bd9Sstevel@tonic-gate return (NULL); 1932*7c478bd9Sstevel@tonic-gate } 1933*7c478bd9Sstevel@tonic-gate 1934*7c478bd9Sstevel@tonic-gate return (prop->pr_propname); 1935*7c478bd9Sstevel@tonic-gate } 1936*7c478bd9Sstevel@tonic-gate 1937*7c478bd9Sstevel@tonic-gate 1938*7c478bd9Sstevel@tonic-gate char * 1939*7c478bd9Sstevel@tonic-gate scf_simple_prop_pgname(const scf_simple_prop_t *prop) 1940*7c478bd9Sstevel@tonic-gate { 1941*7c478bd9Sstevel@tonic-gate if ((prop == NULL) || (prop->pr_pgname == NULL)) { 1942*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NOT_SET); 1943*7c478bd9Sstevel@tonic-gate return (NULL); 1944*7c478bd9Sstevel@tonic-gate } 1945*7c478bd9Sstevel@tonic-gate 1946*7c478bd9Sstevel@tonic-gate return (prop->pr_pgname); 1947*7c478bd9Sstevel@tonic-gate } 1948*7c478bd9Sstevel@tonic-gate 1949*7c478bd9Sstevel@tonic-gate 1950*7c478bd9Sstevel@tonic-gate static union scf_simple_prop_val * 1951*7c478bd9Sstevel@tonic-gate scf_next_val(scf_simple_prop_t *prop, scf_type_t type) 1952*7c478bd9Sstevel@tonic-gate { 1953*7c478bd9Sstevel@tonic-gate if (prop == NULL) { 1954*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NOT_SET); 1955*7c478bd9Sstevel@tonic-gate return (NULL); 1956*7c478bd9Sstevel@tonic-gate } 1957*7c478bd9Sstevel@tonic-gate 1958*7c478bd9Sstevel@tonic-gate switch (prop->pr_type) { 1959*7c478bd9Sstevel@tonic-gate case SCF_TYPE_USTRING: 1960*7c478bd9Sstevel@tonic-gate case SCF_TYPE_HOST: 1961*7c478bd9Sstevel@tonic-gate case SCF_TYPE_HOSTNAME: 1962*7c478bd9Sstevel@tonic-gate case SCF_TYPE_NET_ADDR_V4: 1963*7c478bd9Sstevel@tonic-gate case SCF_TYPE_NET_ADDR_V6: 1964*7c478bd9Sstevel@tonic-gate case SCF_TYPE_URI: 1965*7c478bd9Sstevel@tonic-gate case SCF_TYPE_FMRI: { 1966*7c478bd9Sstevel@tonic-gate if (type != SCF_TYPE_USTRING) { 1967*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_TYPE_MISMATCH); 1968*7c478bd9Sstevel@tonic-gate return (NULL); 1969*7c478bd9Sstevel@tonic-gate } 1970*7c478bd9Sstevel@tonic-gate break; 1971*7c478bd9Sstevel@tonic-gate } 1972*7c478bd9Sstevel@tonic-gate default: { 1973*7c478bd9Sstevel@tonic-gate if (type != prop->pr_type) { 1974*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_TYPE_MISMATCH); 1975*7c478bd9Sstevel@tonic-gate return (NULL); 1976*7c478bd9Sstevel@tonic-gate } 1977*7c478bd9Sstevel@tonic-gate break; 1978*7c478bd9Sstevel@tonic-gate } 1979*7c478bd9Sstevel@tonic-gate } 1980*7c478bd9Sstevel@tonic-gate 1981*7c478bd9Sstevel@tonic-gate if (prop->pr_iter >= prop->pr_numvalues) { 1982*7c478bd9Sstevel@tonic-gate (void) scf_set_error(SCF_ERROR_NONE); 1983*7c478bd9Sstevel@tonic-gate return (NULL); 1984*7c478bd9Sstevel@tonic-gate } 1985*7c478bd9Sstevel@tonic-gate 1986*7c478bd9Sstevel@tonic-gate return (&prop->pr_vallist[prop->pr_iter++]); 1987*7c478bd9Sstevel@tonic-gate } 1988*7c478bd9Sstevel@tonic-gate 1989*7c478bd9Sstevel@tonic-gate 1990*7c478bd9Sstevel@tonic-gate uint8_t * 1991*7c478bd9Sstevel@tonic-gate scf_simple_prop_next_boolean(scf_simple_prop_t *prop) 1992*7c478bd9Sstevel@tonic-gate { 1993*7c478bd9Sstevel@tonic-gate union scf_simple_prop_val *ret; 1994*7c478bd9Sstevel@tonic-gate 1995*7c478bd9Sstevel@tonic-gate ret = scf_next_val(prop, SCF_TYPE_BOOLEAN); 1996*7c478bd9Sstevel@tonic-gate 1997*7c478bd9Sstevel@tonic-gate if (ret == NULL) 1998*7c478bd9Sstevel@tonic-gate return (NULL); 1999*7c478bd9Sstevel@tonic-gate 2000*7c478bd9Sstevel@tonic-gate return (&ret->pv_bool); 2001*7c478bd9Sstevel@tonic-gate } 2002*7c478bd9Sstevel@tonic-gate 2003*7c478bd9Sstevel@tonic-gate 2004*7c478bd9Sstevel@tonic-gate uint64_t * 2005*7c478bd9Sstevel@tonic-gate scf_simple_prop_next_count(scf_simple_prop_t *prop) 2006*7c478bd9Sstevel@tonic-gate { 2007*7c478bd9Sstevel@tonic-gate union scf_simple_prop_val *ret; 2008*7c478bd9Sstevel@tonic-gate 2009*7c478bd9Sstevel@tonic-gate ret = scf_next_val(prop, SCF_TYPE_COUNT); 2010*7c478bd9Sstevel@tonic-gate 2011*7c478bd9Sstevel@tonic-gate if (ret == NULL) 2012*7c478bd9Sstevel@tonic-gate return (NULL); 2013*7c478bd9Sstevel@tonic-gate 2014*7c478bd9Sstevel@tonic-gate return (&ret->pv_uint); 2015*7c478bd9Sstevel@tonic-gate } 2016*7c478bd9Sstevel@tonic-gate 2017*7c478bd9Sstevel@tonic-gate 2018*7c478bd9Sstevel@tonic-gate int64_t * 2019*7c478bd9Sstevel@tonic-gate scf_simple_prop_next_integer(scf_simple_prop_t *prop) 2020*7c478bd9Sstevel@tonic-gate { 2021*7c478bd9Sstevel@tonic-gate union scf_simple_prop_val *ret; 2022*7c478bd9Sstevel@tonic-gate 2023*7c478bd9Sstevel@tonic-gate ret = scf_next_val(prop, SCF_TYPE_INTEGER); 2024*7c478bd9Sstevel@tonic-gate 2025*7c478bd9Sstevel@tonic-gate if (ret == NULL) 2026*7c478bd9Sstevel@tonic-gate return (NULL); 2027*7c478bd9Sstevel@tonic-gate 2028*7c478bd9Sstevel@tonic-gate return (&ret->pv_int); 2029*7c478bd9Sstevel@tonic-gate } 2030*7c478bd9Sstevel@tonic-gate 2031*7c478bd9Sstevel@tonic-gate int64_t * 2032*7c478bd9Sstevel@tonic-gate scf_simple_prop_next_time(scf_simple_prop_t *prop, int32_t *nsec) 2033*7c478bd9Sstevel@tonic-gate { 2034*7c478bd9Sstevel@tonic-gate union scf_simple_prop_val *ret; 2035*7c478bd9Sstevel@tonic-gate 2036*7c478bd9Sstevel@tonic-gate ret = scf_next_val(prop, SCF_TYPE_TIME); 2037*7c478bd9Sstevel@tonic-gate 2038*7c478bd9Sstevel@tonic-gate if (ret == NULL) 2039*7c478bd9Sstevel@tonic-gate return (NULL); 2040*7c478bd9Sstevel@tonic-gate 2041*7c478bd9Sstevel@tonic-gate if (nsec != NULL) 2042*7c478bd9Sstevel@tonic-gate *nsec = ret->pv_time.t_nsec; 2043*7c478bd9Sstevel@tonic-gate 2044*7c478bd9Sstevel@tonic-gate return (&ret->pv_time.t_sec); 2045*7c478bd9Sstevel@tonic-gate } 2046*7c478bd9Sstevel@tonic-gate 2047*7c478bd9Sstevel@tonic-gate char * 2048*7c478bd9Sstevel@tonic-gate scf_simple_prop_next_astring(scf_simple_prop_t *prop) 2049*7c478bd9Sstevel@tonic-gate { 2050*7c478bd9Sstevel@tonic-gate union scf_simple_prop_val *ret; 2051*7c478bd9Sstevel@tonic-gate 2052*7c478bd9Sstevel@tonic-gate ret = scf_next_val(prop, SCF_TYPE_ASTRING); 2053*7c478bd9Sstevel@tonic-gate 2054*7c478bd9Sstevel@tonic-gate if (ret == NULL) 2055*7c478bd9Sstevel@tonic-gate return (NULL); 2056*7c478bd9Sstevel@tonic-gate 2057*7c478bd9Sstevel@tonic-gate return (ret->pv_str); 2058*7c478bd9Sstevel@tonic-gate } 2059*7c478bd9Sstevel@tonic-gate 2060*7c478bd9Sstevel@tonic-gate char * 2061*7c478bd9Sstevel@tonic-gate scf_simple_prop_next_ustring(scf_simple_prop_t *prop) 2062*7c478bd9Sstevel@tonic-gate { 2063*7c478bd9Sstevel@tonic-gate union scf_simple_prop_val *ret; 2064*7c478bd9Sstevel@tonic-gate 2065*7c478bd9Sstevel@tonic-gate ret = scf_next_val(prop, SCF_TYPE_USTRING); 2066*7c478bd9Sstevel@tonic-gate 2067*7c478bd9Sstevel@tonic-gate if (ret == NULL) 2068*7c478bd9Sstevel@tonic-gate return (NULL); 2069*7c478bd9Sstevel@tonic-gate 2070*7c478bd9Sstevel@tonic-gate return (ret->pv_str); 2071*7c478bd9Sstevel@tonic-gate } 2072*7c478bd9Sstevel@tonic-gate 2073*7c478bd9Sstevel@tonic-gate void * 2074*7c478bd9Sstevel@tonic-gate scf_simple_prop_next_opaque(scf_simple_prop_t *prop, size_t *length) 2075*7c478bd9Sstevel@tonic-gate { 2076*7c478bd9Sstevel@tonic-gate union scf_simple_prop_val *ret; 2077*7c478bd9Sstevel@tonic-gate 2078*7c478bd9Sstevel@tonic-gate ret = scf_next_val(prop, SCF_TYPE_OPAQUE); 2079*7c478bd9Sstevel@tonic-gate 2080*7c478bd9Sstevel@tonic-gate if (ret == NULL) { 2081*7c478bd9Sstevel@tonic-gate *length = 0; 2082*7c478bd9Sstevel@tonic-gate return (NULL); 2083*7c478bd9Sstevel@tonic-gate } 2084*7c478bd9Sstevel@tonic-gate 2085*7c478bd9Sstevel@tonic-gate *length = ret->pv_opaque.o_size; 2086*7c478bd9Sstevel@tonic-gate return (ret->pv_opaque.o_value); 2087*7c478bd9Sstevel@tonic-gate } 2088