1*7887SLiane.Praza@Sun.COM /* 2*7887SLiane.Praza@Sun.COM * CDDL HEADER START 3*7887SLiane.Praza@Sun.COM * 4*7887SLiane.Praza@Sun.COM * The contents of this file are subject to the terms of the 5*7887SLiane.Praza@Sun.COM * Common Development and Distribution License (the "License"). 6*7887SLiane.Praza@Sun.COM * You may not use this file except in compliance with the License. 7*7887SLiane.Praza@Sun.COM * 8*7887SLiane.Praza@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7887SLiane.Praza@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*7887SLiane.Praza@Sun.COM * See the License for the specific language governing permissions 11*7887SLiane.Praza@Sun.COM * and limitations under the License. 12*7887SLiane.Praza@Sun.COM * 13*7887SLiane.Praza@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*7887SLiane.Praza@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7887SLiane.Praza@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*7887SLiane.Praza@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*7887SLiane.Praza@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*7887SLiane.Praza@Sun.COM * 19*7887SLiane.Praza@Sun.COM * CDDL HEADER END 20*7887SLiane.Praza@Sun.COM */ 21*7887SLiane.Praza@Sun.COM /* 22*7887SLiane.Praza@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*7887SLiane.Praza@Sun.COM * Use is subject to license terms. 24*7887SLiane.Praza@Sun.COM */ 25*7887SLiane.Praza@Sun.COM 26*7887SLiane.Praza@Sun.COM /* 27*7887SLiane.Praza@Sun.COM * scf_tmpl.c 28*7887SLiane.Praza@Sun.COM * 29*7887SLiane.Praza@Sun.COM * This file implements the bulk of the libscf templates interfaces. 30*7887SLiane.Praza@Sun.COM * Templates describe metadata about a service or instance in general, 31*7887SLiane.Praza@Sun.COM * and individual configuration properties on those services and instances. 32*7887SLiane.Praza@Sun.COM * Human-consumable descriptions can be provided, along with definitions 33*7887SLiane.Praza@Sun.COM * of valid configuration. See service_bundle.dtd.1 for XML definitions 34*7887SLiane.Praza@Sun.COM * of templates, and the svccfg code for information on how those definitions 35*7887SLiane.Praza@Sun.COM * are translated into the repository. 36*7887SLiane.Praza@Sun.COM * 37*7887SLiane.Praza@Sun.COM * The main data structures are scf_pg_tmpl and scf_prop_tmpl. These 38*7887SLiane.Praza@Sun.COM * are allocated by the callers through scf_tmpl_[pg|prop]_create(), and 39*7887SLiane.Praza@Sun.COM * destroyed with scf_tmpl_[pg|prop]_destroy(). They are populated by 40*7887SLiane.Praza@Sun.COM * scf_tmpl_get_by_pg_name(), scf_tmpl_get_by_pg(), and 41*7887SLiane.Praza@Sun.COM * scf_tmpl_get_by_prop(). They also store the iterator state for 42*7887SLiane.Praza@Sun.COM * scf_tmpl_iter_pgs() and scf_tmpl_iter_props(). 43*7887SLiane.Praza@Sun.COM * 44*7887SLiane.Praza@Sun.COM * These data structures are then consumed by other functions to 45*7887SLiane.Praza@Sun.COM * gather information about the template (e.g. name, description, 46*7887SLiane.Praza@Sun.COM * choices, constraints, etc.). 47*7887SLiane.Praza@Sun.COM * 48*7887SLiane.Praza@Sun.COM * scf_tmpl_validate_fmri() does instance validation against template 49*7887SLiane.Praza@Sun.COM * data, and populates a set of template errors which can be explored using 50*7887SLiane.Praza@Sun.COM * the scf_tmpl_next_error() and the scf_tmpl_error*() suite of functions. 51*7887SLiane.Praza@Sun.COM * 52*7887SLiane.Praza@Sun.COM * The main data structures for template errors are scf_tmpl_errors, 53*7887SLiane.Praza@Sun.COM * defined in this file, and scf_tmpl_error, defined in libscf_priv.h. 54*7887SLiane.Praza@Sun.COM * scf_tmpl_error is shared with svccfg to offer common printing 55*7887SLiane.Praza@Sun.COM * of error messages between libscf and svccfg. 56*7887SLiane.Praza@Sun.COM * 57*7887SLiane.Praza@Sun.COM * General convenience functions are towards the top of this file, 58*7887SLiane.Praza@Sun.COM * followed by pg and prop template discovery functions, followed 59*7887SLiane.Praza@Sun.COM * by functions which gather information about the discovered 60*7887SLiane.Praza@Sun.COM * template. Validation and error functions are at the end of this file. 61*7887SLiane.Praza@Sun.COM */ 62*7887SLiane.Praza@Sun.COM 63*7887SLiane.Praza@Sun.COM #include "lowlevel_impl.h" 64*7887SLiane.Praza@Sun.COM #include "libscf_impl.h" 65*7887SLiane.Praza@Sun.COM #include <assert.h> 66*7887SLiane.Praza@Sun.COM #include <errno.h> 67*7887SLiane.Praza@Sun.COM #include <libintl.h> 68*7887SLiane.Praza@Sun.COM #include <stdlib.h> 69*7887SLiane.Praza@Sun.COM #include <stdio.h> 70*7887SLiane.Praza@Sun.COM #include <strings.h> 71*7887SLiane.Praza@Sun.COM #include <locale.h> 72*7887SLiane.Praza@Sun.COM #include <ctype.h> 73*7887SLiane.Praza@Sun.COM #include <inttypes.h> 74*7887SLiane.Praza@Sun.COM 75*7887SLiane.Praza@Sun.COM #define SCF_TMPL_PG_COMMON_NAME_C "common_name_C" 76*7887SLiane.Praza@Sun.COM 77*7887SLiane.Praza@Sun.COM #define SCF__TMPL_ITER_NONE 0 78*7887SLiane.Praza@Sun.COM #define SCF__TMPL_ITER_INST 1 79*7887SLiane.Praza@Sun.COM #define SCF__TMPL_ITER_RESTARTER 2 80*7887SLiane.Praza@Sun.COM #define SCF__TMPL_ITER_GLOBAL 3 81*7887SLiane.Praza@Sun.COM 82*7887SLiane.Praza@Sun.COM #define SCF_TMPL_PG_NT 0 83*7887SLiane.Praza@Sun.COM #define SCF_TMPL_PG_N 1 84*7887SLiane.Praza@Sun.COM #define SCF_TMPL_PG_T 2 85*7887SLiane.Praza@Sun.COM #define SCF_TMPL_PG_WILD 3 86*7887SLiane.Praza@Sun.COM 87*7887SLiane.Praza@Sun.COM struct scf_pg_tmpl { 88*7887SLiane.Praza@Sun.COM int pt_populated; 89*7887SLiane.Praza@Sun.COM scf_handle_t *pt_h; 90*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pt_pg; 91*7887SLiane.Praza@Sun.COM scf_service_t *pt_orig_svc; 92*7887SLiane.Praza@Sun.COM scf_service_t *pt_svc; 93*7887SLiane.Praza@Sun.COM scf_instance_t *pt_orig_inst; 94*7887SLiane.Praza@Sun.COM scf_instance_t *pt_inst; 95*7887SLiane.Praza@Sun.COM scf_snapshot_t *pt_snap; 96*7887SLiane.Praza@Sun.COM int pt_is_iter; 97*7887SLiane.Praza@Sun.COM scf_iter_t *pt_iter; 98*7887SLiane.Praza@Sun.COM int pt_iter_last; 99*7887SLiane.Praza@Sun.COM }; 100*7887SLiane.Praza@Sun.COM 101*7887SLiane.Praza@Sun.COM #define SCF_WALK_ERROR -1 102*7887SLiane.Praza@Sun.COM #define SCF_WALK_NEXT 0 103*7887SLiane.Praza@Sun.COM #define SCF_WALK_DONE 1 104*7887SLiane.Praza@Sun.COM 105*7887SLiane.Praza@Sun.COM struct pg_tmpl_walk { 106*7887SLiane.Praza@Sun.COM const char *pw_snapname; 107*7887SLiane.Praza@Sun.COM const char *pw_pgname; 108*7887SLiane.Praza@Sun.COM const char *pw_pgtype; 109*7887SLiane.Praza@Sun.COM scf_instance_t *pw_inst; 110*7887SLiane.Praza@Sun.COM scf_service_t *pw_svc; 111*7887SLiane.Praza@Sun.COM scf_snapshot_t *pw_snap; 112*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pw_pg; 113*7887SLiane.Praza@Sun.COM const char *pw_target; 114*7887SLiane.Praza@Sun.COM char *pw_tmpl_pgname; 115*7887SLiane.Praza@Sun.COM }; 116*7887SLiane.Praza@Sun.COM 117*7887SLiane.Praza@Sun.COM typedef struct pg_tmpl_walk pg_tmpl_walk_t; 118*7887SLiane.Praza@Sun.COM 119*7887SLiane.Praza@Sun.COM typedef int walk_template_inst_func_t(scf_service_t *_svc, 120*7887SLiane.Praza@Sun.COM scf_instance_t *_inst, pg_tmpl_walk_t *p); 121*7887SLiane.Praza@Sun.COM 122*7887SLiane.Praza@Sun.COM struct scf_prop_tmpl { 123*7887SLiane.Praza@Sun.COM int prt_populated; 124*7887SLiane.Praza@Sun.COM scf_handle_t *prt_h; 125*7887SLiane.Praza@Sun.COM scf_pg_tmpl_t *prt_t; 126*7887SLiane.Praza@Sun.COM scf_propertygroup_t *prt_pg; 127*7887SLiane.Praza@Sun.COM char *prt_pg_name; 128*7887SLiane.Praza@Sun.COM scf_iter_t *prt_iter; 129*7887SLiane.Praza@Sun.COM }; 130*7887SLiane.Praza@Sun.COM 131*7887SLiane.Praza@Sun.COM /* 132*7887SLiane.Praza@Sun.COM * Common server errors are usually passed back to the caller. This 133*7887SLiane.Praza@Sun.COM * array defines them centrally so that they don't need to be enumerated 134*7887SLiane.Praza@Sun.COM * in every libscf call. 135*7887SLiane.Praza@Sun.COM */ 136*7887SLiane.Praza@Sun.COM static const scf_error_t errors_server[] = { 137*7887SLiane.Praza@Sun.COM SCF_ERROR_BACKEND_ACCESS, 138*7887SLiane.Praza@Sun.COM SCF_ERROR_CONNECTION_BROKEN, 139*7887SLiane.Praza@Sun.COM SCF_ERROR_DELETED, 140*7887SLiane.Praza@Sun.COM SCF_ERROR_HANDLE_DESTROYED, 141*7887SLiane.Praza@Sun.COM SCF_ERROR_INTERNAL, 142*7887SLiane.Praza@Sun.COM SCF_ERROR_NO_MEMORY, 143*7887SLiane.Praza@Sun.COM SCF_ERROR_NO_RESOURCES, 144*7887SLiane.Praza@Sun.COM SCF_ERROR_NOT_BOUND, 145*7887SLiane.Praza@Sun.COM SCF_ERROR_PERMISSION_DENIED, 146*7887SLiane.Praza@Sun.COM 0 147*7887SLiane.Praza@Sun.COM }; 148*7887SLiane.Praza@Sun.COM 149*7887SLiane.Praza@Sun.COM /* 150*7887SLiane.Praza@Sun.COM * int ismember() 151*7887SLiane.Praza@Sun.COM * 152*7887SLiane.Praza@Sun.COM * Returns 1 if the supplied error is a member of the error array, 0 153*7887SLiane.Praza@Sun.COM * if it is not. 154*7887SLiane.Praza@Sun.COM */ 155*7887SLiane.Praza@Sun.COM static scf_error_t 156*7887SLiane.Praza@Sun.COM ismember(const int error, const scf_error_t error_array[]) 157*7887SLiane.Praza@Sun.COM { 158*7887SLiane.Praza@Sun.COM int i; 159*7887SLiane.Praza@Sun.COM 160*7887SLiane.Praza@Sun.COM for (i = 0; error_array[i] != 0; ++i) { 161*7887SLiane.Praza@Sun.COM if (error == error_array[i]) 162*7887SLiane.Praza@Sun.COM return (1); 163*7887SLiane.Praza@Sun.COM } 164*7887SLiane.Praza@Sun.COM 165*7887SLiane.Praza@Sun.COM return (0); 166*7887SLiane.Praza@Sun.COM } 167*7887SLiane.Praza@Sun.COM 168*7887SLiane.Praza@Sun.COM /* 169*7887SLiane.Praza@Sun.COM * char *_scf_tmpl_get_fmri() 170*7887SLiane.Praza@Sun.COM * 171*7887SLiane.Praza@Sun.COM * Given a pg_tmpl, returns the FMRI of the service or instance that 172*7887SLiane.Praza@Sun.COM * template describes. The allocated string must be freed with free(). 173*7887SLiane.Praza@Sun.COM * 174*7887SLiane.Praza@Sun.COM * On failure, returns NULL and sets scf_error() to _CONNECTION_BROKEN, 175*7887SLiane.Praza@Sun.COM * _DELETED, or _NO_MEMORY. 176*7887SLiane.Praza@Sun.COM */ 177*7887SLiane.Praza@Sun.COM static char * 178*7887SLiane.Praza@Sun.COM _scf_tmpl_get_fmri(const scf_pg_tmpl_t *t) 179*7887SLiane.Praza@Sun.COM { 180*7887SLiane.Praza@Sun.COM ssize_t sz = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH) + 1; 181*7887SLiane.Praza@Sun.COM int r; 182*7887SLiane.Praza@Sun.COM char *buf = malloc(sz); 183*7887SLiane.Praza@Sun.COM 184*7887SLiane.Praza@Sun.COM assert(t->pt_svc != NULL || t->pt_inst != NULL); 185*7887SLiane.Praza@Sun.COM assert(t->pt_svc == NULL || t->pt_inst == NULL); 186*7887SLiane.Praza@Sun.COM 187*7887SLiane.Praza@Sun.COM if (buf == NULL) { 188*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 189*7887SLiane.Praza@Sun.COM return (buf); 190*7887SLiane.Praza@Sun.COM } 191*7887SLiane.Praza@Sun.COM 192*7887SLiane.Praza@Sun.COM if (t->pt_inst != NULL) 193*7887SLiane.Praza@Sun.COM r = scf_instance_to_fmri(t->pt_inst, buf, sz); 194*7887SLiane.Praza@Sun.COM else 195*7887SLiane.Praza@Sun.COM r = scf_service_to_fmri(t->pt_svc, buf, sz); 196*7887SLiane.Praza@Sun.COM 197*7887SLiane.Praza@Sun.COM if (r == -1) { 198*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 199*7887SLiane.Praza@Sun.COM free(buf); 200*7887SLiane.Praza@Sun.COM buf = NULL; 201*7887SLiane.Praza@Sun.COM } else { 202*7887SLiane.Praza@Sun.COM assert(0); 203*7887SLiane.Praza@Sun.COM abort(); 204*7887SLiane.Praza@Sun.COM } 205*7887SLiane.Praza@Sun.COM } 206*7887SLiane.Praza@Sun.COM 207*7887SLiane.Praza@Sun.COM return (buf); 208*7887SLiane.Praza@Sun.COM } 209*7887SLiane.Praza@Sun.COM 210*7887SLiane.Praza@Sun.COM /* 211*7887SLiane.Praza@Sun.COM * char *_scf_get_pg_type() 212*7887SLiane.Praza@Sun.COM * 213*7887SLiane.Praza@Sun.COM * Given a propertygroup, returns an allocated string containing the 214*7887SLiane.Praza@Sun.COM * type. The string must be freed with free(). 215*7887SLiane.Praza@Sun.COM * 216*7887SLiane.Praza@Sun.COM * On failure, returns NULL and sets scf_error() to: _CONNECTION_BROKEN, 217*7887SLiane.Praza@Sun.COM * _DELETED, or _NO_MEMORY. 218*7887SLiane.Praza@Sun.COM */ 219*7887SLiane.Praza@Sun.COM static char * 220*7887SLiane.Praza@Sun.COM _scf_get_pg_type(scf_propertygroup_t *pg) 221*7887SLiane.Praza@Sun.COM { 222*7887SLiane.Praza@Sun.COM ssize_t sz = scf_limit(SCF_LIMIT_MAX_PG_TYPE_LENGTH) + 1; 223*7887SLiane.Praza@Sun.COM char *buf = malloc(sz); 224*7887SLiane.Praza@Sun.COM 225*7887SLiane.Praza@Sun.COM if (buf == NULL) { 226*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 227*7887SLiane.Praza@Sun.COM } else if (scf_pg_get_type(pg, buf, sz) == -1) { 228*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 229*7887SLiane.Praza@Sun.COM free(buf); 230*7887SLiane.Praza@Sun.COM buf = NULL; 231*7887SLiane.Praza@Sun.COM } else { 232*7887SLiane.Praza@Sun.COM assert(0); 233*7887SLiane.Praza@Sun.COM abort(); 234*7887SLiane.Praza@Sun.COM } 235*7887SLiane.Praza@Sun.COM } 236*7887SLiane.Praza@Sun.COM 237*7887SLiane.Praza@Sun.COM return (buf); 238*7887SLiane.Praza@Sun.COM } 239*7887SLiane.Praza@Sun.COM 240*7887SLiane.Praza@Sun.COM /* 241*7887SLiane.Praza@Sun.COM * char *_scf_get_prop_name() 242*7887SLiane.Praza@Sun.COM * 243*7887SLiane.Praza@Sun.COM * Given a property, returns the name in an allocated string. The string must 244*7887SLiane.Praza@Sun.COM * be freed with free(). 245*7887SLiane.Praza@Sun.COM * 246*7887SLiane.Praza@Sun.COM * On error, returns NULL and sets scf_error() to _CONNECTION_BROKEN, 247*7887SLiane.Praza@Sun.COM * _DELETED, or _NO_MEMORY. 248*7887SLiane.Praza@Sun.COM */ 249*7887SLiane.Praza@Sun.COM static char * 250*7887SLiane.Praza@Sun.COM _scf_get_prop_name(scf_property_t *prop) 251*7887SLiane.Praza@Sun.COM { 252*7887SLiane.Praza@Sun.COM ssize_t sz = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 253*7887SLiane.Praza@Sun.COM char *buf = malloc(sz); 254*7887SLiane.Praza@Sun.COM 255*7887SLiane.Praza@Sun.COM if (buf == NULL) { 256*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 257*7887SLiane.Praza@Sun.COM } else if (scf_property_get_name(prop, buf, sz) == -1) { 258*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 259*7887SLiane.Praza@Sun.COM free(buf); 260*7887SLiane.Praza@Sun.COM buf = NULL; 261*7887SLiane.Praza@Sun.COM } else { 262*7887SLiane.Praza@Sun.COM assert(0); 263*7887SLiane.Praza@Sun.COM abort(); 264*7887SLiane.Praza@Sun.COM } 265*7887SLiane.Praza@Sun.COM } 266*7887SLiane.Praza@Sun.COM 267*7887SLiane.Praza@Sun.COM return (buf); 268*7887SLiane.Praza@Sun.COM } 269*7887SLiane.Praza@Sun.COM 270*7887SLiane.Praza@Sun.COM /* 271*7887SLiane.Praza@Sun.COM * char *_scf_get_prop_type() 272*7887SLiane.Praza@Sun.COM * 273*7887SLiane.Praza@Sun.COM * Given a property, returns the type in an allocated string. The string must 274*7887SLiane.Praza@Sun.COM * be freed with free(). 275*7887SLiane.Praza@Sun.COM * 276*7887SLiane.Praza@Sun.COM * On error, returns NULL and sets scf_error() to _CONNECTION_BROKEN, 277*7887SLiane.Praza@Sun.COM * _DELETED, or _NO_MEMORY. 278*7887SLiane.Praza@Sun.COM */ 279*7887SLiane.Praza@Sun.COM static char * 280*7887SLiane.Praza@Sun.COM _scf_get_prop_type(scf_property_t *prop) 281*7887SLiane.Praza@Sun.COM { 282*7887SLiane.Praza@Sun.COM scf_type_t type; 283*7887SLiane.Praza@Sun.COM char *ret; 284*7887SLiane.Praza@Sun.COM 285*7887SLiane.Praza@Sun.COM if (scf_property_type(prop, &type) == -1) { 286*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 287*7887SLiane.Praza@Sun.COM return (NULL); 288*7887SLiane.Praza@Sun.COM } else { 289*7887SLiane.Praza@Sun.COM assert(0); 290*7887SLiane.Praza@Sun.COM abort(); 291*7887SLiane.Praza@Sun.COM } 292*7887SLiane.Praza@Sun.COM } 293*7887SLiane.Praza@Sun.COM 294*7887SLiane.Praza@Sun.COM ret = strdup(scf_type_to_string(type)); 295*7887SLiane.Praza@Sun.COM if (ret == NULL) 296*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 297*7887SLiane.Praza@Sun.COM 298*7887SLiane.Praza@Sun.COM return (ret); 299*7887SLiane.Praza@Sun.COM } 300*7887SLiane.Praza@Sun.COM 301*7887SLiane.Praza@Sun.COM /* 302*7887SLiane.Praza@Sun.COM * int _read_single_value_from_pg() 303*7887SLiane.Praza@Sun.COM * 304*7887SLiane.Praza@Sun.COM * Reads a single value from the pg and property name specified. On success, 305*7887SLiane.Praza@Sun.COM * returns an allocated value that must be freed. 306*7887SLiane.Praza@Sun.COM * 307*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 308*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 309*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 310*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 311*7887SLiane.Praza@Sun.COM * Property has more than one value associated with it. 312*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 313*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 314*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 315*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 316*7887SLiane.Praza@Sun.COM * prop_name not a valid property name. 317*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 318*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 319*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 320*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 321*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 322*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_SET 323*7887SLiane.Praza@Sun.COM * Property group specified by pg is not set. 324*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 325*7887SLiane.Praza@Sun.COM */ 326*7887SLiane.Praza@Sun.COM static int 327*7887SLiane.Praza@Sun.COM _read_single_value_from_pg(scf_propertygroup_t *pg, const char *prop_name, 328*7887SLiane.Praza@Sun.COM scf_value_t **val) 329*7887SLiane.Praza@Sun.COM { 330*7887SLiane.Praza@Sun.COM scf_handle_t *h; 331*7887SLiane.Praza@Sun.COM scf_property_t *prop; 332*7887SLiane.Praza@Sun.COM int ret = 0; 333*7887SLiane.Praza@Sun.COM 334*7887SLiane.Praza@Sun.COM assert(val != NULL); 335*7887SLiane.Praza@Sun.COM if ((h = scf_pg_handle(pg)) == NULL) { 336*7887SLiane.Praza@Sun.COM assert(scf_error() == SCF_ERROR_HANDLE_DESTROYED); 337*7887SLiane.Praza@Sun.COM return (-1); 338*7887SLiane.Praza@Sun.COM } 339*7887SLiane.Praza@Sun.COM 340*7887SLiane.Praza@Sun.COM prop = scf_property_create(h); 341*7887SLiane.Praza@Sun.COM *val = scf_value_create(h); 342*7887SLiane.Praza@Sun.COM 343*7887SLiane.Praza@Sun.COM if (prop == NULL || *val == NULL) { 344*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 345*7887SLiane.Praza@Sun.COM goto read_single_value_from_pg_fail; 346*7887SLiane.Praza@Sun.COM } 347*7887SLiane.Praza@Sun.COM 348*7887SLiane.Praza@Sun.COM if (scf_pg_get_property(pg, prop_name, prop) != 0) { 349*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_HANDLE_MISMATCH); 350*7887SLiane.Praza@Sun.COM goto read_single_value_from_pg_fail; 351*7887SLiane.Praza@Sun.COM } 352*7887SLiane.Praza@Sun.COM 353*7887SLiane.Praza@Sun.COM if (scf_property_get_value(prop, *val) == -1) { 354*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 355*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_HANDLE_MISMATCH); 356*7887SLiane.Praza@Sun.COM goto read_single_value_from_pg_fail; 357*7887SLiane.Praza@Sun.COM } 358*7887SLiane.Praza@Sun.COM 359*7887SLiane.Praza@Sun.COM goto read_single_value_from_pg_done; 360*7887SLiane.Praza@Sun.COM 361*7887SLiane.Praza@Sun.COM read_single_value_from_pg_fail: 362*7887SLiane.Praza@Sun.COM scf_value_destroy(*val); 363*7887SLiane.Praza@Sun.COM *val = NULL; 364*7887SLiane.Praza@Sun.COM ret = -1; 365*7887SLiane.Praza@Sun.COM 366*7887SLiane.Praza@Sun.COM read_single_value_from_pg_done: 367*7887SLiane.Praza@Sun.COM scf_property_destroy(prop); 368*7887SLiane.Praza@Sun.COM return (ret); 369*7887SLiane.Praza@Sun.COM } 370*7887SLiane.Praza@Sun.COM 371*7887SLiane.Praza@Sun.COM /* 372*7887SLiane.Praza@Sun.COM * char *_scf_read_single_astring_from_pg() 373*7887SLiane.Praza@Sun.COM * 374*7887SLiane.Praza@Sun.COM * Reads an astring from the pg and property name specified. On success, 375*7887SLiane.Praza@Sun.COM * returns an allocated string. The string must be freed with free(). 376*7887SLiane.Praza@Sun.COM * 377*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to: 378*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 379*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 380*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 381*7887SLiane.Praza@Sun.COM * Property has more than one value associated with it. 382*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 383*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 384*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 385*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 386*7887SLiane.Praza@Sun.COM * prop_name not a valid property name. 387*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 388*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 389*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 390*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 391*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 392*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_SET 393*7887SLiane.Praza@Sun.COM * The property group specified by pg is not set. 394*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 395*7887SLiane.Praza@Sun.COM * SCF_ERROR_TYPE_MISMATCH 396*7887SLiane.Praza@Sun.COM */ 397*7887SLiane.Praza@Sun.COM char * 398*7887SLiane.Praza@Sun.COM _scf_read_single_astring_from_pg(scf_propertygroup_t *pg, const char *prop_name) 399*7887SLiane.Praza@Sun.COM { 400*7887SLiane.Praza@Sun.COM scf_value_t *val; 401*7887SLiane.Praza@Sun.COM char *ret = NULL; 402*7887SLiane.Praza@Sun.COM ssize_t rsize = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH) + 1; 403*7887SLiane.Praza@Sun.COM 404*7887SLiane.Praza@Sun.COM assert(rsize != 0); 405*7887SLiane.Praza@Sun.COM if (_read_single_value_from_pg(pg, prop_name, &val) == -1) 406*7887SLiane.Praza@Sun.COM return (NULL); 407*7887SLiane.Praza@Sun.COM 408*7887SLiane.Praza@Sun.COM ret = malloc(rsize); 409*7887SLiane.Praza@Sun.COM if (ret == NULL) { 410*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 411*7887SLiane.Praza@Sun.COM goto cleanup; 412*7887SLiane.Praza@Sun.COM } 413*7887SLiane.Praza@Sun.COM 414*7887SLiane.Praza@Sun.COM if (scf_value_get_astring(val, ret, rsize) < 0) { 415*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 416*7887SLiane.Praza@Sun.COM free(ret); 417*7887SLiane.Praza@Sun.COM ret = NULL; 418*7887SLiane.Praza@Sun.COM } 419*7887SLiane.Praza@Sun.COM 420*7887SLiane.Praza@Sun.COM cleanup: 421*7887SLiane.Praza@Sun.COM scf_value_destroy(val); 422*7887SLiane.Praza@Sun.COM return (ret); 423*7887SLiane.Praza@Sun.COM } 424*7887SLiane.Praza@Sun.COM 425*7887SLiane.Praza@Sun.COM /* 426*7887SLiane.Praza@Sun.COM * char *_scf_read_tmpl_prop_type_as_string() 427*7887SLiane.Praza@Sun.COM * 428*7887SLiane.Praza@Sun.COM * Reads the property type and returns it as an allocated string. The string 429*7887SLiane.Praza@Sun.COM * must be freed with free(). 430*7887SLiane.Praza@Sun.COM * 431*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to _BACKEND_ACCESS, 432*7887SLiane.Praza@Sun.COM * _CONNECTION_BROKEN, _DELETED, _HANDLE_DESTROYED, _INTERNAL, _NO_MEMORY, 433*7887SLiane.Praza@Sun.COM * _NO_RESOURCES, _NOT_BOUND, _PERMISSION_DENIED, or _TEMPLATE_INVALID. 434*7887SLiane.Praza@Sun.COM */ 435*7887SLiane.Praza@Sun.COM char * 436*7887SLiane.Praza@Sun.COM _scf_read_tmpl_prop_type_as_string(const scf_prop_tmpl_t *pt) 437*7887SLiane.Praza@Sun.COM { 438*7887SLiane.Praza@Sun.COM char *type; 439*7887SLiane.Praza@Sun.COM 440*7887SLiane.Praza@Sun.COM type = _scf_read_single_astring_from_pg(pt->prt_pg, 441*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_TYPE); 442*7887SLiane.Praza@Sun.COM if (type == NULL) { 443*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 444*7887SLiane.Praza@Sun.COM return (NULL); 445*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 446*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 447*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 448*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 449*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 450*7887SLiane.Praza@Sun.COM return (NULL); 451*7887SLiane.Praza@Sun.COM 452*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 453*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 454*7887SLiane.Praza@Sun.COM default: 455*7887SLiane.Praza@Sun.COM assert(0); 456*7887SLiane.Praza@Sun.COM abort(); 457*7887SLiane.Praza@Sun.COM } 458*7887SLiane.Praza@Sun.COM } 459*7887SLiane.Praza@Sun.COM 460*7887SLiane.Praza@Sun.COM return (type); 461*7887SLiane.Praza@Sun.COM } 462*7887SLiane.Praza@Sun.COM 463*7887SLiane.Praza@Sun.COM /* 464*7887SLiane.Praza@Sun.COM * int _read_single_boolean_from_pg() 465*7887SLiane.Praza@Sun.COM * 466*7887SLiane.Praza@Sun.COM * Reads a boolean from the pg and property name specified. 467*7887SLiane.Praza@Sun.COM * 468*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 469*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 470*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 471*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 472*7887SLiane.Praza@Sun.COM * Property has more than one value associated with it. 473*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 474*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 475*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 476*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 477*7887SLiane.Praza@Sun.COM * prop_name is not a valid property name. 478*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 479*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 480*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 481*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 482*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 483*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_SET 484*7887SLiane.Praza@Sun.COM * The property group specified by pg is not set. 485*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 486*7887SLiane.Praza@Sun.COM * SCF_ERROR_TYPE_MISMATCH 487*7887SLiane.Praza@Sun.COM */ 488*7887SLiane.Praza@Sun.COM static int 489*7887SLiane.Praza@Sun.COM _read_single_boolean_from_pg(scf_propertygroup_t *pg, const char *prop_name, 490*7887SLiane.Praza@Sun.COM uint8_t *bool) 491*7887SLiane.Praza@Sun.COM { 492*7887SLiane.Praza@Sun.COM scf_value_t *val; 493*7887SLiane.Praza@Sun.COM int ret = 0; 494*7887SLiane.Praza@Sun.COM 495*7887SLiane.Praza@Sun.COM if (_read_single_value_from_pg(pg, prop_name, &val) == -1) 496*7887SLiane.Praza@Sun.COM return (-1); 497*7887SLiane.Praza@Sun.COM 498*7887SLiane.Praza@Sun.COM if (scf_value_get_boolean(val, bool) < 0) { 499*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 500*7887SLiane.Praza@Sun.COM ret = -1; 501*7887SLiane.Praza@Sun.COM } 502*7887SLiane.Praza@Sun.COM 503*7887SLiane.Praza@Sun.COM scf_value_destroy(val); 504*7887SLiane.Praza@Sun.COM return (ret); 505*7887SLiane.Praza@Sun.COM } 506*7887SLiane.Praza@Sun.COM 507*7887SLiane.Praza@Sun.COM /* 508*7887SLiane.Praza@Sun.COM * char **_append_astrings_values() 509*7887SLiane.Praza@Sun.COM * 510*7887SLiane.Praza@Sun.COM * This function reads the values from the property prop_name in pg and 511*7887SLiane.Praza@Sun.COM * appends to an existing scf_values_t *vals. vals may be empty, but 512*7887SLiane.Praza@Sun.COM * must exist. The function skips over zero-length and duplicate values. 513*7887SLiane.Praza@Sun.COM * 514*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to: 515*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 516*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 517*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 518*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 519*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 520*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 521*7887SLiane.Praza@Sun.COM * prop_name is not a valid property name. 522*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 523*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 524*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 525*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 526*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_SET 527*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 528*7887SLiane.Praza@Sun.COM * SCF_ERROR_TYPE_MISMATCH 529*7887SLiane.Praza@Sun.COM */ 530*7887SLiane.Praza@Sun.COM static char ** 531*7887SLiane.Praza@Sun.COM _append_astrings_values(scf_propertygroup_t *pg, const char *prop_name, 532*7887SLiane.Praza@Sun.COM scf_values_t *vals) 533*7887SLiane.Praza@Sun.COM { 534*7887SLiane.Praza@Sun.COM scf_handle_t *h; 535*7887SLiane.Praza@Sun.COM scf_property_t *prop; 536*7887SLiane.Praza@Sun.COM scf_value_t *val; 537*7887SLiane.Praza@Sun.COM scf_iter_t *iter; 538*7887SLiane.Praza@Sun.COM ssize_t rsize = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH) + 1; 539*7887SLiane.Praza@Sun.COM int err, count, cursz, i; 540*7887SLiane.Praza@Sun.COM 541*7887SLiane.Praza@Sun.COM assert(vals != NULL); 542*7887SLiane.Praza@Sun.COM assert(vals->value_type == SCF_TYPE_ASTRING); 543*7887SLiane.Praza@Sun.COM assert(vals->reserved == NULL); 544*7887SLiane.Praza@Sun.COM count = vals->value_count; 545*7887SLiane.Praza@Sun.COM if (count == 0) { 546*7887SLiane.Praza@Sun.COM cursz = 8; 547*7887SLiane.Praza@Sun.COM vals->values.v_astring = calloc(cursz, sizeof (char *)); 548*7887SLiane.Praza@Sun.COM if (vals->values.v_astring == NULL) { 549*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 550*7887SLiane.Praza@Sun.COM return (NULL); 551*7887SLiane.Praza@Sun.COM } 552*7887SLiane.Praza@Sun.COM } else { 553*7887SLiane.Praza@Sun.COM /* 554*7887SLiane.Praza@Sun.COM * The array may be bigger, but it is irrelevant since 555*7887SLiane.Praza@Sun.COM * we will always re-allocate a new one. 556*7887SLiane.Praza@Sun.COM */ 557*7887SLiane.Praza@Sun.COM cursz = count; 558*7887SLiane.Praza@Sun.COM } 559*7887SLiane.Praza@Sun.COM 560*7887SLiane.Praza@Sun.COM if ((h = scf_pg_handle(pg)) == NULL) { 561*7887SLiane.Praza@Sun.COM assert(scf_error() == SCF_ERROR_HANDLE_DESTROYED); 562*7887SLiane.Praza@Sun.COM return (NULL); 563*7887SLiane.Praza@Sun.COM } 564*7887SLiane.Praza@Sun.COM 565*7887SLiane.Praza@Sun.COM prop = scf_property_create(h); 566*7887SLiane.Praza@Sun.COM val = scf_value_create(h); 567*7887SLiane.Praza@Sun.COM iter = scf_iter_create(h); 568*7887SLiane.Praza@Sun.COM 569*7887SLiane.Praza@Sun.COM if (prop == NULL || val == NULL || iter == NULL) { 570*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 571*7887SLiane.Praza@Sun.COM goto append_single_astring_from_pg_fail; 572*7887SLiane.Praza@Sun.COM } 573*7887SLiane.Praza@Sun.COM 574*7887SLiane.Praza@Sun.COM if (scf_pg_get_property(pg, prop_name, prop) != 0) { 575*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_HANDLE_MISMATCH); 576*7887SLiane.Praza@Sun.COM goto append_single_astring_from_pg_fail; 577*7887SLiane.Praza@Sun.COM } 578*7887SLiane.Praza@Sun.COM 579*7887SLiane.Praza@Sun.COM if (scf_iter_property_values(iter, prop) != 0) { 580*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 581*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_HANDLE_MISMATCH); 582*7887SLiane.Praza@Sun.COM goto append_single_astring_from_pg_fail; 583*7887SLiane.Praza@Sun.COM } 584*7887SLiane.Praza@Sun.COM 585*7887SLiane.Praza@Sun.COM while ((err = scf_iter_next_value(iter, val)) == 1) { 586*7887SLiane.Praza@Sun.COM int flag; 587*7887SLiane.Praza@Sun.COM int r; 588*7887SLiane.Praza@Sun.COM 589*7887SLiane.Praza@Sun.COM if (count + 1 >= cursz) { 590*7887SLiane.Praza@Sun.COM void *aux; 591*7887SLiane.Praza@Sun.COM 592*7887SLiane.Praza@Sun.COM cursz *= 2; 593*7887SLiane.Praza@Sun.COM if ((aux = calloc(cursz, sizeof (char *))) == NULL) { 594*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 595*7887SLiane.Praza@Sun.COM goto append_single_astring_from_pg_fail; 596*7887SLiane.Praza@Sun.COM } 597*7887SLiane.Praza@Sun.COM (void) memcpy(aux, vals->values.v_astring, 598*7887SLiane.Praza@Sun.COM count * sizeof (char *)); 599*7887SLiane.Praza@Sun.COM free(vals->values.v_astring); 600*7887SLiane.Praza@Sun.COM vals->values.v_astring = aux; 601*7887SLiane.Praza@Sun.COM } 602*7887SLiane.Praza@Sun.COM 603*7887SLiane.Praza@Sun.COM vals->values.v_astring[count] = malloc(rsize); 604*7887SLiane.Praza@Sun.COM if (vals->values.v_astring[count] == NULL) { 605*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 606*7887SLiane.Praza@Sun.COM goto append_single_astring_from_pg_fail; 607*7887SLiane.Praza@Sun.COM } 608*7887SLiane.Praza@Sun.COM 609*7887SLiane.Praza@Sun.COM if ((r = scf_value_get_astring(val, 610*7887SLiane.Praza@Sun.COM vals->values.v_astring[count], rsize)) <= 0) { 611*7887SLiane.Praza@Sun.COM /* discard zero length strings */ 612*7887SLiane.Praza@Sun.COM if (r == 0) { 613*7887SLiane.Praza@Sun.COM free(vals->values.v_astring[count]); 614*7887SLiane.Praza@Sun.COM continue; 615*7887SLiane.Praza@Sun.COM } 616*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 617*7887SLiane.Praza@Sun.COM goto append_single_astring_from_pg_fail; 618*7887SLiane.Praza@Sun.COM } 619*7887SLiane.Praza@Sun.COM for (i = 0, flag = 0; i < count; ++i) { 620*7887SLiane.Praza@Sun.COM /* find and discard duplicates */ 621*7887SLiane.Praza@Sun.COM if (strncmp(vals->values.v_astring[i], 622*7887SLiane.Praza@Sun.COM vals->values.v_astring[count], rsize) == 0) { 623*7887SLiane.Praza@Sun.COM free(vals->values.v_astring[count]); 624*7887SLiane.Praza@Sun.COM flag = 1; 625*7887SLiane.Praza@Sun.COM break; 626*7887SLiane.Praza@Sun.COM } 627*7887SLiane.Praza@Sun.COM } 628*7887SLiane.Praza@Sun.COM if (flag == 1) 629*7887SLiane.Praza@Sun.COM continue; 630*7887SLiane.Praza@Sun.COM 631*7887SLiane.Praza@Sun.COM count++; 632*7887SLiane.Praza@Sun.COM } 633*7887SLiane.Praza@Sun.COM 634*7887SLiane.Praza@Sun.COM vals->value_count = count; 635*7887SLiane.Praza@Sun.COM 636*7887SLiane.Praza@Sun.COM if (err != 0) { 637*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 638*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 639*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_HANDLE_MISMATCH); 640*7887SLiane.Praza@Sun.COM goto append_single_astring_from_pg_fail; 641*7887SLiane.Praza@Sun.COM } else { 642*7887SLiane.Praza@Sun.COM vals->values_as_strings = vals->values.v_astring; 643*7887SLiane.Praza@Sun.COM } 644*7887SLiane.Praza@Sun.COM 645*7887SLiane.Praza@Sun.COM goto append_single_astring_from_pg_done; 646*7887SLiane.Praza@Sun.COM 647*7887SLiane.Praza@Sun.COM append_single_astring_from_pg_fail: 648*7887SLiane.Praza@Sun.COM for (i = 0; i <= count; ++i) { 649*7887SLiane.Praza@Sun.COM if (vals->values.v_astring[i] != NULL) 650*7887SLiane.Praza@Sun.COM free(vals->values.v_astring[i]); 651*7887SLiane.Praza@Sun.COM vals->values.v_astring[i] = NULL; 652*7887SLiane.Praza@Sun.COM } 653*7887SLiane.Praza@Sun.COM free(vals->values.v_astring); 654*7887SLiane.Praza@Sun.COM vals->values.v_astring = NULL; 655*7887SLiane.Praza@Sun.COM vals->value_count = 0; 656*7887SLiane.Praza@Sun.COM 657*7887SLiane.Praza@Sun.COM append_single_astring_from_pg_done: 658*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 659*7887SLiane.Praza@Sun.COM scf_property_destroy(prop); 660*7887SLiane.Praza@Sun.COM scf_value_destroy(val); 661*7887SLiane.Praza@Sun.COM return (vals->values.v_astring); 662*7887SLiane.Praza@Sun.COM } 663*7887SLiane.Praza@Sun.COM 664*7887SLiane.Praza@Sun.COM /* 665*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to: 666*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 667*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 668*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 669*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 670*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 671*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 672*7887SLiane.Praza@Sun.COM * prop_name is not a valid property name. 673*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 674*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 675*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 676*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 677*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_SET 678*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 679*7887SLiane.Praza@Sun.COM * SCF_ERROR_TYPE_MISMATCH 680*7887SLiane.Praza@Sun.COM */ 681*7887SLiane.Praza@Sun.COM static char ** 682*7887SLiane.Praza@Sun.COM _read_astrings_values(scf_propertygroup_t *pg, const char *prop_name, 683*7887SLiane.Praza@Sun.COM scf_values_t *vals) 684*7887SLiane.Praza@Sun.COM { 685*7887SLiane.Praza@Sun.COM assert(vals != NULL); 686*7887SLiane.Praza@Sun.COM vals->value_count = 0; 687*7887SLiane.Praza@Sun.COM vals->value_type = SCF_TYPE_ASTRING; 688*7887SLiane.Praza@Sun.COM vals->reserved = NULL; 689*7887SLiane.Praza@Sun.COM return (_append_astrings_values(pg, prop_name, vals)); 690*7887SLiane.Praza@Sun.COM } 691*7887SLiane.Praza@Sun.COM 692*7887SLiane.Praza@Sun.COM void 693*7887SLiane.Praza@Sun.COM _scf_sanitize_locale(char *locale) 694*7887SLiane.Praza@Sun.COM { 695*7887SLiane.Praza@Sun.COM for (; *locale != '\0'; locale++) 696*7887SLiane.Praza@Sun.COM if (!isalnum(*locale) && *locale != '_') 697*7887SLiane.Praza@Sun.COM *locale = '_'; 698*7887SLiane.Praza@Sun.COM } 699*7887SLiane.Praza@Sun.COM 700*7887SLiane.Praza@Sun.COM /* 701*7887SLiane.Praza@Sun.COM * The returned string needs to be freed by the caller 702*7887SLiane.Praza@Sun.COM * Returns NULL on failure. Sets scf_error() to: 703*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 704*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 705*7887SLiane.Praza@Sun.COM * Name isn't short enough to add the locale to. 706*7887SLiane.Praza@Sun.COM */ 707*7887SLiane.Praza@Sun.COM static char * 708*7887SLiane.Praza@Sun.COM _add_locale_to_name(const char *name, const char *locale) 709*7887SLiane.Praza@Sun.COM { 710*7887SLiane.Praza@Sun.COM char *lname = NULL; 711*7887SLiane.Praza@Sun.COM ssize_t lsz; 712*7887SLiane.Praza@Sun.COM char *loc; 713*7887SLiane.Praza@Sun.COM 714*7887SLiane.Praza@Sun.COM if (locale == NULL) 715*7887SLiane.Praza@Sun.COM locale = setlocale(LC_MESSAGES, NULL); 716*7887SLiane.Praza@Sun.COM loc = strdup(locale); 717*7887SLiane.Praza@Sun.COM if (loc == NULL) { 718*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 719*7887SLiane.Praza@Sun.COM return (NULL); 720*7887SLiane.Praza@Sun.COM } else { 721*7887SLiane.Praza@Sun.COM _scf_sanitize_locale(loc); 722*7887SLiane.Praza@Sun.COM } 723*7887SLiane.Praza@Sun.COM 724*7887SLiane.Praza@Sun.COM lsz = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 725*7887SLiane.Praza@Sun.COM lname = malloc(lsz); 726*7887SLiane.Praza@Sun.COM if (lname == NULL) { 727*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 728*7887SLiane.Praza@Sun.COM goto cleanup; 729*7887SLiane.Praza@Sun.COM } 730*7887SLiane.Praza@Sun.COM 731*7887SLiane.Praza@Sun.COM (void) strlcpy(lname, name, lsz); 732*7887SLiane.Praza@Sun.COM if (strlcat(lname, loc, lsz) >= lsz) { 733*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 734*7887SLiane.Praza@Sun.COM free(lname); 735*7887SLiane.Praza@Sun.COM lname = NULL; 736*7887SLiane.Praza@Sun.COM } 737*7887SLiane.Praza@Sun.COM cleanup: 738*7887SLiane.Praza@Sun.COM free(loc); 739*7887SLiane.Praza@Sun.COM 740*7887SLiane.Praza@Sun.COM return (lname); 741*7887SLiane.Praza@Sun.COM } 742*7887SLiane.Praza@Sun.COM 743*7887SLiane.Praza@Sun.COM /* 744*7887SLiane.Praza@Sun.COM * char *_tmpl_pg_name(pg, type, use_type) 745*7887SLiane.Praza@Sun.COM * 746*7887SLiane.Praza@Sun.COM * pg and type can both be NULL. Returns the name of the most specific 747*7887SLiane.Praza@Sun.COM * template property group name based on the inputs. 748*7887SLiane.Praza@Sun.COM * If use_type is set and pg is not NULL, a property group name for a 749*7887SLiane.Praza@Sun.COM * property group template that has type defined is returned, even if no 750*7887SLiane.Praza@Sun.COM * type is provided. 751*7887SLiane.Praza@Sun.COM * 752*7887SLiane.Praza@Sun.COM * Returns NULL on failure and sets scf_error() to: 753*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 754*7887SLiane.Praza@Sun.COM * can't combine the arguments and get a reasonable length name 755*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 756*7887SLiane.Praza@Sun.COM * 757*7887SLiane.Praza@Sun.COM */ 758*7887SLiane.Praza@Sun.COM static char * 759*7887SLiane.Praza@Sun.COM _tmpl_pg_name(const char *pg, const char *type, int use_type) 760*7887SLiane.Praza@Sun.COM { 761*7887SLiane.Praza@Sun.COM char *name; 762*7887SLiane.Praza@Sun.COM ssize_t limit, size = 0; 763*7887SLiane.Praza@Sun.COM 764*7887SLiane.Praza@Sun.COM limit = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 765*7887SLiane.Praza@Sun.COM name = malloc(limit); 766*7887SLiane.Praza@Sun.COM if (name == NULL) { 767*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 768*7887SLiane.Praza@Sun.COM return (NULL); 769*7887SLiane.Praza@Sun.COM } 770*7887SLiane.Praza@Sun.COM 771*7887SLiane.Praza@Sun.COM if (pg == NULL && type == NULL) { 772*7887SLiane.Praza@Sun.COM if (strlcpy(name, SCF_PG_TM_PG_PATTERN_PREFIX, limit) >= 773*7887SLiane.Praza@Sun.COM limit) { 774*7887SLiane.Praza@Sun.COM assert(0); 775*7887SLiane.Praza@Sun.COM abort(); 776*7887SLiane.Praza@Sun.COM } 777*7887SLiane.Praza@Sun.COM return (name); 778*7887SLiane.Praza@Sun.COM } else if (pg != NULL && type != NULL) { 779*7887SLiane.Praza@Sun.COM size = snprintf(name, limit, "%s%s", 780*7887SLiane.Praza@Sun.COM SCF_PG_TM_PG_PATTERN_NT_PREFIX, pg); 781*7887SLiane.Praza@Sun.COM } else if (pg != NULL && type == NULL && use_type == 1) { 782*7887SLiane.Praza@Sun.COM size = snprintf(name, limit, "%s%s", 783*7887SLiane.Praza@Sun.COM SCF_PG_TM_PG_PATTERN_NT_PREFIX, pg); 784*7887SLiane.Praza@Sun.COM } else if (pg != NULL && type == NULL) { 785*7887SLiane.Praza@Sun.COM size = snprintf(name, limit, "%s%s", 786*7887SLiane.Praza@Sun.COM SCF_PG_TM_PG_PATTERN_N_PREFIX, pg); 787*7887SLiane.Praza@Sun.COM } else if (type != NULL && pg == NULL) { 788*7887SLiane.Praza@Sun.COM size = snprintf(name, limit, "%s%s", 789*7887SLiane.Praza@Sun.COM SCF_PG_TM_PG_PATTERN_T_PREFIX, type); 790*7887SLiane.Praza@Sun.COM } else { 791*7887SLiane.Praza@Sun.COM assert(0); 792*7887SLiane.Praza@Sun.COM abort(); 793*7887SLiane.Praza@Sun.COM } 794*7887SLiane.Praza@Sun.COM 795*7887SLiane.Praza@Sun.COM if (size >= limit) { 796*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 797*7887SLiane.Praza@Sun.COM free(name); 798*7887SLiane.Praza@Sun.COM return (NULL); 799*7887SLiane.Praza@Sun.COM } else { 800*7887SLiane.Praza@Sun.COM return (name); 801*7887SLiane.Praza@Sun.COM } 802*7887SLiane.Praza@Sun.COM } 803*7887SLiane.Praza@Sun.COM 804*7887SLiane.Praza@Sun.COM /* 805*7887SLiane.Praza@Sun.COM * _scf_get_pg_name() 806*7887SLiane.Praza@Sun.COM * Gets the name of the supplied property group. On success, returns an 807*7887SLiane.Praza@Sun.COM * allocated string. The string must be freed by free(). 808*7887SLiane.Praza@Sun.COM * 809*7887SLiane.Praza@Sun.COM * Returns NULL on failure and sets scf_error() to _CONNECTION_BROKEN, 810*7887SLiane.Praza@Sun.COM * _DELETED, or _NO_MEMORY. 811*7887SLiane.Praza@Sun.COM */ 812*7887SLiane.Praza@Sun.COM static char * 813*7887SLiane.Praza@Sun.COM _scf_get_pg_name(scf_propertygroup_t *pg) 814*7887SLiane.Praza@Sun.COM { 815*7887SLiane.Praza@Sun.COM ssize_t sz = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 816*7887SLiane.Praza@Sun.COM char *buf = malloc(sz); 817*7887SLiane.Praza@Sun.COM 818*7887SLiane.Praza@Sun.COM if (buf == NULL) { 819*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 820*7887SLiane.Praza@Sun.COM } else if (scf_pg_get_name(pg, buf, sz) == -1) { 821*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 822*7887SLiane.Praza@Sun.COM free(buf); 823*7887SLiane.Praza@Sun.COM buf = NULL; 824*7887SLiane.Praza@Sun.COM } else { 825*7887SLiane.Praza@Sun.COM assert(0); 826*7887SLiane.Praza@Sun.COM abort(); 827*7887SLiane.Praza@Sun.COM } 828*7887SLiane.Praza@Sun.COM } 829*7887SLiane.Praza@Sun.COM 830*7887SLiane.Praza@Sun.COM return (buf); 831*7887SLiane.Praza@Sun.COM } 832*7887SLiane.Praza@Sun.COM 833*7887SLiane.Praza@Sun.COM /* 834*7887SLiane.Praza@Sun.COM * char *_tmpl_prop_name() 835*7887SLiane.Praza@Sun.COM * 836*7887SLiane.Praza@Sun.COM * Returns the name of the property template prop (which is the name of 837*7887SLiane.Praza@Sun.COM * the property template property group) in the property group 838*7887SLiane.Praza@Sun.COM * template t. Returns NULL on failure and sets scf_error() to: 839*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 840*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 841*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 842*7887SLiane.Praza@Sun.COM * can't combine the arguments and get a reasonable length name 843*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 844*7887SLiane.Praza@Sun.COM */ 845*7887SLiane.Praza@Sun.COM static char * 846*7887SLiane.Praza@Sun.COM _tmpl_prop_name(const char *prop, scf_pg_tmpl_t *t) 847*7887SLiane.Praza@Sun.COM { 848*7887SLiane.Praza@Sun.COM char *name = NULL, *pg_name = NULL; 849*7887SLiane.Praza@Sun.COM size_t prefix_size; 850*7887SLiane.Praza@Sun.COM ssize_t limit, size = 0; 851*7887SLiane.Praza@Sun.COM 852*7887SLiane.Praza@Sun.COM assert(prop != NULL); 853*7887SLiane.Praza@Sun.COM assert(t->pt_pg != NULL); 854*7887SLiane.Praza@Sun.COM 855*7887SLiane.Praza@Sun.COM limit = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 856*7887SLiane.Praza@Sun.COM name = malloc(limit); 857*7887SLiane.Praza@Sun.COM if (name == NULL) { 858*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 859*7887SLiane.Praza@Sun.COM return (NULL); 860*7887SLiane.Praza@Sun.COM } 861*7887SLiane.Praza@Sun.COM 862*7887SLiane.Praza@Sun.COM if ((pg_name = _scf_get_pg_name(t->pt_pg)) == NULL) { 863*7887SLiane.Praza@Sun.COM free(name); 864*7887SLiane.Praza@Sun.COM return (NULL); 865*7887SLiane.Praza@Sun.COM } 866*7887SLiane.Praza@Sun.COM 867*7887SLiane.Praza@Sun.COM prefix_size = strlen(SCF_PG_TM_PG_PAT_BASE); 868*7887SLiane.Praza@Sun.COM if (strncmp(pg_name, SCF_PG_TM_PG_PAT_BASE, prefix_size) != 0) { 869*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 870*7887SLiane.Praza@Sun.COM free(name); 871*7887SLiane.Praza@Sun.COM free(pg_name); 872*7887SLiane.Praza@Sun.COM return (NULL); 873*7887SLiane.Praza@Sun.COM } 874*7887SLiane.Praza@Sun.COM 875*7887SLiane.Praza@Sun.COM size = snprintf(name, limit, "%s%s_%s", SCF_PG_TM_PROP_PATTERN_PREFIX, 876*7887SLiane.Praza@Sun.COM pg_name + prefix_size, prop); 877*7887SLiane.Praza@Sun.COM 878*7887SLiane.Praza@Sun.COM if (size >= limit) { 879*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 880*7887SLiane.Praza@Sun.COM free(name); 881*7887SLiane.Praza@Sun.COM free(pg_name); 882*7887SLiane.Praza@Sun.COM return (NULL); 883*7887SLiane.Praza@Sun.COM } else { 884*7887SLiane.Praza@Sun.COM free(pg_name); 885*7887SLiane.Praza@Sun.COM return (name); 886*7887SLiane.Praza@Sun.COM } 887*7887SLiane.Praza@Sun.COM } 888*7887SLiane.Praza@Sun.COM 889*7887SLiane.Praza@Sun.COM /* 890*7887SLiane.Praza@Sun.COM * int _get_snapshot() 891*7887SLiane.Praza@Sun.COM * 892*7887SLiane.Praza@Sun.COM * Gets the specified snapshot. If "snapshot" isn't defined, use the 893*7887SLiane.Praza@Sun.COM * running snapshot. If the snapshot isn't found, that may or may 894*7887SLiane.Praza@Sun.COM * not be an error depending on the caller. Return 0 in that case, 895*7887SLiane.Praza@Sun.COM * but leave scf_error() set to SCF_ERROR_NOT_FOUND. On all other 896*7887SLiane.Praza@Sun.COM * errors, set scf_error() to: 897*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 898*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 899*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 900*7887SLiane.Praza@Sun.COM * SCF_ERR_HANDLE_DESTROYED 901*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 902*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 903*7887SLiane.Praza@Sun.COM * The handle argument is NULL, or snaphot is not a valid snapshot name 904*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 905*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 906*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 907*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 908*7887SLiane.Praza@Sun.COM */ 909*7887SLiane.Praza@Sun.COM static int 910*7887SLiane.Praza@Sun.COM _get_snapshot(scf_instance_t *inst, const char *snapshot, 911*7887SLiane.Praza@Sun.COM scf_snapshot_t **snap) 912*7887SLiane.Praza@Sun.COM { 913*7887SLiane.Praza@Sun.COM int err; 914*7887SLiane.Praza@Sun.COM scf_handle_t *h; 915*7887SLiane.Praza@Sun.COM 916*7887SLiane.Praza@Sun.COM h = scf_instance_handle(inst); 917*7887SLiane.Praza@Sun.COM if (h == NULL) 918*7887SLiane.Praza@Sun.COM return (-1); 919*7887SLiane.Praza@Sun.COM 920*7887SLiane.Praza@Sun.COM if ((*snap = scf_snapshot_create(h)) == NULL) { 921*7887SLiane.Praza@Sun.COM return (-1); 922*7887SLiane.Praza@Sun.COM } 923*7887SLiane.Praza@Sun.COM 924*7887SLiane.Praza@Sun.COM /* Use running snapshot by default. */ 925*7887SLiane.Praza@Sun.COM if (snapshot == NULL) 926*7887SLiane.Praza@Sun.COM err = scf_instance_get_snapshot(inst, "running", *snap); 927*7887SLiane.Praza@Sun.COM else 928*7887SLiane.Praza@Sun.COM err = scf_instance_get_snapshot(inst, snapshot, *snap); 929*7887SLiane.Praza@Sun.COM 930*7887SLiane.Praza@Sun.COM if (err != 0) { 931*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 932*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(*snap); 933*7887SLiane.Praza@Sun.COM *snap = NULL; 934*7887SLiane.Praza@Sun.COM return (-1); 935*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 936*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 937*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(*snap); 938*7887SLiane.Praza@Sun.COM *snap = NULL; 939*7887SLiane.Praza@Sun.COM return (-1); 940*7887SLiane.Praza@Sun.COM 941*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 942*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(*snap); 943*7887SLiane.Praza@Sun.COM *snap = NULL; 944*7887SLiane.Praza@Sun.COM return (0); 945*7887SLiane.Praza@Sun.COM 946*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 947*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 948*7887SLiane.Praza@Sun.COM default: 949*7887SLiane.Praza@Sun.COM assert(0); 950*7887SLiane.Praza@Sun.COM abort(); 951*7887SLiane.Praza@Sun.COM } 952*7887SLiane.Praza@Sun.COM } 953*7887SLiane.Praza@Sun.COM 954*7887SLiane.Praza@Sun.COM /* 955*7887SLiane.Praza@Sun.COM * Explicitly set SCF_ERROR_NONE so that the SCF_ERROR_NOT_FOUND 956*7887SLiane.Praza@Sun.COM * return above is explicitly guaranteed to be from 957*7887SLiane.Praza@Sun.COM * scf_instance_get_snapshot(). 958*7887SLiane.Praza@Sun.COM */ 959*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NONE); 960*7887SLiane.Praza@Sun.COM return (0); 961*7887SLiane.Praza@Sun.COM } 962*7887SLiane.Praza@Sun.COM 963*7887SLiane.Praza@Sun.COM /* 964*7887SLiane.Praza@Sun.COM * Returns NULL on error, sets scf_error() to: 965*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 966*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 967*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 968*7887SLiane.Praza@Sun.COM * The restarter's FMRI does not match an existing instance. 969*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 970*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 971*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 972*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 973*7887SLiane.Praza@Sun.COM * The restarter's FMRI is not a valid FMRI. 974*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 975*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 976*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 977*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 978*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 979*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 980*7887SLiane.Praza@Sun.COM * restarter property is not SCF_TYPE_ASTRING or has more than one value 981*7887SLiane.Praza@Sun.COM */ 982*7887SLiane.Praza@Sun.COM static scf_instance_t * 983*7887SLiane.Praza@Sun.COM _get_restarter_inst(scf_handle_t *h, scf_service_t *svc, 984*7887SLiane.Praza@Sun.COM scf_instance_t *inst, scf_snapshot_t *s) 985*7887SLiane.Praza@Sun.COM { 986*7887SLiane.Praza@Sun.COM char *restarter = NULL; 987*7887SLiane.Praza@Sun.COM scf_instance_t *ri = NULL; 988*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg = NULL; 989*7887SLiane.Praza@Sun.COM int ret = 0; 990*7887SLiane.Praza@Sun.COM 991*7887SLiane.Praza@Sun.COM assert(svc != NULL || inst != NULL); 992*7887SLiane.Praza@Sun.COM assert(svc == NULL || inst == NULL); 993*7887SLiane.Praza@Sun.COM 994*7887SLiane.Praza@Sun.COM if ((ri = scf_instance_create(h)) == NULL || 995*7887SLiane.Praza@Sun.COM (pg = scf_pg_create(h)) == NULL) { 996*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 997*7887SLiane.Praza@Sun.COM scf_instance_destroy(ri); 998*7887SLiane.Praza@Sun.COM return (NULL); 999*7887SLiane.Praza@Sun.COM } 1000*7887SLiane.Praza@Sun.COM 1001*7887SLiane.Praza@Sun.COM if (inst != NULL) 1002*7887SLiane.Praza@Sun.COM ret = scf_instance_get_pg_composed(inst, s, SCF_PG_GENERAL, 1003*7887SLiane.Praza@Sun.COM pg); 1004*7887SLiane.Praza@Sun.COM else 1005*7887SLiane.Praza@Sun.COM ret = scf_service_get_pg(svc, SCF_PG_GENERAL, pg); 1006*7887SLiane.Praza@Sun.COM 1007*7887SLiane.Praza@Sun.COM if (ret != 0) { 1008*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1009*7887SLiane.Praza@Sun.COM goto _get_restarter_inst_fail; 1010*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 1011*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 1012*7887SLiane.Praza@Sun.COM /* Assume default restarter. */ 1013*7887SLiane.Praza@Sun.COM break; 1014*7887SLiane.Praza@Sun.COM 1015*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1016*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 1017*7887SLiane.Praza@Sun.COM /* 1018*7887SLiane.Praza@Sun.COM * If the arguments to the above functions 1019*7887SLiane.Praza@Sun.COM * aren't derived from the same handle, there's 1020*7887SLiane.Praza@Sun.COM * something wrong with the internal implementation, 1021*7887SLiane.Praza@Sun.COM * not the public caller further up the chain. 1022*7887SLiane.Praza@Sun.COM */ 1023*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 1024*7887SLiane.Praza@Sun.COM default: 1025*7887SLiane.Praza@Sun.COM assert(0); 1026*7887SLiane.Praza@Sun.COM abort(); 1027*7887SLiane.Praza@Sun.COM } 1028*7887SLiane.Praza@Sun.COM } else { 1029*7887SLiane.Praza@Sun.COM restarter = _scf_read_single_astring_from_pg(pg, 1030*7887SLiane.Praza@Sun.COM SCF_PROPERTY_RESTARTER); 1031*7887SLiane.Praza@Sun.COM /* zero length string is NOT a valid restarter */ 1032*7887SLiane.Praza@Sun.COM if (restarter != NULL && restarter[0] == '\0') { 1033*7887SLiane.Praza@Sun.COM free(restarter); 1034*7887SLiane.Praza@Sun.COM restarter = NULL; 1035*7887SLiane.Praza@Sun.COM } else if (restarter == NULL) { 1036*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1037*7887SLiane.Praza@Sun.COM goto _get_restarter_inst_fail; 1038*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 1039*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 1040*7887SLiane.Praza@Sun.COM break; 1041*7887SLiane.Praza@Sun.COM 1042*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 1043*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 1044*7887SLiane.Praza@Sun.COM (void) scf_set_error( 1045*7887SLiane.Praza@Sun.COM SCF_ERROR_TEMPLATE_INVALID); 1046*7887SLiane.Praza@Sun.COM goto _get_restarter_inst_fail; 1047*7887SLiane.Praza@Sun.COM 1048*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1049*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 1050*7887SLiane.Praza@Sun.COM default: 1051*7887SLiane.Praza@Sun.COM assert(0); 1052*7887SLiane.Praza@Sun.COM abort(); 1053*7887SLiane.Praza@Sun.COM } 1054*7887SLiane.Praza@Sun.COM } 1055*7887SLiane.Praza@Sun.COM } 1056*7887SLiane.Praza@Sun.COM 1057*7887SLiane.Praza@Sun.COM if (restarter == NULL) { 1058*7887SLiane.Praza@Sun.COM /* Use default restarter */ 1059*7887SLiane.Praza@Sun.COM restarter = strdup(SCF_SERVICE_STARTD); 1060*7887SLiane.Praza@Sun.COM if (restarter == NULL) { 1061*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1062*7887SLiane.Praza@Sun.COM goto _get_restarter_inst_fail; 1063*7887SLiane.Praza@Sun.COM } 1064*7887SLiane.Praza@Sun.COM } 1065*7887SLiane.Praza@Sun.COM 1066*7887SLiane.Praza@Sun.COM if (scf_handle_decode_fmri(h, restarter, NULL, NULL, ri, NULL, NULL, 1067*7887SLiane.Praza@Sun.COM SCF_DECODE_FMRI_EXACT|SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { 1068*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1069*7887SLiane.Praza@Sun.COM uu_free(restarter); 1070*7887SLiane.Praza@Sun.COM goto _get_restarter_inst_fail; 1071*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 1072*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 1073*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 1074*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 1075*7887SLiane.Praza@Sun.COM free(restarter); 1076*7887SLiane.Praza@Sun.COM goto _get_restarter_inst_fail; 1077*7887SLiane.Praza@Sun.COM 1078*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 1079*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1080*7887SLiane.Praza@Sun.COM default: 1081*7887SLiane.Praza@Sun.COM assert(0); 1082*7887SLiane.Praza@Sun.COM abort(); 1083*7887SLiane.Praza@Sun.COM } 1084*7887SLiane.Praza@Sun.COM } 1085*7887SLiane.Praza@Sun.COM free(restarter); 1086*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 1087*7887SLiane.Praza@Sun.COM 1088*7887SLiane.Praza@Sun.COM return (ri); 1089*7887SLiane.Praza@Sun.COM 1090*7887SLiane.Praza@Sun.COM _get_restarter_inst_fail: 1091*7887SLiane.Praza@Sun.COM scf_instance_destroy(ri); 1092*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 1093*7887SLiane.Praza@Sun.COM return (NULL); 1094*7887SLiane.Praza@Sun.COM } 1095*7887SLiane.Praza@Sun.COM 1096*7887SLiane.Praza@Sun.COM /* 1097*7887SLiane.Praza@Sun.COM * Returns NULL on error, sets scf_error() to: 1098*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 1099*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 1100*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 1101*7887SLiane.Praza@Sun.COM * Restarter property has more than one value associated with it, 1102*7887SLiane.Praza@Sun.COM * or FMRI does not meet restrictions in scf_handle_decode_fmri() flags. 1103*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 1104*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 1105*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 1106*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 1107*7887SLiane.Praza@Sun.COM * The fmri argument in scf_handle_decode_fmri() is not a valid FMRI. 1108*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 1109*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 1110*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 1111*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 1112*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 1113*7887SLiane.Praza@Sun.COM */ 1114*7887SLiane.Praza@Sun.COM static scf_instance_t * 1115*7887SLiane.Praza@Sun.COM _get_global_inst(scf_handle_t *h) 1116*7887SLiane.Praza@Sun.COM { 1117*7887SLiane.Praza@Sun.COM scf_instance_t *ri; 1118*7887SLiane.Praza@Sun.COM 1119*7887SLiane.Praza@Sun.COM if ((ri = scf_instance_create(h)) == NULL) { 1120*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 1121*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_RESOURCES); 1122*7887SLiane.Praza@Sun.COM return (NULL); 1123*7887SLiane.Praza@Sun.COM } 1124*7887SLiane.Praza@Sun.COM 1125*7887SLiane.Praza@Sun.COM if (scf_handle_decode_fmri(h, SCF_INSTANCE_GLOBAL, NULL, NULL, ri, 1126*7887SLiane.Praza@Sun.COM NULL, NULL, 1127*7887SLiane.Praza@Sun.COM SCF_DECODE_FMRI_EXACT|SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { 1128*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1129*7887SLiane.Praza@Sun.COM scf_instance_destroy(ri); 1130*7887SLiane.Praza@Sun.COM return (NULL); 1131*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 1132*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 1133*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 1134*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 1135*7887SLiane.Praza@Sun.COM scf_instance_destroy(ri); 1136*7887SLiane.Praza@Sun.COM return (NULL); 1137*7887SLiane.Praza@Sun.COM 1138*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 1139*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1140*7887SLiane.Praza@Sun.COM default: 1141*7887SLiane.Praza@Sun.COM assert(0); 1142*7887SLiane.Praza@Sun.COM abort(); 1143*7887SLiane.Praza@Sun.COM } 1144*7887SLiane.Praza@Sun.COM } 1145*7887SLiane.Praza@Sun.COM 1146*7887SLiane.Praza@Sun.COM return (ri); 1147*7887SLiane.Praza@Sun.COM } 1148*7887SLiane.Praza@Sun.COM 1149*7887SLiane.Praza@Sun.COM /* 1150*7887SLiane.Praza@Sun.COM * Call the supplied function for each of the service or instance, the 1151*7887SLiane.Praza@Sun.COM * service's restarter, and the globally defined template instance. 1152*7887SLiane.Praza@Sun.COM * If the function returns SCF_WALK_ERROR, the walk is ended. If 1153*7887SLiane.Praza@Sun.COM * the function returns SCF_WALK_NEXT, the next entity is tried. 1154*7887SLiane.Praza@Sun.COM * 1155*7887SLiane.Praza@Sun.COM * The function is only expected to return SCF_WALK_DONE if it has 1156*7887SLiane.Praza@Sun.COM * found a property group match in the current entity, and has 1157*7887SLiane.Praza@Sun.COM * populated p->pw_pg with the matching property group. 1158*7887SLiane.Praza@Sun.COM */ 1159*7887SLiane.Praza@Sun.COM static void 1160*7887SLiane.Praza@Sun.COM _walk_template_instances(scf_service_t *svc, scf_instance_t *inst, 1161*7887SLiane.Praza@Sun.COM scf_snapshot_t *snap, walk_template_inst_func_t *func, 1162*7887SLiane.Praza@Sun.COM pg_tmpl_walk_t *p, int flag) 1163*7887SLiane.Praza@Sun.COM { 1164*7887SLiane.Praza@Sun.COM scf_instance_t *tmpl_inst = NULL; 1165*7887SLiane.Praza@Sun.COM scf_handle_t *h; 1166*7887SLiane.Praza@Sun.COM int ret; 1167*7887SLiane.Praza@Sun.COM char *tg = NULL; 1168*7887SLiane.Praza@Sun.COM 1169*7887SLiane.Praza@Sun.COM assert(svc != NULL || inst != NULL); 1170*7887SLiane.Praza@Sun.COM assert(svc == NULL || inst == NULL); 1171*7887SLiane.Praza@Sun.COM 1172*7887SLiane.Praza@Sun.COM if (inst != NULL) 1173*7887SLiane.Praza@Sun.COM h = scf_instance_handle(inst); 1174*7887SLiane.Praza@Sun.COM else 1175*7887SLiane.Praza@Sun.COM h = scf_service_handle(svc); 1176*7887SLiane.Praza@Sun.COM if (h == NULL) 1177*7887SLiane.Praza@Sun.COM goto done; 1178*7887SLiane.Praza@Sun.COM 1179*7887SLiane.Praza@Sun.COM /* First, use supplied service or instance */ 1180*7887SLiane.Praza@Sun.COM p->pw_target = SCF_TM_TARGET_THIS; 1181*7887SLiane.Praza@Sun.COM ret = func(svc, inst, p); 1182*7887SLiane.Praza@Sun.COM switch (ret) { 1183*7887SLiane.Praza@Sun.COM case SCF_WALK_NEXT: 1184*7887SLiane.Praza@Sun.COM break; 1185*7887SLiane.Praza@Sun.COM case SCF_WALK_DONE: 1186*7887SLiane.Praza@Sun.COM /* 1187*7887SLiane.Praza@Sun.COM * Check that the template scoping matches and if not, 1188*7887SLiane.Praza@Sun.COM * continue. 1189*7887SLiane.Praza@Sun.COM */ 1190*7887SLiane.Praza@Sun.COM assert(p->pw_pg != NULL); 1191*7887SLiane.Praza@Sun.COM tg = _scf_read_single_astring_from_pg(p->pw_pg, 1192*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_TARGET); 1193*7887SLiane.Praza@Sun.COM if (tg == NULL || /* scf_error() was set */ 1194*7887SLiane.Praza@Sun.COM (strcmp(tg, SCF_TM_TARGET_INSTANCE) != 0 && 1195*7887SLiane.Praza@Sun.COM strcmp(tg, SCF_TM_TARGET_THIS) != 0 && 1196*7887SLiane.Praza@Sun.COM (flag & SCF_PG_TMPL_FLAG_EXACT) != 1197*7887SLiane.Praza@Sun.COM SCF_PG_TMPL_FLAG_EXACT)) { 1198*7887SLiane.Praza@Sun.COM scf_pg_destroy(p->pw_pg); 1199*7887SLiane.Praza@Sun.COM p->pw_pg = NULL; 1200*7887SLiane.Praza@Sun.COM if (tg != NULL) { 1201*7887SLiane.Praza@Sun.COM free(tg); 1202*7887SLiane.Praza@Sun.COM tg = NULL; 1203*7887SLiane.Praza@Sun.COM break; 1204*7887SLiane.Praza@Sun.COM } 1205*7887SLiane.Praza@Sun.COM } 1206*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 1207*7887SLiane.Praza@Sun.COM case SCF_WALK_ERROR: 1208*7887SLiane.Praza@Sun.COM goto done; 1209*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 1210*7887SLiane.Praza@Sun.COM default: 1211*7887SLiane.Praza@Sun.COM assert(0); 1212*7887SLiane.Praza@Sun.COM abort(); 1213*7887SLiane.Praza@Sun.COM } 1214*7887SLiane.Praza@Sun.COM 1215*7887SLiane.Praza@Sun.COM /* Next the restarter. */ 1216*7887SLiane.Praza@Sun.COM p->pw_target = SCF_TM_TARGET_DELEGATE; 1217*7887SLiane.Praza@Sun.COM tmpl_inst = _get_restarter_inst(h, svc, inst, snap); 1218*7887SLiane.Praza@Sun.COM if (tmpl_inst != NULL) { 1219*7887SLiane.Praza@Sun.COM ret = func(NULL, tmpl_inst, p); 1220*7887SLiane.Praza@Sun.COM switch (ret) { 1221*7887SLiane.Praza@Sun.COM case SCF_WALK_NEXT: 1222*7887SLiane.Praza@Sun.COM break; 1223*7887SLiane.Praza@Sun.COM case SCF_WALK_DONE: 1224*7887SLiane.Praza@Sun.COM /* 1225*7887SLiane.Praza@Sun.COM * Check that the template scoping matches and if not, 1226*7887SLiane.Praza@Sun.COM * continue. 1227*7887SLiane.Praza@Sun.COM */ 1228*7887SLiane.Praza@Sun.COM assert(p->pw_pg != NULL); 1229*7887SLiane.Praza@Sun.COM tg = _scf_read_single_astring_from_pg(p->pw_pg, 1230*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_TARGET); 1231*7887SLiane.Praza@Sun.COM if (tg == NULL || /* scf_error() was set */ 1232*7887SLiane.Praza@Sun.COM strcmp(tg, SCF_TM_TARGET_DELEGATE) != 0) { 1233*7887SLiane.Praza@Sun.COM scf_pg_destroy(p->pw_pg); 1234*7887SLiane.Praza@Sun.COM p->pw_pg = NULL; 1235*7887SLiane.Praza@Sun.COM if (tg != NULL) { 1236*7887SLiane.Praza@Sun.COM free(tg); 1237*7887SLiane.Praza@Sun.COM tg = NULL; 1238*7887SLiane.Praza@Sun.COM break; 1239*7887SLiane.Praza@Sun.COM } 1240*7887SLiane.Praza@Sun.COM } 1241*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 1242*7887SLiane.Praza@Sun.COM case SCF_WALK_ERROR: 1243*7887SLiane.Praza@Sun.COM goto done; 1244*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 1245*7887SLiane.Praza@Sun.COM default: 1246*7887SLiane.Praza@Sun.COM assert(0); 1247*7887SLiane.Praza@Sun.COM abort(); 1248*7887SLiane.Praza@Sun.COM } 1249*7887SLiane.Praza@Sun.COM } 1250*7887SLiane.Praza@Sun.COM 1251*7887SLiane.Praza@Sun.COM p->pw_target = SCF_TM_TARGET_ALL; 1252*7887SLiane.Praza@Sun.COM scf_instance_destroy(tmpl_inst); 1253*7887SLiane.Praza@Sun.COM tmpl_inst = _get_global_inst(h); 1254*7887SLiane.Praza@Sun.COM if (tmpl_inst != NULL) { 1255*7887SLiane.Praza@Sun.COM ret = func(NULL, tmpl_inst, p); 1256*7887SLiane.Praza@Sun.COM switch (ret) { 1257*7887SLiane.Praza@Sun.COM case SCF_WALK_NEXT: 1258*7887SLiane.Praza@Sun.COM break; 1259*7887SLiane.Praza@Sun.COM case SCF_WALK_DONE: 1260*7887SLiane.Praza@Sun.COM /* 1261*7887SLiane.Praza@Sun.COM * Check that the template scoping matches and if not, 1262*7887SLiane.Praza@Sun.COM * continue. 1263*7887SLiane.Praza@Sun.COM */ 1264*7887SLiane.Praza@Sun.COM assert(p->pw_pg != NULL); 1265*7887SLiane.Praza@Sun.COM tg = _scf_read_single_astring_from_pg(p->pw_pg, 1266*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_TARGET); 1267*7887SLiane.Praza@Sun.COM if (tg == NULL || /* scf_error() was set */ 1268*7887SLiane.Praza@Sun.COM strcmp(tg, SCF_TM_TARGET_ALL) != 0) { 1269*7887SLiane.Praza@Sun.COM scf_pg_destroy(p->pw_pg); 1270*7887SLiane.Praza@Sun.COM p->pw_pg = NULL; 1271*7887SLiane.Praza@Sun.COM if (tg != NULL) { 1272*7887SLiane.Praza@Sun.COM free(tg); 1273*7887SLiane.Praza@Sun.COM tg = NULL; 1274*7887SLiane.Praza@Sun.COM break; 1275*7887SLiane.Praza@Sun.COM } 1276*7887SLiane.Praza@Sun.COM } 1277*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 1278*7887SLiane.Praza@Sun.COM case SCF_WALK_ERROR: 1279*7887SLiane.Praza@Sun.COM goto done; 1280*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 1281*7887SLiane.Praza@Sun.COM default: 1282*7887SLiane.Praza@Sun.COM assert(0); 1283*7887SLiane.Praza@Sun.COM abort(); 1284*7887SLiane.Praza@Sun.COM } 1285*7887SLiane.Praza@Sun.COM } 1286*7887SLiane.Praza@Sun.COM 1287*7887SLiane.Praza@Sun.COM done: 1288*7887SLiane.Praza@Sun.COM free(tg); 1289*7887SLiane.Praza@Sun.COM if (ret != SCF_WALK_DONE) 1290*7887SLiane.Praza@Sun.COM scf_instance_destroy(tmpl_inst); 1291*7887SLiane.Praza@Sun.COM p->pw_target = NULL; 1292*7887SLiane.Praza@Sun.COM } 1293*7887SLiane.Praza@Sun.COM 1294*7887SLiane.Praza@Sun.COM /* 1295*7887SLiane.Praza@Sun.COM * _get_pg() returns 0 on success and -1 on failure. Sets scf_error() 1296*7887SLiane.Praza@Sun.COM * on failure. 1297*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 1298*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 1299*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 1300*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_MISMATCH 1301*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 1302*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 1303*7887SLiane.Praza@Sun.COM * name is not a valid property group. 1304*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 1305*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 1306*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 1307*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_SET 1308*7887SLiane.Praza@Sun.COM */ 1309*7887SLiane.Praza@Sun.COM static int 1310*7887SLiane.Praza@Sun.COM _get_pg(scf_service_t *svc, scf_instance_t *inst, 1311*7887SLiane.Praza@Sun.COM const scf_snapshot_t *snap, const char *name, scf_propertygroup_t *pg) 1312*7887SLiane.Praza@Sun.COM { 1313*7887SLiane.Praza@Sun.COM int ret; 1314*7887SLiane.Praza@Sun.COM 1315*7887SLiane.Praza@Sun.COM assert(svc != NULL || inst != NULL); 1316*7887SLiane.Praza@Sun.COM assert(svc == NULL || inst == NULL); 1317*7887SLiane.Praza@Sun.COM assert(pg != NULL); 1318*7887SLiane.Praza@Sun.COM 1319*7887SLiane.Praza@Sun.COM if (inst != NULL) 1320*7887SLiane.Praza@Sun.COM ret = scf_instance_get_pg_composed(inst, snap, name, pg); 1321*7887SLiane.Praza@Sun.COM else 1322*7887SLiane.Praza@Sun.COM ret = scf_service_get_pg(svc, name, pg); 1323*7887SLiane.Praza@Sun.COM 1324*7887SLiane.Praza@Sun.COM return (ret); 1325*7887SLiane.Praza@Sun.COM } 1326*7887SLiane.Praza@Sun.COM 1327*7887SLiane.Praza@Sun.COM /* 1328*7887SLiane.Praza@Sun.COM * Returns SCF_WALK_NEXT for not found, SCF_WALK_ERROR for error, 1329*7887SLiane.Praza@Sun.COM * and SCF_WALK_DONE for found. 1330*7887SLiane.Praza@Sun.COM * On error, destroy pg and set it to NULL. 1331*7887SLiane.Praza@Sun.COM * 1332*7887SLiane.Praza@Sun.COM * Sets scf_error() if SCF_WALK_ERROR is returned to _BACKEND_ACCESS, 1333*7887SLiane.Praza@Sun.COM * _CONNECTION_BROKEN, _INTERNAL, _INVALID_ARGUMENT (name is not a 1334*7887SLiane.Praza@Sun.COM * valid property group), _NO_RESOURCES, or _NOT_BOUND. 1335*7887SLiane.Praza@Sun.COM */ 1336*7887SLiane.Praza@Sun.COM static int 1337*7887SLiane.Praza@Sun.COM _lookup_pg(scf_service_t *svc, scf_instance_t *inst, 1338*7887SLiane.Praza@Sun.COM const scf_snapshot_t *snap, const char *name, scf_propertygroup_t *pg) 1339*7887SLiane.Praza@Sun.COM { 1340*7887SLiane.Praza@Sun.COM int ret; 1341*7887SLiane.Praza@Sun.COM 1342*7887SLiane.Praza@Sun.COM ret = _get_pg(svc, inst, snap, name, pg); 1343*7887SLiane.Praza@Sun.COM 1344*7887SLiane.Praza@Sun.COM if (ret == 0) { 1345*7887SLiane.Praza@Sun.COM return (SCF_WALK_DONE); 1346*7887SLiane.Praza@Sun.COM } else { 1347*7887SLiane.Praza@Sun.COM switch (scf_error()) { 1348*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 1349*7887SLiane.Praza@Sun.COM case SCF_ERROR_DELETED: 1350*7887SLiane.Praza@Sun.COM return (SCF_WALK_NEXT); 1351*7887SLiane.Praza@Sun.COM 1352*7887SLiane.Praza@Sun.COM case SCF_ERROR_BACKEND_ACCESS: 1353*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONNECTION_BROKEN: 1354*7887SLiane.Praza@Sun.COM case SCF_ERROR_INTERNAL: 1355*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 1356*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_BOUND: 1357*7887SLiane.Praza@Sun.COM case SCF_ERROR_NO_RESOURCES: 1358*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 1359*7887SLiane.Praza@Sun.COM pg = NULL; 1360*7887SLiane.Praza@Sun.COM return (SCF_WALK_ERROR); 1361*7887SLiane.Praza@Sun.COM 1362*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1363*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 1364*7887SLiane.Praza@Sun.COM default: 1365*7887SLiane.Praza@Sun.COM assert(0); 1366*7887SLiane.Praza@Sun.COM abort(); 1367*7887SLiane.Praza@Sun.COM } 1368*7887SLiane.Praza@Sun.COM } 1369*7887SLiane.Praza@Sun.COM 1370*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 1371*7887SLiane.Praza@Sun.COM } 1372*7887SLiane.Praza@Sun.COM 1373*7887SLiane.Praza@Sun.COM /* 1374*7887SLiane.Praza@Sun.COM * If match, return 0. If no match, return 1. If error, return -1. 1375*7887SLiane.Praza@Sun.COM * On error set scf_error() to _BACKEND_ACCESS, _CONNECTION_BROKEN, 1376*7887SLiane.Praza@Sun.COM * _HANDLE_DESTROYED, _INTERNAL, _NO_MEMORY, _NO_RESOURCES, _NOT_BOUND, 1377*7887SLiane.Praza@Sun.COM * _NOT_SET (property group specified by pg is not set), _PERMISSION_DENIED, 1378*7887SLiane.Praza@Sun.COM * or _TEMPLATE_INVALID (target property is not SCF_TYPE_ASTRING or has 1379*7887SLiane.Praza@Sun.COM * more than one value). 1380*7887SLiane.Praza@Sun.COM */ 1381*7887SLiane.Praza@Sun.COM static int 1382*7887SLiane.Praza@Sun.COM check_target_match(scf_propertygroup_t *pg, const char *target) 1383*7887SLiane.Praza@Sun.COM { 1384*7887SLiane.Praza@Sun.COM char *pg_target; 1385*7887SLiane.Praza@Sun.COM int ret = 0; 1386*7887SLiane.Praza@Sun.COM 1387*7887SLiane.Praza@Sun.COM pg_target = _scf_read_single_astring_from_pg(pg, 1388*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_TARGET); 1389*7887SLiane.Praza@Sun.COM if (pg_target == NULL) { 1390*7887SLiane.Praza@Sun.COM switch (scf_error()) { 1391*7887SLiane.Praza@Sun.COM case SCF_ERROR_DELETED: 1392*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 1393*7887SLiane.Praza@Sun.COM return (1); 1394*7887SLiane.Praza@Sun.COM 1395*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 1396*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 1397*7887SLiane.Praza@Sun.COM (void) scf_set_error( 1398*7887SLiane.Praza@Sun.COM SCF_ERROR_TEMPLATE_INVALID); 1399*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 1400*7887SLiane.Praza@Sun.COM 1401*7887SLiane.Praza@Sun.COM case SCF_ERROR_BACKEND_ACCESS: 1402*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONNECTION_BROKEN: 1403*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_DESTROYED: 1404*7887SLiane.Praza@Sun.COM case SCF_ERROR_INTERNAL: 1405*7887SLiane.Praza@Sun.COM case SCF_ERROR_NO_RESOURCES: 1406*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_BOUND: 1407*7887SLiane.Praza@Sun.COM case SCF_ERROR_PERMISSION_DENIED: 1408*7887SLiane.Praza@Sun.COM return (-1); 1409*7887SLiane.Praza@Sun.COM 1410*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1411*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 1412*7887SLiane.Praza@Sun.COM default: 1413*7887SLiane.Praza@Sun.COM assert(0); 1414*7887SLiane.Praza@Sun.COM abort(); 1415*7887SLiane.Praza@Sun.COM } 1416*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 1417*7887SLiane.Praza@Sun.COM } 1418*7887SLiane.Praza@Sun.COM 1419*7887SLiane.Praza@Sun.COM /* For a desired target of 'this', check for 'this' and 'instance'. */ 1420*7887SLiane.Praza@Sun.COM if ((strcmp(target, SCF_TM_TARGET_INSTANCE) == 0 || 1421*7887SLiane.Praza@Sun.COM strcmp(target, SCF_TM_TARGET_THIS) == 0) && 1422*7887SLiane.Praza@Sun.COM (strcmp(pg_target, SCF_TM_TARGET_INSTANCE) == 0 || 1423*7887SLiane.Praza@Sun.COM strcmp(pg_target, SCF_TM_TARGET_THIS) == 0)) { 1424*7887SLiane.Praza@Sun.COM goto cleanup; 1425*7887SLiane.Praza@Sun.COM } 1426*7887SLiane.Praza@Sun.COM 1427*7887SLiane.Praza@Sun.COM if (strcmp(target, SCF_TM_TARGET_DELEGATE) == 0 && 1428*7887SLiane.Praza@Sun.COM strcmp(pg_target, SCF_TM_TARGET_DELEGATE) == 0) { 1429*7887SLiane.Praza@Sun.COM goto cleanup; 1430*7887SLiane.Praza@Sun.COM } 1431*7887SLiane.Praza@Sun.COM 1432*7887SLiane.Praza@Sun.COM if (strcmp(target, SCF_TM_TARGET_ALL) == 0 && 1433*7887SLiane.Praza@Sun.COM strcmp(pg_target, SCF_TM_TARGET_ALL) == 0) { 1434*7887SLiane.Praza@Sun.COM goto cleanup; 1435*7887SLiane.Praza@Sun.COM } 1436*7887SLiane.Praza@Sun.COM 1437*7887SLiane.Praza@Sun.COM ret = 1; 1438*7887SLiane.Praza@Sun.COM cleanup: 1439*7887SLiane.Praza@Sun.COM free(pg_target); 1440*7887SLiane.Praza@Sun.COM return (ret); 1441*7887SLiane.Praza@Sun.COM } 1442*7887SLiane.Praza@Sun.COM 1443*7887SLiane.Praza@Sun.COM /* 1444*7887SLiane.Praza@Sun.COM * Check if a matching template property group exists for each of: 1445*7887SLiane.Praza@Sun.COM * name and type, name only, type only, and completely wildcarded 1446*7887SLiane.Praza@Sun.COM * template. 1447*7887SLiane.Praza@Sun.COM * 1448*7887SLiane.Praza@Sun.COM * Both pg_name and pg_type are optional. 1449*7887SLiane.Praza@Sun.COM * 1450*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error(): 1451*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 1452*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 1453*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 1454*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 1455*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 1456*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 1457*7887SLiane.Praza@Sun.COM * can't combine the _tmpl_pg_name arguments and get a reasonable 1458*7887SLiane.Praza@Sun.COM * length name, or pg_name is not a valid property group. 1459*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 1460*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 1461*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 1462*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 1463*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 1464*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 1465*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 1466*7887SLiane.Praza@Sun.COM * target property is not SCF_TYPE_ASTRING or has more than one value. 1467*7887SLiane.Praza@Sun.COM */ 1468*7887SLiane.Praza@Sun.COM static scf_propertygroup_t * 1469*7887SLiane.Praza@Sun.COM _find_template_pg_match(scf_service_t *svc, scf_instance_t *inst, 1470*7887SLiane.Praza@Sun.COM const scf_snapshot_t *snap, const char *pg_name, const char *pg_type, 1471*7887SLiane.Praza@Sun.COM const char *target, char **tmpl_pg_name) 1472*7887SLiane.Praza@Sun.COM { 1473*7887SLiane.Praza@Sun.COM int ret, r; 1474*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg = NULL; 1475*7887SLiane.Praza@Sun.COM scf_handle_t *h; 1476*7887SLiane.Praza@Sun.COM scf_iter_t *iter; 1477*7887SLiane.Praza@Sun.COM char *name, *type; 1478*7887SLiane.Praza@Sun.COM 1479*7887SLiane.Praza@Sun.COM assert(inst != NULL || svc != NULL); 1480*7887SLiane.Praza@Sun.COM assert(inst == NULL || svc == NULL); 1481*7887SLiane.Praza@Sun.COM 1482*7887SLiane.Praza@Sun.COM if (inst != NULL) 1483*7887SLiane.Praza@Sun.COM h = scf_instance_handle(inst); 1484*7887SLiane.Praza@Sun.COM else 1485*7887SLiane.Praza@Sun.COM h = scf_service_handle(svc); 1486*7887SLiane.Praza@Sun.COM if (h == NULL) { 1487*7887SLiane.Praza@Sun.COM return (NULL); 1488*7887SLiane.Praza@Sun.COM } 1489*7887SLiane.Praza@Sun.COM 1490*7887SLiane.Praza@Sun.COM if ((pg = scf_pg_create(h)) == NULL || 1491*7887SLiane.Praza@Sun.COM (iter = scf_iter_create(h)) == NULL) { 1492*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 1493*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 1494*7887SLiane.Praza@Sun.COM return (NULL); 1495*7887SLiane.Praza@Sun.COM } 1496*7887SLiane.Praza@Sun.COM 1497*7887SLiane.Praza@Sun.COM /* 1498*7887SLiane.Praza@Sun.COM * We're going to walk through the possible pg templates that 1499*7887SLiane.Praza@Sun.COM * could match the supplied name and type. We do this 1500*7887SLiane.Praza@Sun.COM * by explicit name lookups when possible to avoid having to 1501*7887SLiane.Praza@Sun.COM * keep track of a most-explicit-match during iteration. 1502*7887SLiane.Praza@Sun.COM */ 1503*7887SLiane.Praza@Sun.COM 1504*7887SLiane.Praza@Sun.COM /* First look for a template with name and type set and matching. */ 1505*7887SLiane.Praza@Sun.COM *tmpl_pg_name = _tmpl_pg_name(pg_name, pg_type, 1); 1506*7887SLiane.Praza@Sun.COM if (*tmpl_pg_name == NULL) 1507*7887SLiane.Praza@Sun.COM goto fail; 1508*7887SLiane.Praza@Sun.COM ret = _lookup_pg(svc, inst, snap, *tmpl_pg_name, pg); 1509*7887SLiane.Praza@Sun.COM if (ret != SCF_WALK_NEXT) { 1510*7887SLiane.Praza@Sun.COM if (pg != NULL) { 1511*7887SLiane.Praza@Sun.COM if ((r = check_target_match(pg, target)) == 0) 1512*7887SLiane.Praza@Sun.COM goto done; 1513*7887SLiane.Praza@Sun.COM else if (r == -1) 1514*7887SLiane.Praza@Sun.COM goto fail; 1515*7887SLiane.Praza@Sun.COM } else { 1516*7887SLiane.Praza@Sun.COM goto done; 1517*7887SLiane.Praza@Sun.COM } 1518*7887SLiane.Praza@Sun.COM } 1519*7887SLiane.Praza@Sun.COM free(*tmpl_pg_name); 1520*7887SLiane.Praza@Sun.COM 1521*7887SLiane.Praza@Sun.COM /* 1522*7887SLiane.Praza@Sun.COM * Need to search on a name-only match before searching on 1523*7887SLiane.Praza@Sun.COM * type matches. 1524*7887SLiane.Praza@Sun.COM */ 1525*7887SLiane.Praza@Sun.COM 1526*7887SLiane.Praza@Sun.COM *tmpl_pg_name = _tmpl_pg_name(pg_name, NULL, 0); 1527*7887SLiane.Praza@Sun.COM if (*tmpl_pg_name == NULL) 1528*7887SLiane.Praza@Sun.COM goto fail; 1529*7887SLiane.Praza@Sun.COM ret = _lookup_pg(svc, inst, snap, *tmpl_pg_name, pg); 1530*7887SLiane.Praza@Sun.COM if (ret != SCF_WALK_NEXT) { 1531*7887SLiane.Praza@Sun.COM if (pg != NULL) { 1532*7887SLiane.Praza@Sun.COM if ((r = check_target_match(pg, target)) == 0) 1533*7887SLiane.Praza@Sun.COM goto done; 1534*7887SLiane.Praza@Sun.COM else if (r == -1) 1535*7887SLiane.Praza@Sun.COM goto fail; 1536*7887SLiane.Praza@Sun.COM } else { 1537*7887SLiane.Praza@Sun.COM goto done; 1538*7887SLiane.Praza@Sun.COM } 1539*7887SLiane.Praza@Sun.COM } 1540*7887SLiane.Praza@Sun.COM free(*tmpl_pg_name); 1541*7887SLiane.Praza@Sun.COM 1542*7887SLiane.Praza@Sun.COM /* Next, see if there's an "nt" template where the type matches. */ 1543*7887SLiane.Praza@Sun.COM if (pg_type != NULL && pg_name == NULL) { 1544*7887SLiane.Praza@Sun.COM if (inst != NULL) 1545*7887SLiane.Praza@Sun.COM ret = scf_iter_instance_pgs_typed_composed(iter, inst, 1546*7887SLiane.Praza@Sun.COM snap, SCF_GROUP_TEMPLATE_PG_PATTERN); 1547*7887SLiane.Praza@Sun.COM else 1548*7887SLiane.Praza@Sun.COM ret = scf_iter_service_pgs_typed(iter, svc, 1549*7887SLiane.Praza@Sun.COM SCF_GROUP_TEMPLATE_PG_PATTERN); 1550*7887SLiane.Praza@Sun.COM 1551*7887SLiane.Praza@Sun.COM if (ret != 0) { 1552*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1553*7887SLiane.Praza@Sun.COM goto fail; 1554*7887SLiane.Praza@Sun.COM } else { 1555*7887SLiane.Praza@Sun.COM assert(0); 1556*7887SLiane.Praza@Sun.COM abort(); 1557*7887SLiane.Praza@Sun.COM } 1558*7887SLiane.Praza@Sun.COM } 1559*7887SLiane.Praza@Sun.COM 1560*7887SLiane.Praza@Sun.COM while ((ret = scf_iter_next_pg(iter, pg)) == 1) { 1561*7887SLiane.Praza@Sun.COM /* Make sure this is a name and type specified pg. */ 1562*7887SLiane.Praza@Sun.COM name = _scf_read_single_astring_from_pg(pg, 1563*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_NAME); 1564*7887SLiane.Praza@Sun.COM if (name == NULL) 1565*7887SLiane.Praza@Sun.COM continue; 1566*7887SLiane.Praza@Sun.COM type = _scf_read_single_astring_from_pg(pg, 1567*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_TYPE); 1568*7887SLiane.Praza@Sun.COM if (type == NULL) { 1569*7887SLiane.Praza@Sun.COM free(name); 1570*7887SLiane.Praza@Sun.COM continue; 1571*7887SLiane.Praza@Sun.COM } 1572*7887SLiane.Praza@Sun.COM if (strcmp(pg_type, type) == 0 && 1573*7887SLiane.Praza@Sun.COM check_target_match(pg, target) == 0) { 1574*7887SLiane.Praza@Sun.COM *tmpl_pg_name = name; 1575*7887SLiane.Praza@Sun.COM free(type); 1576*7887SLiane.Praza@Sun.COM goto done; 1577*7887SLiane.Praza@Sun.COM } 1578*7887SLiane.Praza@Sun.COM free(type); 1579*7887SLiane.Praza@Sun.COM free(name); 1580*7887SLiane.Praza@Sun.COM } 1581*7887SLiane.Praza@Sun.COM if (ret == -1) { 1582*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1583*7887SLiane.Praza@Sun.COM goto fail; 1584*7887SLiane.Praza@Sun.COM } else { 1585*7887SLiane.Praza@Sun.COM assert(0); 1586*7887SLiane.Praza@Sun.COM abort(); 1587*7887SLiane.Praza@Sun.COM } 1588*7887SLiane.Praza@Sun.COM } 1589*7887SLiane.Praza@Sun.COM } 1590*7887SLiane.Praza@Sun.COM 1591*7887SLiane.Praza@Sun.COM *tmpl_pg_name = _tmpl_pg_name(NULL, pg_type, 0); 1592*7887SLiane.Praza@Sun.COM if (*tmpl_pg_name == NULL) 1593*7887SLiane.Praza@Sun.COM goto fail; 1594*7887SLiane.Praza@Sun.COM ret = _lookup_pg(svc, inst, snap, *tmpl_pg_name, pg); 1595*7887SLiane.Praza@Sun.COM if (ret != SCF_WALK_NEXT) { 1596*7887SLiane.Praza@Sun.COM if (pg != NULL) { 1597*7887SLiane.Praza@Sun.COM if ((r = check_target_match(pg, target)) == 0) 1598*7887SLiane.Praza@Sun.COM goto done; 1599*7887SLiane.Praza@Sun.COM else if (r == -1) 1600*7887SLiane.Praza@Sun.COM goto fail; 1601*7887SLiane.Praza@Sun.COM } else { 1602*7887SLiane.Praza@Sun.COM goto done; 1603*7887SLiane.Praza@Sun.COM } 1604*7887SLiane.Praza@Sun.COM } 1605*7887SLiane.Praza@Sun.COM free(*tmpl_pg_name); 1606*7887SLiane.Praza@Sun.COM 1607*7887SLiane.Praza@Sun.COM *tmpl_pg_name = _tmpl_pg_name(NULL, NULL, 0); 1608*7887SLiane.Praza@Sun.COM if (*tmpl_pg_name == NULL) 1609*7887SLiane.Praza@Sun.COM goto fail; 1610*7887SLiane.Praza@Sun.COM ret = _lookup_pg(svc, inst, snap, *tmpl_pg_name, pg); 1611*7887SLiane.Praza@Sun.COM if (ret != SCF_WALK_NEXT) { 1612*7887SLiane.Praza@Sun.COM if (pg != NULL) { 1613*7887SLiane.Praza@Sun.COM if ((r = check_target_match(pg, target)) == 0) 1614*7887SLiane.Praza@Sun.COM goto done; 1615*7887SLiane.Praza@Sun.COM else if (r == -1) 1616*7887SLiane.Praza@Sun.COM goto fail; 1617*7887SLiane.Praza@Sun.COM } else { 1618*7887SLiane.Praza@Sun.COM goto done; 1619*7887SLiane.Praza@Sun.COM } 1620*7887SLiane.Praza@Sun.COM } 1621*7887SLiane.Praza@Sun.COM 1622*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 1623*7887SLiane.Praza@Sun.COM fail: 1624*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 1625*7887SLiane.Praza@Sun.COM if (*tmpl_pg_name != NULL) 1626*7887SLiane.Praza@Sun.COM free(*tmpl_pg_name); 1627*7887SLiane.Praza@Sun.COM *tmpl_pg_name = NULL; 1628*7887SLiane.Praza@Sun.COM pg = NULL; 1629*7887SLiane.Praza@Sun.COM done: 1630*7887SLiane.Praza@Sun.COM if (ret == SCF_WALK_ERROR) 1631*7887SLiane.Praza@Sun.COM free(*tmpl_pg_name); 1632*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 1633*7887SLiane.Praza@Sun.COM return (pg); 1634*7887SLiane.Praza@Sun.COM } 1635*7887SLiane.Praza@Sun.COM 1636*7887SLiane.Praza@Sun.COM /* 1637*7887SLiane.Praza@Sun.COM * Finds the pg match in either the supplied service or instance. 1638*7887SLiane.Praza@Sun.COM * Returns SCF_WALK_ERROR, SCF_WALK_NEXT, or SCF_WALK_DONE. 1639*7887SLiane.Praza@Sun.COM * If returning SCF_WALK_ERROR, sets scf_error(): 1640*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 1641*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 1642*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 1643*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 1644*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 1645*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 1646*7887SLiane.Praza@Sun.COM * The snaphot is not a valid snapshot name, 1647*7887SLiane.Praza@Sun.COM * or can't create a reasonable property group template name. 1648*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 1649*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 1650*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 1651*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 1652*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 1653*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 1654*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 1655*7887SLiane.Praza@Sun.COM * target property is not SCF_TYPE_ASTRING or has more than one value. 1656*7887SLiane.Praza@Sun.COM */ 1657*7887SLiane.Praza@Sun.COM static int 1658*7887SLiane.Praza@Sun.COM find_pg_match(scf_service_t *svc, scf_instance_t *inst, pg_tmpl_walk_t *p) 1659*7887SLiane.Praza@Sun.COM { 1660*7887SLiane.Praza@Sun.COM scf_snapshot_t *tmpl_snap = NULL; 1661*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg; 1662*7887SLiane.Praza@Sun.COM scf_handle_t *h; 1663*7887SLiane.Praza@Sun.COM char *tmpl_pg_name; 1664*7887SLiane.Praza@Sun.COM 1665*7887SLiane.Praza@Sun.COM assert(svc != NULL || inst != NULL); 1666*7887SLiane.Praza@Sun.COM assert(svc == NULL || inst == NULL); 1667*7887SLiane.Praza@Sun.COM 1668*7887SLiane.Praza@Sun.COM if (inst != NULL) 1669*7887SLiane.Praza@Sun.COM h = scf_instance_handle(inst); 1670*7887SLiane.Praza@Sun.COM else 1671*7887SLiane.Praza@Sun.COM h = scf_service_handle(svc); 1672*7887SLiane.Praza@Sun.COM if (h == NULL) 1673*7887SLiane.Praza@Sun.COM return (SCF_WALK_ERROR); 1674*7887SLiane.Praza@Sun.COM 1675*7887SLiane.Praza@Sun.COM if (p->pw_snapname != NULL) { 1676*7887SLiane.Praza@Sun.COM if (_get_snapshot(inst, p->pw_snapname, &tmpl_snap) == -1) 1677*7887SLiane.Praza@Sun.COM return (SCF_WALK_ERROR); 1678*7887SLiane.Praza@Sun.COM } 1679*7887SLiane.Praza@Sun.COM pg = _find_template_pg_match(svc, inst, tmpl_snap, p->pw_pgname, 1680*7887SLiane.Praza@Sun.COM p->pw_pgtype, p->pw_target, &tmpl_pg_name); 1681*7887SLiane.Praza@Sun.COM 1682*7887SLiane.Praza@Sun.COM if (pg != NULL) { 1683*7887SLiane.Praza@Sun.COM p->pw_snap = tmpl_snap; 1684*7887SLiane.Praza@Sun.COM p->pw_pg = pg; 1685*7887SLiane.Praza@Sun.COM p->pw_tmpl_pgname = tmpl_pg_name; 1686*7887SLiane.Praza@Sun.COM p->pw_inst = inst; 1687*7887SLiane.Praza@Sun.COM p->pw_svc = svc; 1688*7887SLiane.Praza@Sun.COM return (SCF_WALK_DONE); 1689*7887SLiane.Praza@Sun.COM } 1690*7887SLiane.Praza@Sun.COM 1691*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(tmpl_snap); 1692*7887SLiane.Praza@Sun.COM return (SCF_WALK_NEXT); 1693*7887SLiane.Praza@Sun.COM } 1694*7887SLiane.Praza@Sun.COM 1695*7887SLiane.Praza@Sun.COM /* 1696*7887SLiane.Praza@Sun.COM * return 0 on success and -1 on failure. 1697*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 1698*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 1699*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 1700*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_MISMATCH 1701*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 1702*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 1703*7887SLiane.Praza@Sun.COM * FMRI argument, snapshot name, pg_name, or pg is invalid. 1704*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 1705*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 1706*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 1707*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 1708*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_SET 1709*7887SLiane.Praza@Sun.COM */ 1710*7887SLiane.Praza@Sun.COM int 1711*7887SLiane.Praza@Sun.COM scf_tmpl_get_by_pg(scf_propertygroup_t *pg, scf_pg_tmpl_t *pg_tmpl, int flags) 1712*7887SLiane.Praza@Sun.COM { 1713*7887SLiane.Praza@Sun.COM char *fmribuf = NULL, *snapbuf = NULL, *pg_name = NULL, *pg_type = NULL; 1714*7887SLiane.Praza@Sun.COM int ret = 0; 1715*7887SLiane.Praza@Sun.COM ssize_t fbufsz = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH) + 1; 1716*7887SLiane.Praza@Sun.COM ssize_t nbufsz = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 1717*7887SLiane.Praza@Sun.COM ssize_t tbufsz = scf_limit(SCF_LIMIT_MAX_PG_TYPE_LENGTH) + 1; 1718*7887SLiane.Praza@Sun.COM scf_instance_t *inst = NULL; 1719*7887SLiane.Praza@Sun.COM scf_snaplevel_t *snaplvl = NULL; 1720*7887SLiane.Praza@Sun.COM scf_service_t *svc = NULL; 1721*7887SLiane.Praza@Sun.COM scf_handle_t *h; 1722*7887SLiane.Praza@Sun.COM scf_snapshot_t *snap = NULL; 1723*7887SLiane.Praza@Sun.COM pg_tmpl_walk_t *p; 1724*7887SLiane.Praza@Sun.COM 1725*7887SLiane.Praza@Sun.COM assert(fbufsz != 0 && nbufsz != 0 && tbufsz != 0); 1726*7887SLiane.Praza@Sun.COM 1727*7887SLiane.Praza@Sun.COM scf_tmpl_pg_reset(pg_tmpl); 1728*7887SLiane.Praza@Sun.COM 1729*7887SLiane.Praza@Sun.COM if ((h = scf_pg_handle(pg)) == NULL) 1730*7887SLiane.Praza@Sun.COM return (-1); 1731*7887SLiane.Praza@Sun.COM 1732*7887SLiane.Praza@Sun.COM if ((inst = scf_instance_create(h)) == NULL || 1733*7887SLiane.Praza@Sun.COM (svc = scf_service_create(h)) == NULL || 1734*7887SLiane.Praza@Sun.COM (snaplvl = scf_snaplevel_create(h)) == NULL) { 1735*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 1736*7887SLiane.Praza@Sun.COM scf_service_destroy(svc); 1737*7887SLiane.Praza@Sun.COM return (-1); 1738*7887SLiane.Praza@Sun.COM } 1739*7887SLiane.Praza@Sun.COM 1740*7887SLiane.Praza@Sun.COM if ((fmribuf = malloc(fbufsz)) == NULL || 1741*7887SLiane.Praza@Sun.COM (pg_name = malloc(nbufsz)) == NULL || 1742*7887SLiane.Praza@Sun.COM (pg_type = malloc(tbufsz)) == NULL || 1743*7887SLiane.Praza@Sun.COM (p = calloc(1, sizeof (pg_tmpl_walk_t))) == NULL) { 1744*7887SLiane.Praza@Sun.COM free(fmribuf); 1745*7887SLiane.Praza@Sun.COM free(pg_name); 1746*7887SLiane.Praza@Sun.COM free(pg_type); 1747*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 1748*7887SLiane.Praza@Sun.COM scf_service_destroy(svc); 1749*7887SLiane.Praza@Sun.COM scf_snaplevel_destroy(snaplvl); 1750*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1751*7887SLiane.Praza@Sun.COM return (-1); 1752*7887SLiane.Praza@Sun.COM } 1753*7887SLiane.Praza@Sun.COM 1754*7887SLiane.Praza@Sun.COM if (scf_pg_get_name(pg, pg_name, nbufsz) < 0) { 1755*7887SLiane.Praza@Sun.COM ret = -1; 1756*7887SLiane.Praza@Sun.COM goto fail; 1757*7887SLiane.Praza@Sun.COM } 1758*7887SLiane.Praza@Sun.COM 1759*7887SLiane.Praza@Sun.COM if (scf_pg_get_type(pg, pg_type, tbufsz) < 0) { 1760*7887SLiane.Praza@Sun.COM ret = -1; 1761*7887SLiane.Praza@Sun.COM goto fail; 1762*7887SLiane.Praza@Sun.COM } 1763*7887SLiane.Praza@Sun.COM p->pw_pgname = pg_name; 1764*7887SLiane.Praza@Sun.COM p->pw_pgtype = pg_type; 1765*7887SLiane.Praza@Sun.COM 1766*7887SLiane.Praza@Sun.COM ret = scf_pg_get_parent_snaplevel(pg, snaplvl); 1767*7887SLiane.Praza@Sun.COM if (ret == -1) { 1768*7887SLiane.Praza@Sun.COM switch (scf_error()) { 1769*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 1770*7887SLiane.Praza@Sun.COM /* Parent type doesn't match. Keep looking. */ 1771*7887SLiane.Praza@Sun.COM break; 1772*7887SLiane.Praza@Sun.COM 1773*7887SLiane.Praza@Sun.COM case SCF_ERROR_DELETED: 1774*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_BOUND: 1775*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1776*7887SLiane.Praza@Sun.COM /* Pass these back to the caller. */ 1777*7887SLiane.Praza@Sun.COM goto fail; 1778*7887SLiane.Praza@Sun.COM 1779*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 1780*7887SLiane.Praza@Sun.COM default: 1781*7887SLiane.Praza@Sun.COM assert(0); 1782*7887SLiane.Praza@Sun.COM abort(); 1783*7887SLiane.Praza@Sun.COM } 1784*7887SLiane.Praza@Sun.COM 1785*7887SLiane.Praza@Sun.COM /* 1786*7887SLiane.Praza@Sun.COM * No snapshot. We'll use 'editing' by default since 1787*7887SLiane.Praza@Sun.COM * snap and snapbuf are NULL. 1788*7887SLiane.Praza@Sun.COM */ 1789*7887SLiane.Praza@Sun.COM p->pw_snapname = NULL; 1790*7887SLiane.Praza@Sun.COM 1791*7887SLiane.Praza@Sun.COM } else { 1792*7887SLiane.Praza@Sun.COM if ((snap = scf_snapshot_create(h)) == NULL) { 1793*7887SLiane.Praza@Sun.COM ret = -1; 1794*7887SLiane.Praza@Sun.COM goto fail; 1795*7887SLiane.Praza@Sun.COM } 1796*7887SLiane.Praza@Sun.COM 1797*7887SLiane.Praza@Sun.COM ret = scf_snaplevel_get_parent(snaplvl, snap); 1798*7887SLiane.Praza@Sun.COM if (ret == -1) { 1799*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1800*7887SLiane.Praza@Sun.COM ret = -1; 1801*7887SLiane.Praza@Sun.COM goto fail; 1802*7887SLiane.Praza@Sun.COM } else { 1803*7887SLiane.Praza@Sun.COM assert(0); 1804*7887SLiane.Praza@Sun.COM abort(); 1805*7887SLiane.Praza@Sun.COM } 1806*7887SLiane.Praza@Sun.COM } 1807*7887SLiane.Praza@Sun.COM 1808*7887SLiane.Praza@Sun.COM /* Grab snapshot name while we're here. */ 1809*7887SLiane.Praza@Sun.COM if ((snapbuf = malloc(nbufsz)) == NULL) { 1810*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1811*7887SLiane.Praza@Sun.COM ret = -1; 1812*7887SLiane.Praza@Sun.COM goto fail; 1813*7887SLiane.Praza@Sun.COM } 1814*7887SLiane.Praza@Sun.COM if (scf_snapshot_get_name(snap, snapbuf, nbufsz) < 0) { 1815*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1816*7887SLiane.Praza@Sun.COM ret = -1; 1817*7887SLiane.Praza@Sun.COM goto fail; 1818*7887SLiane.Praza@Sun.COM } else { 1819*7887SLiane.Praza@Sun.COM assert(0); 1820*7887SLiane.Praza@Sun.COM abort(); 1821*7887SLiane.Praza@Sun.COM } 1822*7887SLiane.Praza@Sun.COM } 1823*7887SLiane.Praza@Sun.COM p->pw_snapname = snapbuf; 1824*7887SLiane.Praza@Sun.COM 1825*7887SLiane.Praza@Sun.COM ret = scf_snapshot_get_parent(snap, inst); 1826*7887SLiane.Praza@Sun.COM if (ret == -1) { 1827*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1828*7887SLiane.Praza@Sun.COM ret = -1; 1829*7887SLiane.Praza@Sun.COM goto fail; 1830*7887SLiane.Praza@Sun.COM } else { 1831*7887SLiane.Praza@Sun.COM assert(0); 1832*7887SLiane.Praza@Sun.COM abort(); 1833*7887SLiane.Praza@Sun.COM } 1834*7887SLiane.Praza@Sun.COM } 1835*7887SLiane.Praza@Sun.COM 1836*7887SLiane.Praza@Sun.COM _walk_template_instances(NULL, inst, snap, 1837*7887SLiane.Praza@Sun.COM (walk_template_inst_func_t *)find_pg_match, p, flags); 1838*7887SLiane.Praza@Sun.COM } 1839*7887SLiane.Praza@Sun.COM 1840*7887SLiane.Praza@Sun.COM /* No snapshot parent. Go looking for instance parent. */ 1841*7887SLiane.Praza@Sun.COM if (snapbuf == NULL) { 1842*7887SLiane.Praza@Sun.COM /* First look for instance parent. */ 1843*7887SLiane.Praza@Sun.COM ret = scf_pg_get_parent_instance(pg, inst); 1844*7887SLiane.Praza@Sun.COM if (ret == 0) { 1845*7887SLiane.Praza@Sun.COM _walk_template_instances(NULL, inst, snap, 1846*7887SLiane.Praza@Sun.COM (walk_template_inst_func_t *)find_pg_match, 1847*7887SLiane.Praza@Sun.COM p, flags); 1848*7887SLiane.Praza@Sun.COM /* OK, check for service parent */ 1849*7887SLiane.Praza@Sun.COM } else if (ret == -1 && 1850*7887SLiane.Praza@Sun.COM scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) { 1851*7887SLiane.Praza@Sun.COM ret = scf_pg_get_parent_service(pg, svc); 1852*7887SLiane.Praza@Sun.COM if (ret == 0) { 1853*7887SLiane.Praza@Sun.COM _walk_template_instances(svc, NULL, snap, 1854*7887SLiane.Praza@Sun.COM (walk_template_inst_func_t *)find_pg_match, 1855*7887SLiane.Praza@Sun.COM p, flags); 1856*7887SLiane.Praza@Sun.COM } else { 1857*7887SLiane.Praza@Sun.COM switch (scf_error()) { 1858*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 1859*7887SLiane.Praza@Sun.COM (void) scf_set_error( 1860*7887SLiane.Praza@Sun.COM SCF_ERROR_NOT_FOUND); 1861*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 1862*7887SLiane.Praza@Sun.COM 1863*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONNECTION_BROKEN: 1864*7887SLiane.Praza@Sun.COM case SCF_ERROR_DELETED: 1865*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 1866*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_BOUND: 1867*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1868*7887SLiane.Praza@Sun.COM ret = -1; 1869*7887SLiane.Praza@Sun.COM goto fail; 1870*7887SLiane.Praza@Sun.COM 1871*7887SLiane.Praza@Sun.COM default: 1872*7887SLiane.Praza@Sun.COM assert(0); 1873*7887SLiane.Praza@Sun.COM abort(); 1874*7887SLiane.Praza@Sun.COM } 1875*7887SLiane.Praza@Sun.COM } 1876*7887SLiane.Praza@Sun.COM } else { 1877*7887SLiane.Praza@Sun.COM ret = -1; 1878*7887SLiane.Praza@Sun.COM goto fail; 1879*7887SLiane.Praza@Sun.COM } 1880*7887SLiane.Praza@Sun.COM } 1881*7887SLiane.Praza@Sun.COM 1882*7887SLiane.Praza@Sun.COM if (p->pw_pg != NULL) { 1883*7887SLiane.Praza@Sun.COM pg_tmpl->pt_h = h; 1884*7887SLiane.Praza@Sun.COM pg_tmpl->pt_pg = p->pw_pg; 1885*7887SLiane.Praza@Sun.COM pg_tmpl->pt_inst = p->pw_inst; 1886*7887SLiane.Praza@Sun.COM pg_tmpl->pt_snap = p->pw_snap; 1887*7887SLiane.Praza@Sun.COM pg_tmpl->pt_svc = p->pw_svc; 1888*7887SLiane.Praza@Sun.COM pg_tmpl->pt_populated = 1; 1889*7887SLiane.Praza@Sun.COM free(p->pw_tmpl_pgname); 1890*7887SLiane.Praza@Sun.COM ret = 0; 1891*7887SLiane.Praza@Sun.COM goto done; 1892*7887SLiane.Praza@Sun.COM } 1893*7887SLiane.Praza@Sun.COM 1894*7887SLiane.Praza@Sun.COM ret = -1; 1895*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 1896*7887SLiane.Praza@Sun.COM 1897*7887SLiane.Praza@Sun.COM fail: 1898*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 1899*7887SLiane.Praza@Sun.COM scf_service_destroy(svc); 1900*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(snap); 1901*7887SLiane.Praza@Sun.COM done: 1902*7887SLiane.Praza@Sun.COM free(snapbuf); 1903*7887SLiane.Praza@Sun.COM free(fmribuf); 1904*7887SLiane.Praza@Sun.COM free(pg_name); 1905*7887SLiane.Praza@Sun.COM free(pg_type); 1906*7887SLiane.Praza@Sun.COM free(p); 1907*7887SLiane.Praza@Sun.COM scf_snaplevel_destroy(snaplvl); 1908*7887SLiane.Praza@Sun.COM return (ret); 1909*7887SLiane.Praza@Sun.COM } 1910*7887SLiane.Praza@Sun.COM 1911*7887SLiane.Praza@Sun.COM /* 1912*7887SLiane.Praza@Sun.COM * int scf_tmpl_get_by_pg_name() 1913*7887SLiane.Praza@Sun.COM * 1914*7887SLiane.Praza@Sun.COM * Get a template by a combination of the name and type. Either name 1915*7887SLiane.Praza@Sun.COM * or type can be null, which indicates a wildcard. flags may be 1916*7887SLiane.Praza@Sun.COM * SCF_PG_TMPL_FLAG_CURRENT (use current properties rather than 1917*7887SLiane.Praza@Sun.COM * the defined or running snapshot), and SCF_PG_TMPL_FLAG_EXACT (match 1918*7887SLiane.Praza@Sun.COM * only templates defined by the FMRI in question, not by its restarter 1919*7887SLiane.Praza@Sun.COM * or globally). Returns 0 on success and -1 on error, and sets 1920*7887SLiane.Praza@Sun.COM * scf_error() to: 1921*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 1922*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 1923*7887SLiane.Praza@Sun.COM * The connection to the repository was lost. 1924*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 1925*7887SLiane.Praza@Sun.COM * The instance has been deleted. 1926*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 1927*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 1928*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 1929*7887SLiane.Praza@Sun.COM * FMRI isn't valid, pg_name is too long to look for a template, or 1930*7887SLiane.Praza@Sun.COM * snapshot specified isn't a valid name 1931*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 1932*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 1933*7887SLiane.Praza@Sun.COM * The server does not have adequate resources to complete the request. 1934*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 1935*7887SLiane.Praza@Sun.COM * The handle is not currently bound. 1936*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 1937*7887SLiane.Praza@Sun.COM * Object matching FMRI doesn't exist in the repository, or snapshot 1938*7887SLiane.Praza@Sun.COM * doesn't exist. 1939*7887SLiane.Praza@Sun.COM */ 1940*7887SLiane.Praza@Sun.COM int 1941*7887SLiane.Praza@Sun.COM scf_tmpl_get_by_pg_name(const char *fmri, const char *snapshot, 1942*7887SLiane.Praza@Sun.COM const char *pg_name, const char *pg_type, scf_pg_tmpl_t *pg_tmpl, int flags) 1943*7887SLiane.Praza@Sun.COM { 1944*7887SLiane.Praza@Sun.COM scf_instance_t *inst = NULL; 1945*7887SLiane.Praza@Sun.COM scf_service_t *svc = NULL; 1946*7887SLiane.Praza@Sun.COM scf_snapshot_t *snap = NULL; 1947*7887SLiane.Praza@Sun.COM pg_tmpl_walk_t *p; 1948*7887SLiane.Praza@Sun.COM scf_handle_t *h; 1949*7887SLiane.Praza@Sun.COM int ret; 1950*7887SLiane.Praza@Sun.COM 1951*7887SLiane.Praza@Sun.COM assert(pg_tmpl != NULL); 1952*7887SLiane.Praza@Sun.COM h = pg_tmpl->pt_h; 1953*7887SLiane.Praza@Sun.COM assert(h != NULL); 1954*7887SLiane.Praza@Sun.COM 1955*7887SLiane.Praza@Sun.COM scf_tmpl_pg_reset(pg_tmpl); 1956*7887SLiane.Praza@Sun.COM 1957*7887SLiane.Praza@Sun.COM if ((inst = scf_instance_create(h)) == NULL || 1958*7887SLiane.Praza@Sun.COM (svc = scf_service_create(h)) == NULL) { 1959*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 1960*7887SLiane.Praza@Sun.COM return (-1); 1961*7887SLiane.Praza@Sun.COM } 1962*7887SLiane.Praza@Sun.COM 1963*7887SLiane.Praza@Sun.COM p = calloc(1, sizeof (pg_tmpl_walk_t)); 1964*7887SLiane.Praza@Sun.COM if (p == NULL) { 1965*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 1966*7887SLiane.Praza@Sun.COM goto fail_zalloc; 1967*7887SLiane.Praza@Sun.COM } 1968*7887SLiane.Praza@Sun.COM 1969*7887SLiane.Praza@Sun.COM ret = scf_handle_decode_fmri(h, fmri, NULL, NULL, inst, NULL, 1970*7887SLiane.Praza@Sun.COM NULL, SCF_DECODE_FMRI_EXACT); 1971*7887SLiane.Praza@Sun.COM if (ret == 0) { 1972*7887SLiane.Praza@Sun.COM scf_service_destroy(svc); 1973*7887SLiane.Praza@Sun.COM svc = NULL; 1974*7887SLiane.Praza@Sun.COM } else if (ret != 0 && 1975*7887SLiane.Praza@Sun.COM scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) { 1976*7887SLiane.Praza@Sun.COM ret = scf_handle_decode_fmri(h, fmri, NULL, svc, 1977*7887SLiane.Praza@Sun.COM NULL, NULL, NULL, SCF_DECODE_FMRI_EXACT); 1978*7887SLiane.Praza@Sun.COM if (ret == 0) { 1979*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 1980*7887SLiane.Praza@Sun.COM inst = NULL; 1981*7887SLiane.Praza@Sun.COM } 1982*7887SLiane.Praza@Sun.COM } 1983*7887SLiane.Praza@Sun.COM if (ret != 0) { 1984*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 1985*7887SLiane.Praza@Sun.COM goto fail; 1986*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 1987*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 1988*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 1989*7887SLiane.Praza@Sun.COM goto fail; 1990*7887SLiane.Praza@Sun.COM 1991*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 1992*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 1993*7887SLiane.Praza@Sun.COM goto fail; 1994*7887SLiane.Praza@Sun.COM 1995*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 1996*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 1997*7887SLiane.Praza@Sun.COM default: 1998*7887SLiane.Praza@Sun.COM assert(0); 1999*7887SLiane.Praza@Sun.COM abort(); 2000*7887SLiane.Praza@Sun.COM } 2001*7887SLiane.Praza@Sun.COM } 2002*7887SLiane.Praza@Sun.COM 2003*7887SLiane.Praza@Sun.COM assert(svc == NULL || inst == NULL); 2004*7887SLiane.Praza@Sun.COM assert(svc != NULL || inst != NULL); 2005*7887SLiane.Praza@Sun.COM 2006*7887SLiane.Praza@Sun.COM if (inst != NULL) { 2007*7887SLiane.Praza@Sun.COM if (snapshot == NULL || strcmp(snapshot, "running") == 0 || 2008*7887SLiane.Praza@Sun.COM (flags & SCF_PG_TMPL_FLAG_CURRENT) == 2009*7887SLiane.Praza@Sun.COM SCF_PG_TMPL_FLAG_CURRENT) { 2010*7887SLiane.Praza@Sun.COM if (_get_snapshot(inst, NULL, &snap) == -1) 2011*7887SLiane.Praza@Sun.COM goto fail; 2012*7887SLiane.Praza@Sun.COM } else { 2013*7887SLiane.Praza@Sun.COM if (_get_snapshot(inst, snapshot, &snap) == -1) { 2014*7887SLiane.Praza@Sun.COM goto fail; 2015*7887SLiane.Praza@Sun.COM } else if (scf_error() == SCF_ERROR_NOT_FOUND) { 2016*7887SLiane.Praza@Sun.COM goto fail; 2017*7887SLiane.Praza@Sun.COM } 2018*7887SLiane.Praza@Sun.COM } 2019*7887SLiane.Praza@Sun.COM } else { 2020*7887SLiane.Praza@Sun.COM /* If we have a service fmri, snapshot is ignored. */ 2021*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(snap); 2022*7887SLiane.Praza@Sun.COM snap = NULL; 2023*7887SLiane.Praza@Sun.COM } 2024*7887SLiane.Praza@Sun.COM 2025*7887SLiane.Praza@Sun.COM p->pw_snapname = snapshot; 2026*7887SLiane.Praza@Sun.COM p->pw_pgname = pg_name; 2027*7887SLiane.Praza@Sun.COM p->pw_pgtype = pg_type; 2028*7887SLiane.Praza@Sun.COM 2029*7887SLiane.Praza@Sun.COM /* 2030*7887SLiane.Praza@Sun.COM * For each of instance, restarter, global 2031*7887SLiane.Praza@Sun.COM * - check for a tm_pg_pattern_nt_<name> matching type 2032*7887SLiane.Praza@Sun.COM * - check for a tm_pg_pattern_t_<type> matching type 2033*7887SLiane.Praza@Sun.COM * - check for any tm_pg_pattern_ 2034*7887SLiane.Praza@Sun.COM * Currently plan to return the most specific match only. 2035*7887SLiane.Praza@Sun.COM */ 2036*7887SLiane.Praza@Sun.COM _walk_template_instances(svc, inst, snap, 2037*7887SLiane.Praza@Sun.COM (walk_template_inst_func_t *)find_pg_match, p, flags); 2038*7887SLiane.Praza@Sun.COM 2039*7887SLiane.Praza@Sun.COM if (p->pw_pg != NULL) { 2040*7887SLiane.Praza@Sun.COM pg_tmpl->pt_h = h; 2041*7887SLiane.Praza@Sun.COM pg_tmpl->pt_pg = p->pw_pg; 2042*7887SLiane.Praza@Sun.COM pg_tmpl->pt_inst = p->pw_inst; 2043*7887SLiane.Praza@Sun.COM pg_tmpl->pt_snap = p->pw_snap; 2044*7887SLiane.Praza@Sun.COM pg_tmpl->pt_svc = p->pw_svc; 2045*7887SLiane.Praza@Sun.COM pg_tmpl->pt_populated = 1; 2046*7887SLiane.Praza@Sun.COM free(p->pw_tmpl_pgname); 2047*7887SLiane.Praza@Sun.COM free(p); 2048*7887SLiane.Praza@Sun.COM return (0); 2049*7887SLiane.Praza@Sun.COM } 2050*7887SLiane.Praza@Sun.COM 2051*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 2052*7887SLiane.Praza@Sun.COM fail: 2053*7887SLiane.Praza@Sun.COM free(p); 2054*7887SLiane.Praza@Sun.COM fail_zalloc: 2055*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 2056*7887SLiane.Praza@Sun.COM scf_service_destroy(svc); 2057*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(snap); 2058*7887SLiane.Praza@Sun.COM return (-1); 2059*7887SLiane.Praza@Sun.COM } 2060*7887SLiane.Praza@Sun.COM 2061*7887SLiane.Praza@Sun.COM /* 2062*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to _CONNECTION_BROKEN, 2063*7887SLiane.Praza@Sun.COM * _DELETED, _NO_RESOURCES, or _NOT_BOUND. 2064*7887SLiane.Praza@Sun.COM */ 2065*7887SLiane.Praza@Sun.COM static scf_iter_t * 2066*7887SLiane.Praza@Sun.COM _get_svc_or_inst_iter(scf_handle_t *h, scf_pg_tmpl_t *t) 2067*7887SLiane.Praza@Sun.COM { 2068*7887SLiane.Praza@Sun.COM scf_iter_t *iter; 2069*7887SLiane.Praza@Sun.COM int ret; 2070*7887SLiane.Praza@Sun.COM 2071*7887SLiane.Praza@Sun.COM assert(t->pt_svc != NULL || t->pt_inst != NULL); 2072*7887SLiane.Praza@Sun.COM assert(t->pt_svc == NULL || t->pt_inst == NULL); 2073*7887SLiane.Praza@Sun.COM 2074*7887SLiane.Praza@Sun.COM if ((iter = scf_iter_create(h)) == NULL) { 2075*7887SLiane.Praza@Sun.COM return (NULL); 2076*7887SLiane.Praza@Sun.COM } 2077*7887SLiane.Praza@Sun.COM 2078*7887SLiane.Praza@Sun.COM /* Iterate on property groups of type template_pg_pattern */ 2079*7887SLiane.Praza@Sun.COM 2080*7887SLiane.Praza@Sun.COM if (t->pt_inst != NULL) 2081*7887SLiane.Praza@Sun.COM ret = scf_iter_instance_pgs_typed_composed(iter, 2082*7887SLiane.Praza@Sun.COM t->pt_inst, t->pt_snap, 2083*7887SLiane.Praza@Sun.COM SCF_GROUP_TEMPLATE_PG_PATTERN); 2084*7887SLiane.Praza@Sun.COM if (t->pt_svc != NULL) 2085*7887SLiane.Praza@Sun.COM ret = scf_iter_service_pgs_typed(iter, t->pt_svc, 2086*7887SLiane.Praza@Sun.COM SCF_GROUP_TEMPLATE_PG_PATTERN); 2087*7887SLiane.Praza@Sun.COM 2088*7887SLiane.Praza@Sun.COM if (ret != 0) { 2089*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 2090*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 2091*7887SLiane.Praza@Sun.COM return (NULL); 2092*7887SLiane.Praza@Sun.COM } else { 2093*7887SLiane.Praza@Sun.COM assert(0); 2094*7887SLiane.Praza@Sun.COM abort(); 2095*7887SLiane.Praza@Sun.COM } 2096*7887SLiane.Praza@Sun.COM } 2097*7887SLiane.Praza@Sun.COM 2098*7887SLiane.Praza@Sun.COM return (iter); 2099*7887SLiane.Praza@Sun.COM } 2100*7887SLiane.Praza@Sun.COM 2101*7887SLiane.Praza@Sun.COM /* 2102*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to: 2103*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2104*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2105*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2106*7887SLiane.Praza@Sun.COM * SCF_HANDLE_DESTROYED 2107*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2108*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 2109*7887SLiane.Praza@Sun.COM * Handle argument is NULL, or snaphot is not a valid snapshot name. 2110*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 2111*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 2112*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 2113*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 2114*7887SLiane.Praza@Sun.COM */ 2115*7887SLiane.Praza@Sun.COM static scf_iter_t * 2116*7887SLiane.Praza@Sun.COM _get_next_iterator(scf_handle_t *h, scf_pg_tmpl_t *t, const char *snapshot, 2117*7887SLiane.Praza@Sun.COM int exact) 2118*7887SLiane.Praza@Sun.COM { 2119*7887SLiane.Praza@Sun.COM scf_iter_t *iter = NULL; 2120*7887SLiane.Praza@Sun.COM ssize_t limit; 2121*7887SLiane.Praza@Sun.COM 2122*7887SLiane.Praza@Sun.COM limit = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 2123*7887SLiane.Praza@Sun.COM assert(limit != 0); 2124*7887SLiane.Praza@Sun.COM 2125*7887SLiane.Praza@Sun.COM /* 2126*7887SLiane.Praza@Sun.COM * Check what level we last iterated on: none, service, 2127*7887SLiane.Praza@Sun.COM * restarter, or global. Make sure that if one in the middle 2128*7887SLiane.Praza@Sun.COM * doesn't exist, we move on to the next entity. 2129*7887SLiane.Praza@Sun.COM */ 2130*7887SLiane.Praza@Sun.COM do { 2131*7887SLiane.Praza@Sun.COM switch (t->pt_iter_last) { 2132*7887SLiane.Praza@Sun.COM case SCF__TMPL_ITER_NONE: 2133*7887SLiane.Praza@Sun.COM t->pt_iter_last = SCF__TMPL_ITER_INST; 2134*7887SLiane.Praza@Sun.COM t->pt_inst = t->pt_orig_inst; 2135*7887SLiane.Praza@Sun.COM t->pt_svc = t->pt_orig_svc; 2136*7887SLiane.Praza@Sun.COM break; 2137*7887SLiane.Praza@Sun.COM 2138*7887SLiane.Praza@Sun.COM case SCF__TMPL_ITER_INST: 2139*7887SLiane.Praza@Sun.COM /* 2140*7887SLiane.Praza@Sun.COM * Don't go any further than the specified instance 2141*7887SLiane.Praza@Sun.COM * if exact was set. 2142*7887SLiane.Praza@Sun.COM */ 2143*7887SLiane.Praza@Sun.COM if (exact == 1) { 2144*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 2145*7887SLiane.Praza@Sun.COM goto fail; 2146*7887SLiane.Praza@Sun.COM } 2147*7887SLiane.Praza@Sun.COM t->pt_iter_last = SCF__TMPL_ITER_RESTARTER; 2148*7887SLiane.Praza@Sun.COM t->pt_inst = _get_restarter_inst(h, t->pt_orig_svc, 2149*7887SLiane.Praza@Sun.COM t->pt_orig_inst, t->pt_snap); 2150*7887SLiane.Praza@Sun.COM t->pt_svc = NULL; 2151*7887SLiane.Praza@Sun.COM break; 2152*7887SLiane.Praza@Sun.COM 2153*7887SLiane.Praza@Sun.COM case SCF__TMPL_ITER_RESTARTER: 2154*7887SLiane.Praza@Sun.COM t->pt_iter_last = SCF__TMPL_ITER_GLOBAL; 2155*7887SLiane.Praza@Sun.COM t->pt_inst = _get_global_inst(h); 2156*7887SLiane.Praza@Sun.COM t->pt_svc = NULL; 2157*7887SLiane.Praza@Sun.COM break; 2158*7887SLiane.Praza@Sun.COM 2159*7887SLiane.Praza@Sun.COM case SCF__TMPL_ITER_GLOBAL: 2160*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 2161*7887SLiane.Praza@Sun.COM return (NULL); 2162*7887SLiane.Praza@Sun.COM 2163*7887SLiane.Praza@Sun.COM default: 2164*7887SLiane.Praza@Sun.COM assert(0); 2165*7887SLiane.Praza@Sun.COM abort(); 2166*7887SLiane.Praza@Sun.COM } 2167*7887SLiane.Praza@Sun.COM } while (t->pt_inst == NULL && t->pt_svc == NULL); 2168*7887SLiane.Praza@Sun.COM 2169*7887SLiane.Praza@Sun.COM /* Set pt_snap to the snapshot for this instance */ 2170*7887SLiane.Praza@Sun.COM if (t->pt_inst != NULL) { 2171*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(t->pt_snap); 2172*7887SLiane.Praza@Sun.COM if (_get_snapshot(t->pt_inst, snapshot, 2173*7887SLiane.Praza@Sun.COM &t->pt_snap) == -1) 2174*7887SLiane.Praza@Sun.COM goto fail; 2175*7887SLiane.Praza@Sun.COM } 2176*7887SLiane.Praza@Sun.COM 2177*7887SLiane.Praza@Sun.COM 2178*7887SLiane.Praza@Sun.COM iter = _get_svc_or_inst_iter(h, t); 2179*7887SLiane.Praza@Sun.COM fail: 2180*7887SLiane.Praza@Sun.COM return (iter); 2181*7887SLiane.Praza@Sun.COM } 2182*7887SLiane.Praza@Sun.COM 2183*7887SLiane.Praza@Sun.COM /* 2184*7887SLiane.Praza@Sun.COM * scf_pg_tmpl_t *scf_tmpl_pg_create(scf_handle_t *) 2185*7887SLiane.Praza@Sun.COM * 2186*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to _INVALID_ARGUMENT 2187*7887SLiane.Praza@Sun.COM * or _NO_MEMORY. 2188*7887SLiane.Praza@Sun.COM */ 2189*7887SLiane.Praza@Sun.COM scf_pg_tmpl_t * 2190*7887SLiane.Praza@Sun.COM scf_tmpl_pg_create(scf_handle_t *handle) 2191*7887SLiane.Praza@Sun.COM { 2192*7887SLiane.Praza@Sun.COM scf_pg_tmpl_t *pg_tmpl = NULL; 2193*7887SLiane.Praza@Sun.COM 2194*7887SLiane.Praza@Sun.COM if (handle == NULL) { 2195*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 2196*7887SLiane.Praza@Sun.COM return (NULL); 2197*7887SLiane.Praza@Sun.COM } 2198*7887SLiane.Praza@Sun.COM pg_tmpl = calloc(1, sizeof (scf_pg_tmpl_t)); 2199*7887SLiane.Praza@Sun.COM if (pg_tmpl == NULL) 2200*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 2201*7887SLiane.Praza@Sun.COM else 2202*7887SLiane.Praza@Sun.COM pg_tmpl->pt_h = handle; 2203*7887SLiane.Praza@Sun.COM 2204*7887SLiane.Praza@Sun.COM return (pg_tmpl); 2205*7887SLiane.Praza@Sun.COM } 2206*7887SLiane.Praza@Sun.COM 2207*7887SLiane.Praza@Sun.COM /* 2208*7887SLiane.Praza@Sun.COM * Retrieves name or type of a template pg. 2209*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 2210*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2211*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2212*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2213*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 2214*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2215*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 2216*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 2217*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 2218*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 2219*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 2220*7887SLiane.Praza@Sun.COM * pname property is not SCF_TYPE_ASTRING or has more than one value. 2221*7887SLiane.Praza@Sun.COM */ 2222*7887SLiane.Praza@Sun.COM static ssize_t 2223*7887SLiane.Praza@Sun.COM _scf_tmpl_prop_value(scf_propertygroup_t *pg, const char *pname, char **out) 2224*7887SLiane.Praza@Sun.COM { 2225*7887SLiane.Praza@Sun.COM assert(strcmp(pname, SCF_PROPERTY_TM_NAME) == 0 || 2226*7887SLiane.Praza@Sun.COM strcmp(pname, SCF_PROPERTY_TM_TYPE) == 0); 2227*7887SLiane.Praza@Sun.COM 2228*7887SLiane.Praza@Sun.COM *out = _scf_read_single_astring_from_pg(pg, pname); 2229*7887SLiane.Praza@Sun.COM 2230*7887SLiane.Praza@Sun.COM if (*out != NULL && *out[0] == '\0') { 2231*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NONE); 2232*7887SLiane.Praza@Sun.COM free(*out); 2233*7887SLiane.Praza@Sun.COM *out = strdup(SCF_TMPL_WILDCARD); 2234*7887SLiane.Praza@Sun.COM if (*out == NULL) 2235*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 2236*7887SLiane.Praza@Sun.COM } 2237*7887SLiane.Praza@Sun.COM if (*out == NULL) { 2238*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 2239*7887SLiane.Praza@Sun.COM return (-1); 2240*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 2241*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 2242*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 2243*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 2244*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 2245*7887SLiane.Praza@Sun.COM return (-1); 2246*7887SLiane.Praza@Sun.COM 2247*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 2248*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 2249*7887SLiane.Praza@Sun.COM default: 2250*7887SLiane.Praza@Sun.COM assert(0); 2251*7887SLiane.Praza@Sun.COM abort(); 2252*7887SLiane.Praza@Sun.COM } 2253*7887SLiane.Praza@Sun.COM } 2254*7887SLiane.Praza@Sun.COM 2255*7887SLiane.Praza@Sun.COM return (strlen(*out)); 2256*7887SLiane.Praza@Sun.COM } 2257*7887SLiane.Praza@Sun.COM 2258*7887SLiane.Praza@Sun.COM /* 2259*7887SLiane.Praza@Sun.COM * int scf_tmpl_iter_pgs() 2260*7887SLiane.Praza@Sun.COM * 2261*7887SLiane.Praza@Sun.COM * Iterates through the property group templates for the fmri given. 2262*7887SLiane.Praza@Sun.COM * When t is uninitialized or reset, sets t to the first property group 2263*7887SLiane.Praza@Sun.COM * template in fmri. On subsequent calls, sets t to the next property group 2264*7887SLiane.Praza@Sun.COM * template in frmi. 2265*7887SLiane.Praza@Sun.COM * Returns 1 on success, 0 when no property group templates are left to 2266*7887SLiane.Praza@Sun.COM * iterate, -1 on error. 2267*7887SLiane.Praza@Sun.COM * The flags argument may include SCF_PG_TMPL_FLAG_REQUIRED, 2268*7887SLiane.Praza@Sun.COM * SCF_PG_TMPL_FLAG_CURRENT, and/or SCF_PG_TMPL_FLAG_EXACT. 2269*7887SLiane.Praza@Sun.COM * 2270*7887SLiane.Praza@Sun.COM * Returns -1 on error and sets scf_error() to: 2271*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2272*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2273*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2274*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 2275*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2276*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 2277*7887SLiane.Praza@Sun.COM * The handle argument is NULL, fmri is invalid, or snapshot is invalid. 2278*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 2279*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 2280*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 2281*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 2282*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 2283*7887SLiane.Praza@Sun.COM */ 2284*7887SLiane.Praza@Sun.COM int 2285*7887SLiane.Praza@Sun.COM scf_tmpl_iter_pgs(scf_pg_tmpl_t *t, const char *fmri, const char *snapshot, 2286*7887SLiane.Praza@Sun.COM const char *type, int flags) 2287*7887SLiane.Praza@Sun.COM { 2288*7887SLiane.Praza@Sun.COM scf_handle_t *h; 2289*7887SLiane.Praza@Sun.COM scf_service_t *svc = NULL; 2290*7887SLiane.Praza@Sun.COM scf_instance_t *inst = NULL; 2291*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg = NULL; 2292*7887SLiane.Praza@Sun.COM scf_snapshot_t *snap = NULL; 2293*7887SLiane.Praza@Sun.COM scf_pg_tmpl_t *pg_tmpl = NULL; 2294*7887SLiane.Praza@Sun.COM int err; 2295*7887SLiane.Praza@Sun.COM int found = 0; 2296*7887SLiane.Praza@Sun.COM char *tmpl_type; 2297*7887SLiane.Praza@Sun.COM uint8_t required; 2298*7887SLiane.Praza@Sun.COM int ret; 2299*7887SLiane.Praza@Sun.COM 2300*7887SLiane.Praza@Sun.COM if (t == NULL) { 2301*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 2302*7887SLiane.Praza@Sun.COM return (-1); 2303*7887SLiane.Praza@Sun.COM } 2304*7887SLiane.Praza@Sun.COM 2305*7887SLiane.Praza@Sun.COM h = t->pt_h; 2306*7887SLiane.Praza@Sun.COM 2307*7887SLiane.Praza@Sun.COM if (t->pt_populated == 0) { 2308*7887SLiane.Praza@Sun.COM if ((svc = scf_service_create(h)) == NULL || 2309*7887SLiane.Praza@Sun.COM (inst = scf_instance_create(h)) == NULL || 2310*7887SLiane.Praza@Sun.COM (pg = scf_pg_create(h)) == NULL) { 2311*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2312*7887SLiane.Praza@Sun.COM } 2313*7887SLiane.Praza@Sun.COM 2314*7887SLiane.Praza@Sun.COM ret = scf_handle_decode_fmri(h, fmri, NULL, NULL, inst, NULL, 2315*7887SLiane.Praza@Sun.COM NULL, SCF_DECODE_FMRI_EXACT); 2316*7887SLiane.Praza@Sun.COM if (ret == 0) { 2317*7887SLiane.Praza@Sun.COM scf_service_destroy(svc); 2318*7887SLiane.Praza@Sun.COM svc = NULL; 2319*7887SLiane.Praza@Sun.COM } else if (ret != 0 && 2320*7887SLiane.Praza@Sun.COM scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) { 2321*7887SLiane.Praza@Sun.COM ret = scf_handle_decode_fmri(h, fmri, NULL, svc, 2322*7887SLiane.Praza@Sun.COM NULL, NULL, NULL, SCF_DECODE_FMRI_EXACT); 2323*7887SLiane.Praza@Sun.COM if (ret == 0) { 2324*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 2325*7887SLiane.Praza@Sun.COM inst = NULL; 2326*7887SLiane.Praza@Sun.COM } 2327*7887SLiane.Praza@Sun.COM } 2328*7887SLiane.Praza@Sun.COM 2329*7887SLiane.Praza@Sun.COM if (ret != 0) { 2330*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 2331*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2332*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 2333*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 2334*7887SLiane.Praza@Sun.COM (void) scf_set_error( 2335*7887SLiane.Praza@Sun.COM SCF_ERROR_INVALID_ARGUMENT); 2336*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2337*7887SLiane.Praza@Sun.COM 2338*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 2339*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 2340*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2341*7887SLiane.Praza@Sun.COM 2342*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 2343*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 2344*7887SLiane.Praza@Sun.COM default: 2345*7887SLiane.Praza@Sun.COM assert(0); 2346*7887SLiane.Praza@Sun.COM abort(); 2347*7887SLiane.Praza@Sun.COM } 2348*7887SLiane.Praza@Sun.COM } 2349*7887SLiane.Praza@Sun.COM 2350*7887SLiane.Praza@Sun.COM assert(svc == NULL || inst == NULL); 2351*7887SLiane.Praza@Sun.COM assert(svc != NULL || inst != NULL); 2352*7887SLiane.Praza@Sun.COM 2353*7887SLiane.Praza@Sun.COM if (inst != NULL) { 2354*7887SLiane.Praza@Sun.COM if (snapshot == NULL || 2355*7887SLiane.Praza@Sun.COM strcmp(snapshot, "running") == 0 || 2356*7887SLiane.Praza@Sun.COM (flags & SCF_PG_TMPL_FLAG_CURRENT) == 2357*7887SLiane.Praza@Sun.COM SCF_PG_TMPL_FLAG_CURRENT) { 2358*7887SLiane.Praza@Sun.COM if (_get_snapshot(inst, NULL, &snap) == -1) 2359*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2360*7887SLiane.Praza@Sun.COM } else { 2361*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NONE); 2362*7887SLiane.Praza@Sun.COM if (_get_snapshot(inst, snapshot, 2363*7887SLiane.Praza@Sun.COM &snap) == -1) { 2364*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2365*7887SLiane.Praza@Sun.COM } else if (scf_error() == SCF_ERROR_NOT_FOUND) { 2366*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2367*7887SLiane.Praza@Sun.COM } 2368*7887SLiane.Praza@Sun.COM } 2369*7887SLiane.Praza@Sun.COM } else { 2370*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(snap); 2371*7887SLiane.Praza@Sun.COM snap = NULL; 2372*7887SLiane.Praza@Sun.COM } 2373*7887SLiane.Praza@Sun.COM 2374*7887SLiane.Praza@Sun.COM pg_tmpl = t; 2375*7887SLiane.Praza@Sun.COM pg_tmpl->pt_orig_inst = inst; 2376*7887SLiane.Praza@Sun.COM pg_tmpl->pt_orig_svc = svc; 2377*7887SLiane.Praza@Sun.COM pg_tmpl->pt_snap = snap; 2378*7887SLiane.Praza@Sun.COM pg_tmpl->pt_is_iter = 1; 2379*7887SLiane.Praza@Sun.COM pg_tmpl->pt_iter_last = SCF__TMPL_ITER_NONE; 2380*7887SLiane.Praza@Sun.COM pg_tmpl->pt_pg = pg; 2381*7887SLiane.Praza@Sun.COM pg_tmpl->pt_populated = 1; 2382*7887SLiane.Praza@Sun.COM } else { 2383*7887SLiane.Praza@Sun.COM if (t->pt_is_iter != 1) { 2384*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 2385*7887SLiane.Praza@Sun.COM return (-1); 2386*7887SLiane.Praza@Sun.COM } 2387*7887SLiane.Praza@Sun.COM pg_tmpl = t; 2388*7887SLiane.Praza@Sun.COM assert(pg_tmpl->pt_pg != NULL); 2389*7887SLiane.Praza@Sun.COM } 2390*7887SLiane.Praza@Sun.COM 2391*7887SLiane.Praza@Sun.COM if (pg_tmpl->pt_iter == NULL) { 2392*7887SLiane.Praza@Sun.COM pg_tmpl->pt_iter = _get_next_iterator(h, pg_tmpl, snapshot, 2393*7887SLiane.Praza@Sun.COM (flags & SCF_PG_TMPL_FLAG_EXACT) ? 1 : 0); 2394*7887SLiane.Praza@Sun.COM if (pg_tmpl->pt_iter == NULL) { 2395*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_NOT_FOUND) 2396*7887SLiane.Praza@Sun.COM return (0); 2397*7887SLiane.Praza@Sun.COM else 2398*7887SLiane.Praza@Sun.COM return (-1); 2399*7887SLiane.Praza@Sun.COM } 2400*7887SLiane.Praza@Sun.COM } 2401*7887SLiane.Praza@Sun.COM 2402*7887SLiane.Praza@Sun.COM while (found == 0) { 2403*7887SLiane.Praza@Sun.COM while ((err = scf_iter_next_pg(pg_tmpl->pt_iter, 2404*7887SLiane.Praza@Sun.COM pg_tmpl->pt_pg)) != 1) { 2405*7887SLiane.Praza@Sun.COM if (err == -1) { 2406*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 2407*7887SLiane.Praza@Sun.COM return (-1); 2408*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 2409*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 2410*7887SLiane.Praza@Sun.COM return (-1); 2411*7887SLiane.Praza@Sun.COM 2412*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 2413*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 2414*7887SLiane.Praza@Sun.COM default: 2415*7887SLiane.Praza@Sun.COM assert(0); 2416*7887SLiane.Praza@Sun.COM abort(); 2417*7887SLiane.Praza@Sun.COM } 2418*7887SLiane.Praza@Sun.COM } else if (err == 0) { 2419*7887SLiane.Praza@Sun.COM /* This iteration is done. Get the next one */ 2420*7887SLiane.Praza@Sun.COM scf_iter_destroy(pg_tmpl->pt_iter); 2421*7887SLiane.Praza@Sun.COM pg_tmpl->pt_iter = _get_next_iterator(h, 2422*7887SLiane.Praza@Sun.COM pg_tmpl, snapshot, 2423*7887SLiane.Praza@Sun.COM (flags & SCF_PG_TMPL_FLAG_EXACT) ? 1 : 0); 2424*7887SLiane.Praza@Sun.COM if (pg_tmpl->pt_iter == NULL) { 2425*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_NOT_FOUND) 2426*7887SLiane.Praza@Sun.COM return (0); 2427*7887SLiane.Praza@Sun.COM else 2428*7887SLiane.Praza@Sun.COM return (-1); 2429*7887SLiane.Praza@Sun.COM } 2430*7887SLiane.Praza@Sun.COM continue; 2431*7887SLiane.Praza@Sun.COM } else { 2432*7887SLiane.Praza@Sun.COM assert(0); 2433*7887SLiane.Praza@Sun.COM abort(); 2434*7887SLiane.Praza@Sun.COM } 2435*7887SLiane.Praza@Sun.COM } 2436*7887SLiane.Praza@Sun.COM 2437*7887SLiane.Praza@Sun.COM /* 2438*7887SLiane.Praza@Sun.COM * Discard pgs which don't exist at the right scoping. This 2439*7887SLiane.Praza@Sun.COM * check also makes sure that if we're looking at, for 2440*7887SLiane.Praza@Sun.COM * example, svc:/system/svc/restarter:default, that we 2441*7887SLiane.Praza@Sun.COM * don't hand back the same property groups twice. 2442*7887SLiane.Praza@Sun.COM */ 2443*7887SLiane.Praza@Sun.COM switch (t->pt_iter_last) { 2444*7887SLiane.Praza@Sun.COM case SCF__TMPL_ITER_INST: 2445*7887SLiane.Praza@Sun.COM ret = check_target_match(pg_tmpl->pt_pg, 2446*7887SLiane.Praza@Sun.COM SCF_TM_TARGET_THIS); 2447*7887SLiane.Praza@Sun.COM break; 2448*7887SLiane.Praza@Sun.COM case SCF__TMPL_ITER_RESTARTER: 2449*7887SLiane.Praza@Sun.COM ret = check_target_match(pg_tmpl->pt_pg, 2450*7887SLiane.Praza@Sun.COM SCF_TM_TARGET_DELEGATE); 2451*7887SLiane.Praza@Sun.COM break; 2452*7887SLiane.Praza@Sun.COM case SCF__TMPL_ITER_GLOBAL: 2453*7887SLiane.Praza@Sun.COM ret = check_target_match(pg_tmpl->pt_pg, 2454*7887SLiane.Praza@Sun.COM SCF_TM_TARGET_ALL); 2455*7887SLiane.Praza@Sun.COM break; 2456*7887SLiane.Praza@Sun.COM case SCF__TMPL_ITER_NONE: 2457*7887SLiane.Praza@Sun.COM default: 2458*7887SLiane.Praza@Sun.COM assert(0); 2459*7887SLiane.Praza@Sun.COM abort(); 2460*7887SLiane.Praza@Sun.COM } 2461*7887SLiane.Praza@Sun.COM 2462*7887SLiane.Praza@Sun.COM if (ret != 0) 2463*7887SLiane.Praza@Sun.COM continue; 2464*7887SLiane.Praza@Sun.COM 2465*7887SLiane.Praza@Sun.COM /* 2466*7887SLiane.Praza@Sun.COM * If walking only required property groups, check if 2467*7887SLiane.Praza@Sun.COM * the retrieved group is required. 2468*7887SLiane.Praza@Sun.COM */ 2469*7887SLiane.Praza@Sun.COM if (flags & SCF_PG_TMPL_FLAG_REQUIRED) { 2470*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_required(pg_tmpl, &required) == 0) { 2471*7887SLiane.Praza@Sun.COM if (required == 0) 2472*7887SLiane.Praza@Sun.COM continue; 2473*7887SLiane.Praza@Sun.COM } else { 2474*7887SLiane.Praza@Sun.COM return (-1); 2475*7887SLiane.Praza@Sun.COM } 2476*7887SLiane.Praza@Sun.COM } 2477*7887SLiane.Praza@Sun.COM 2478*7887SLiane.Praza@Sun.COM /* 2479*7887SLiane.Praza@Sun.COM * If type != NULL, check if type property matches. If no 2480*7887SLiane.Praza@Sun.COM * type property exists, consider it a match. 2481*7887SLiane.Praza@Sun.COM */ 2482*7887SLiane.Praza@Sun.COM if (type != NULL) { 2483*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(pg_tmpl, &tmpl_type) != -1) { 2484*7887SLiane.Praza@Sun.COM if (strcmp(tmpl_type, SCF_TMPL_WILDCARD) 2485*7887SLiane.Praza@Sun.COM == 0 || strcmp(type, tmpl_type) == 0) { 2486*7887SLiane.Praza@Sun.COM free(tmpl_type); 2487*7887SLiane.Praza@Sun.COM break; 2488*7887SLiane.Praza@Sun.COM } 2489*7887SLiane.Praza@Sun.COM free(tmpl_type); 2490*7887SLiane.Praza@Sun.COM } else if (scf_error() == SCF_ERROR_NOT_FOUND || 2491*7887SLiane.Praza@Sun.COM scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED || 2492*7887SLiane.Praza@Sun.COM scf_error() == SCF_ERROR_TYPE_MISMATCH) { 2493*7887SLiane.Praza@Sun.COM break; 2494*7887SLiane.Praza@Sun.COM } else { 2495*7887SLiane.Praza@Sun.COM return (-1); 2496*7887SLiane.Praza@Sun.COM } 2497*7887SLiane.Praza@Sun.COM } else { 2498*7887SLiane.Praza@Sun.COM break; 2499*7887SLiane.Praza@Sun.COM } 2500*7887SLiane.Praza@Sun.COM } 2501*7887SLiane.Praza@Sun.COM 2502*7887SLiane.Praza@Sun.COM return (1); 2503*7887SLiane.Praza@Sun.COM 2504*7887SLiane.Praza@Sun.COM fail_non_populated: 2505*7887SLiane.Praza@Sun.COM scf_service_destroy(svc); 2506*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 2507*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 2508*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(snap); 2509*7887SLiane.Praza@Sun.COM return (-1); 2510*7887SLiane.Praza@Sun.COM } 2511*7887SLiane.Praza@Sun.COM 2512*7887SLiane.Praza@Sun.COM void 2513*7887SLiane.Praza@Sun.COM scf_tmpl_pg_destroy(scf_pg_tmpl_t *t) 2514*7887SLiane.Praza@Sun.COM { 2515*7887SLiane.Praza@Sun.COM if (t == NULL) 2516*7887SLiane.Praza@Sun.COM return; 2517*7887SLiane.Praza@Sun.COM 2518*7887SLiane.Praza@Sun.COM scf_pg_destroy(t->pt_pg); 2519*7887SLiane.Praza@Sun.COM scf_instance_destroy(t->pt_inst); 2520*7887SLiane.Praza@Sun.COM if (t->pt_inst != t->pt_orig_inst) 2521*7887SLiane.Praza@Sun.COM scf_instance_destroy(t->pt_orig_inst); 2522*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(t->pt_snap); 2523*7887SLiane.Praza@Sun.COM scf_service_destroy(t->pt_orig_svc); 2524*7887SLiane.Praza@Sun.COM if (t->pt_svc != t->pt_orig_svc) 2525*7887SLiane.Praza@Sun.COM scf_service_destroy(t->pt_svc); 2526*7887SLiane.Praza@Sun.COM scf_iter_destroy(t->pt_iter); 2527*7887SLiane.Praza@Sun.COM free(t); 2528*7887SLiane.Praza@Sun.COM } 2529*7887SLiane.Praza@Sun.COM 2530*7887SLiane.Praza@Sun.COM void 2531*7887SLiane.Praza@Sun.COM scf_tmpl_pg_reset(scf_pg_tmpl_t *t) 2532*7887SLiane.Praza@Sun.COM { 2533*7887SLiane.Praza@Sun.COM scf_pg_destroy(t->pt_pg); 2534*7887SLiane.Praza@Sun.COM t->pt_pg = NULL; 2535*7887SLiane.Praza@Sun.COM 2536*7887SLiane.Praza@Sun.COM scf_instance_destroy(t->pt_inst); 2537*7887SLiane.Praza@Sun.COM if (t->pt_inst != t->pt_orig_inst) 2538*7887SLiane.Praza@Sun.COM scf_instance_destroy(t->pt_orig_inst); 2539*7887SLiane.Praza@Sun.COM t->pt_inst = NULL; 2540*7887SLiane.Praza@Sun.COM t->pt_orig_inst = NULL; 2541*7887SLiane.Praza@Sun.COM 2542*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(t->pt_snap); 2543*7887SLiane.Praza@Sun.COM t->pt_snap = NULL; 2544*7887SLiane.Praza@Sun.COM 2545*7887SLiane.Praza@Sun.COM scf_service_destroy(t->pt_orig_svc); 2546*7887SLiane.Praza@Sun.COM if (t->pt_svc != t->pt_orig_svc) 2547*7887SLiane.Praza@Sun.COM scf_service_destroy(t->pt_svc); 2548*7887SLiane.Praza@Sun.COM t->pt_orig_svc = NULL; 2549*7887SLiane.Praza@Sun.COM t->pt_svc = NULL; 2550*7887SLiane.Praza@Sun.COM 2551*7887SLiane.Praza@Sun.COM scf_iter_destroy(t->pt_iter); 2552*7887SLiane.Praza@Sun.COM t->pt_iter = NULL; 2553*7887SLiane.Praza@Sun.COM 2554*7887SLiane.Praza@Sun.COM t->pt_populated = 0; 2555*7887SLiane.Praza@Sun.COM t->pt_is_iter = 0; 2556*7887SLiane.Praza@Sun.COM t->pt_iter_last = 0; 2557*7887SLiane.Praza@Sun.COM 2558*7887SLiane.Praza@Sun.COM /* Do not reset t->pt_h. */ 2559*7887SLiane.Praza@Sun.COM } 2560*7887SLiane.Praza@Sun.COM 2561*7887SLiane.Praza@Sun.COM /* 2562*7887SLiane.Praza@Sun.COM * int scf_tmpl_get_by_prop() 2563*7887SLiane.Praza@Sun.COM * 2564*7887SLiane.Praza@Sun.COM * Get the property template given a property group template and property 2565*7887SLiane.Praza@Sun.COM * name. No flags are currently defined for this function. 2566*7887SLiane.Praza@Sun.COM * 2567*7887SLiane.Praza@Sun.COM * Returns NULL on failure, and sets scf_error(): 2568*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2569*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2570*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2571*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 2572*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2573*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 2574*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 2575*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 2576*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 2577*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 2578*7887SLiane.Praza@Sun.COM * Template object matching property doesn't exist in the repository. 2579*7887SLiane.Praza@Sun.COM * SCF_ERROR_TYPE_MISMATCH 2580*7887SLiane.Praza@Sun.COM * Matching template object is the wrong type in the repository. 2581*7887SLiane.Praza@Sun.COM */ 2582*7887SLiane.Praza@Sun.COM int 2583*7887SLiane.Praza@Sun.COM scf_tmpl_get_by_prop(scf_pg_tmpl_t *t, const char *prop, 2584*7887SLiane.Praza@Sun.COM scf_prop_tmpl_t *prop_tmpl, int flags) 2585*7887SLiane.Praza@Sun.COM { 2586*7887SLiane.Praza@Sun.COM char *tmpl_prop_name; 2587*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg = NULL; 2588*7887SLiane.Praza@Sun.COM char *pg_type; 2589*7887SLiane.Praza@Sun.COM int found = 0; 2590*7887SLiane.Praza@Sun.COM 2591*7887SLiane.Praza@Sun.COM if (flags != 0) { 2592*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 2593*7887SLiane.Praza@Sun.COM return (-1); 2594*7887SLiane.Praza@Sun.COM } 2595*7887SLiane.Praza@Sun.COM 2596*7887SLiane.Praza@Sun.COM scf_tmpl_prop_reset(prop_tmpl); 2597*7887SLiane.Praza@Sun.COM if ((pg = scf_pg_create(scf_pg_handle(t->pt_pg))) == NULL) 2598*7887SLiane.Praza@Sun.COM return (-1); 2599*7887SLiane.Praza@Sun.COM 2600*7887SLiane.Praza@Sun.COM tmpl_prop_name = _tmpl_prop_name(prop, t); 2601*7887SLiane.Praza@Sun.COM if (tmpl_prop_name == NULL) { 2602*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 2603*7887SLiane.Praza@Sun.COM return (-1); 2604*7887SLiane.Praza@Sun.COM } 2605*7887SLiane.Praza@Sun.COM 2606*7887SLiane.Praza@Sun.COM if (_get_pg(t->pt_svc, t->pt_inst, t->pt_snap, 2607*7887SLiane.Praza@Sun.COM tmpl_prop_name, pg) != 0) { 2608*7887SLiane.Praza@Sun.COM if (!ismember(scf_error(), errors_server)) { 2609*7887SLiane.Praza@Sun.COM switch (scf_error()) { 2610*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 2611*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 2612*7887SLiane.Praza@Sun.COM break; 2613*7887SLiane.Praza@Sun.COM 2614*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 2615*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 2616*7887SLiane.Praza@Sun.COM default: 2617*7887SLiane.Praza@Sun.COM assert(0); 2618*7887SLiane.Praza@Sun.COM abort(); 2619*7887SLiane.Praza@Sun.COM } 2620*7887SLiane.Praza@Sun.COM } 2621*7887SLiane.Praza@Sun.COM } else { 2622*7887SLiane.Praza@Sun.COM /* 2623*7887SLiane.Praza@Sun.COM * We've only found a template property group if the type 2624*7887SLiane.Praza@Sun.COM * is correct. 2625*7887SLiane.Praza@Sun.COM */ 2626*7887SLiane.Praza@Sun.COM if ((pg_type = _scf_get_pg_type(pg)) != NULL && 2627*7887SLiane.Praza@Sun.COM strcmp(pg_type, SCF_GROUP_TEMPLATE_PROP_PATTERN) == 0) 2628*7887SLiane.Praza@Sun.COM found++; 2629*7887SLiane.Praza@Sun.COM else 2630*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TYPE_MISMATCH); 2631*7887SLiane.Praza@Sun.COM 2632*7887SLiane.Praza@Sun.COM 2633*7887SLiane.Praza@Sun.COM free(pg_type); 2634*7887SLiane.Praza@Sun.COM } 2635*7887SLiane.Praza@Sun.COM 2636*7887SLiane.Praza@Sun.COM if (found == 0) { 2637*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 2638*7887SLiane.Praza@Sun.COM free(tmpl_prop_name); 2639*7887SLiane.Praza@Sun.COM return (-1); 2640*7887SLiane.Praza@Sun.COM } 2641*7887SLiane.Praza@Sun.COM 2642*7887SLiane.Praza@Sun.COM prop_tmpl->prt_h = scf_pg_handle(t->pt_pg); 2643*7887SLiane.Praza@Sun.COM prop_tmpl->prt_t = t; 2644*7887SLiane.Praza@Sun.COM prop_tmpl->prt_pg = pg; 2645*7887SLiane.Praza@Sun.COM prop_tmpl->prt_pg_name = tmpl_prop_name; 2646*7887SLiane.Praza@Sun.COM prop_tmpl->prt_populated = 1; 2647*7887SLiane.Praza@Sun.COM 2648*7887SLiane.Praza@Sun.COM return (0); 2649*7887SLiane.Praza@Sun.COM } 2650*7887SLiane.Praza@Sun.COM 2651*7887SLiane.Praza@Sun.COM /* 2652*7887SLiane.Praza@Sun.COM * scf_prop_tmpl_t *scf_tmpl_prop_create(scf_handle_t *); 2653*7887SLiane.Praza@Sun.COM * 2654*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to _INVALID_ARGUMENT, or 2655*7887SLiane.Praza@Sun.COM * _NO_MEMORY. 2656*7887SLiane.Praza@Sun.COM */ 2657*7887SLiane.Praza@Sun.COM scf_prop_tmpl_t * 2658*7887SLiane.Praza@Sun.COM scf_tmpl_prop_create(scf_handle_t *handle) 2659*7887SLiane.Praza@Sun.COM { 2660*7887SLiane.Praza@Sun.COM scf_prop_tmpl_t *pt; 2661*7887SLiane.Praza@Sun.COM 2662*7887SLiane.Praza@Sun.COM if (handle == NULL) { 2663*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 2664*7887SLiane.Praza@Sun.COM return (NULL); 2665*7887SLiane.Praza@Sun.COM } 2666*7887SLiane.Praza@Sun.COM pt = calloc(1, sizeof (scf_prop_tmpl_t)); 2667*7887SLiane.Praza@Sun.COM if (pt == NULL) 2668*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 2669*7887SLiane.Praza@Sun.COM else 2670*7887SLiane.Praza@Sun.COM pt->prt_h = handle; 2671*7887SLiane.Praza@Sun.COM 2672*7887SLiane.Praza@Sun.COM return (pt); 2673*7887SLiane.Praza@Sun.COM } 2674*7887SLiane.Praza@Sun.COM 2675*7887SLiane.Praza@Sun.COM /* 2676*7887SLiane.Praza@Sun.COM * int scf_tmpl_iter_props() 2677*7887SLiane.Praza@Sun.COM * 2678*7887SLiane.Praza@Sun.COM * Iterates over all property templates defined in the specified property 2679*7887SLiane.Praza@Sun.COM * group template. The iterator state is stored on the property template 2680*7887SLiane.Praza@Sun.COM * data structure, and the data structure should be allocated with 2681*7887SLiane.Praza@Sun.COM * scf_tmpl_prop_create(). To continue the iteration, the previously 2682*7887SLiane.Praza@Sun.COM * returned structure should be passed in as an argument to this function. 2683*7887SLiane.Praza@Sun.COM * flags can include SCF_PROP_TMPL_FLAG_REQUIRED. The function returns 2684*7887SLiane.Praza@Sun.COM * 1 when a result was found, and 0 when the iteration is complete. 2685*7887SLiane.Praza@Sun.COM * 2686*7887SLiane.Praza@Sun.COM * Returns -1 on failure, and sets scf_error(): 2687*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2688*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2689*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2690*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 2691*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2692*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 2693*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 2694*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 2695*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 2696*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 2697*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 2698*7887SLiane.Praza@Sun.COM * Template data is invalid. One of the property templates in this 2699*7887SLiane.Praza@Sun.COM * pg_tmpl is malformed. 2700*7887SLiane.Praza@Sun.COM */ 2701*7887SLiane.Praza@Sun.COM int 2702*7887SLiane.Praza@Sun.COM scf_tmpl_iter_props(scf_pg_tmpl_t *t, scf_prop_tmpl_t *pt, int flags) 2703*7887SLiane.Praza@Sun.COM { 2704*7887SLiane.Praza@Sun.COM scf_prop_tmpl_t *prop_tmpl; 2705*7887SLiane.Praza@Sun.COM char *pg_pat; 2706*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 2707*7887SLiane.Praza@Sun.COM int err; 2708*7887SLiane.Praza@Sun.COM int ret; 2709*7887SLiane.Praza@Sun.COM ssize_t size = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 2710*7887SLiane.Praza@Sun.COM uint8_t required; 2711*7887SLiane.Praza@Sun.COM scf_handle_t *h; 2712*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg = NULL; 2713*7887SLiane.Praza@Sun.COM scf_iter_t *iter = NULL; 2714*7887SLiane.Praza@Sun.COM 2715*7887SLiane.Praza@Sun.COM assert(size != 0); 2716*7887SLiane.Praza@Sun.COM if (t == NULL || pt == NULL) { 2717*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 2718*7887SLiane.Praza@Sun.COM return (-1); 2719*7887SLiane.Praza@Sun.COM } 2720*7887SLiane.Praza@Sun.COM 2721*7887SLiane.Praza@Sun.COM assert(t->pt_inst == NULL || t->pt_svc == NULL); 2722*7887SLiane.Praza@Sun.COM assert(t->pt_inst != NULL || t->pt_svc != NULL); 2723*7887SLiane.Praza@Sun.COM 2724*7887SLiane.Praza@Sun.COM if ((pg_name = malloc(size)) == NULL) { 2725*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 2726*7887SLiane.Praza@Sun.COM return (-1); 2727*7887SLiane.Praza@Sun.COM } 2728*7887SLiane.Praza@Sun.COM 2729*7887SLiane.Praza@Sun.COM if (pt->prt_populated == 0) { 2730*7887SLiane.Praza@Sun.COM if ((h = scf_pg_handle(t->pt_pg)) == NULL) 2731*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2732*7887SLiane.Praza@Sun.COM 2733*7887SLiane.Praza@Sun.COM if ((pg = scf_pg_create(h)) == NULL || 2734*7887SLiane.Praza@Sun.COM (iter = scf_iter_create(h)) == NULL) 2735*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2736*7887SLiane.Praza@Sun.COM 2737*7887SLiane.Praza@Sun.COM if (t->pt_inst != NULL) 2738*7887SLiane.Praza@Sun.COM err = scf_iter_instance_pgs_typed_composed(iter, 2739*7887SLiane.Praza@Sun.COM t->pt_inst, t->pt_snap, 2740*7887SLiane.Praza@Sun.COM SCF_GROUP_TEMPLATE_PROP_PATTERN); 2741*7887SLiane.Praza@Sun.COM else if (t->pt_svc != NULL) 2742*7887SLiane.Praza@Sun.COM err = scf_iter_service_pgs_typed(iter, t->pt_svc, 2743*7887SLiane.Praza@Sun.COM SCF_GROUP_TEMPLATE_PROP_PATTERN); 2744*7887SLiane.Praza@Sun.COM 2745*7887SLiane.Praza@Sun.COM if (err != 0) { 2746*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 2747*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2748*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 2749*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 2750*7887SLiane.Praza@Sun.COM goto fail_non_populated; 2751*7887SLiane.Praza@Sun.COM 2752*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 2753*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 2754*7887SLiane.Praza@Sun.COM default: 2755*7887SLiane.Praza@Sun.COM assert(0); 2756*7887SLiane.Praza@Sun.COM abort(); 2757*7887SLiane.Praza@Sun.COM } 2758*7887SLiane.Praza@Sun.COM 2759*7887SLiane.Praza@Sun.COM } 2760*7887SLiane.Praza@Sun.COM prop_tmpl = pt; 2761*7887SLiane.Praza@Sun.COM prop_tmpl->prt_t = t; 2762*7887SLiane.Praza@Sun.COM prop_tmpl->prt_populated = 1; 2763*7887SLiane.Praza@Sun.COM prop_tmpl->prt_pg = pg; 2764*7887SLiane.Praza@Sun.COM prop_tmpl->prt_iter = iter; 2765*7887SLiane.Praza@Sun.COM } else { 2766*7887SLiane.Praza@Sun.COM prop_tmpl = pt; 2767*7887SLiane.Praza@Sun.COM } 2768*7887SLiane.Praza@Sun.COM 2769*7887SLiane.Praza@Sun.COM while ((err = scf_iter_next_pg(prop_tmpl->prt_iter, 2770*7887SLiane.Praza@Sun.COM prop_tmpl->prt_pg)) > 0) { 2771*7887SLiane.Praza@Sun.COM /* 2772*7887SLiane.Praza@Sun.COM * Check if the name matches the appropriate property 2773*7887SLiane.Praza@Sun.COM * group template name. 2774*7887SLiane.Praza@Sun.COM */ 2775*7887SLiane.Praza@Sun.COM pg_pat = _scf_read_single_astring_from_pg(prop_tmpl->prt_pg, 2776*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_PG_PATTERN); 2777*7887SLiane.Praza@Sun.COM if (pg_pat == NULL) { 2778*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 2779*7887SLiane.Praza@Sun.COM uu_free(pg_name); 2780*7887SLiane.Praza@Sun.COM return (-1); 2781*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 2782*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 2783*7887SLiane.Praza@Sun.COM continue; 2784*7887SLiane.Praza@Sun.COM 2785*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 2786*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 2787*7887SLiane.Praza@Sun.COM (void) scf_set_error( 2788*7887SLiane.Praza@Sun.COM SCF_ERROR_TEMPLATE_INVALID); 2789*7887SLiane.Praza@Sun.COM free(pg_name); 2790*7887SLiane.Praza@Sun.COM return (-1); 2791*7887SLiane.Praza@Sun.COM 2792*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 2793*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 2794*7887SLiane.Praza@Sun.COM default: 2795*7887SLiane.Praza@Sun.COM assert(0); 2796*7887SLiane.Praza@Sun.COM abort(); 2797*7887SLiane.Praza@Sun.COM } 2798*7887SLiane.Praza@Sun.COM } 2799*7887SLiane.Praza@Sun.COM if ((ret = scf_pg_get_name(t->pt_pg, pg_name, size)) <= 0) { 2800*7887SLiane.Praza@Sun.COM free(pg_pat); 2801*7887SLiane.Praza@Sun.COM if (ret == 0) 2802*7887SLiane.Praza@Sun.COM continue; 2803*7887SLiane.Praza@Sun.COM 2804*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 2805*7887SLiane.Praza@Sun.COM free(pg_name); 2806*7887SLiane.Praza@Sun.COM return (-1); 2807*7887SLiane.Praza@Sun.COM } else { 2808*7887SLiane.Praza@Sun.COM assert(0); 2809*7887SLiane.Praza@Sun.COM abort(); 2810*7887SLiane.Praza@Sun.COM } 2811*7887SLiane.Praza@Sun.COM } 2812*7887SLiane.Praza@Sun.COM if (strcmp(pg_pat, pg_name) != 0) { 2813*7887SLiane.Praza@Sun.COM free(pg_pat); 2814*7887SLiane.Praza@Sun.COM continue; 2815*7887SLiane.Praza@Sun.COM } 2816*7887SLiane.Praza@Sun.COM free(pg_pat); 2817*7887SLiane.Praza@Sun.COM 2818*7887SLiane.Praza@Sun.COM /* 2819*7887SLiane.Praza@Sun.COM * If walking only required properties, check if 2820*7887SLiane.Praza@Sun.COM * the retrieved property is required. 2821*7887SLiane.Praza@Sun.COM */ 2822*7887SLiane.Praza@Sun.COM if (flags & SCF_PROP_TMPL_FLAG_REQUIRED) { 2823*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_required(prop_tmpl, &required) == 0) { 2824*7887SLiane.Praza@Sun.COM if (required == 0) 2825*7887SLiane.Praza@Sun.COM continue; 2826*7887SLiane.Praza@Sun.COM } else { 2827*7887SLiane.Praza@Sun.COM free(pg_name); 2828*7887SLiane.Praza@Sun.COM return (-1); 2829*7887SLiane.Praza@Sun.COM } 2830*7887SLiane.Praza@Sun.COM } 2831*7887SLiane.Praza@Sun.COM free(pg_name); 2832*7887SLiane.Praza@Sun.COM return (0); 2833*7887SLiane.Praza@Sun.COM } 2834*7887SLiane.Praza@Sun.COM 2835*7887SLiane.Praza@Sun.COM if (err == -1) { 2836*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 2837*7887SLiane.Praza@Sun.COM free(pg_name); 2838*7887SLiane.Praza@Sun.COM return (-1); 2839*7887SLiane.Praza@Sun.COM } else { 2840*7887SLiane.Praza@Sun.COM assert(0); 2841*7887SLiane.Praza@Sun.COM abort(); 2842*7887SLiane.Praza@Sun.COM } 2843*7887SLiane.Praza@Sun.COM } else if (err == 0) { 2844*7887SLiane.Praza@Sun.COM scf_iter_destroy(prop_tmpl->prt_iter); 2845*7887SLiane.Praza@Sun.COM prop_tmpl->prt_iter = NULL; 2846*7887SLiane.Praza@Sun.COM prop_tmpl->prt_populated = 0; 2847*7887SLiane.Praza@Sun.COM } 2848*7887SLiane.Praza@Sun.COM free(pg_name); 2849*7887SLiane.Praza@Sun.COM 2850*7887SLiane.Praza@Sun.COM return (1); 2851*7887SLiane.Praza@Sun.COM 2852*7887SLiane.Praza@Sun.COM fail_non_populated: 2853*7887SLiane.Praza@Sun.COM free(pg_name); 2854*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 2855*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 2856*7887SLiane.Praza@Sun.COM return (-1); 2857*7887SLiane.Praza@Sun.COM } 2858*7887SLiane.Praza@Sun.COM 2859*7887SLiane.Praza@Sun.COM void 2860*7887SLiane.Praza@Sun.COM scf_tmpl_prop_destroy(scf_prop_tmpl_t *t) 2861*7887SLiane.Praza@Sun.COM { 2862*7887SLiane.Praza@Sun.COM if (t == NULL) 2863*7887SLiane.Praza@Sun.COM return; 2864*7887SLiane.Praza@Sun.COM 2865*7887SLiane.Praza@Sun.COM scf_pg_destroy(t->prt_pg); 2866*7887SLiane.Praza@Sun.COM free(t->prt_pg_name); 2867*7887SLiane.Praza@Sun.COM free(t->prt_iter); 2868*7887SLiane.Praza@Sun.COM free(t); 2869*7887SLiane.Praza@Sun.COM } 2870*7887SLiane.Praza@Sun.COM 2871*7887SLiane.Praza@Sun.COM void 2872*7887SLiane.Praza@Sun.COM scf_tmpl_prop_reset(scf_prop_tmpl_t *t) 2873*7887SLiane.Praza@Sun.COM { 2874*7887SLiane.Praza@Sun.COM scf_pg_destroy(t->prt_pg); 2875*7887SLiane.Praza@Sun.COM t->prt_pg = NULL; 2876*7887SLiane.Praza@Sun.COM 2877*7887SLiane.Praza@Sun.COM free(t->prt_pg_name); 2878*7887SLiane.Praza@Sun.COM t->prt_pg_name = NULL; 2879*7887SLiane.Praza@Sun.COM 2880*7887SLiane.Praza@Sun.COM free(t->prt_iter); 2881*7887SLiane.Praza@Sun.COM t->prt_iter = NULL; 2882*7887SLiane.Praza@Sun.COM 2883*7887SLiane.Praza@Sun.COM t->prt_populated = 0; 2884*7887SLiane.Praza@Sun.COM t->prt_h = NULL; 2885*7887SLiane.Praza@Sun.COM t->prt_t = NULL; 2886*7887SLiane.Praza@Sun.COM } 2887*7887SLiane.Praza@Sun.COM 2888*7887SLiane.Praza@Sun.COM /* 2889*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 2890*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2891*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2892*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2893*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 2894*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2895*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 2896*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 2897*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 2898*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 2899*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 2900*7887SLiane.Praza@Sun.COM * The name of the template property group (the pname property) has 2901*7887SLiane.Praza@Sun.COM * an improper repository format and is not type astring or has 2902*7887SLiane.Praza@Sun.COM * more than one value. 2903*7887SLiane.Praza@Sun.COM */ 2904*7887SLiane.Praza@Sun.COM ssize_t 2905*7887SLiane.Praza@Sun.COM scf_tmpl_pg_name(const scf_pg_tmpl_t *t, char **out) 2906*7887SLiane.Praza@Sun.COM { 2907*7887SLiane.Praza@Sun.COM return (_scf_tmpl_prop_value(t->pt_pg, SCF_PROPERTY_TM_NAME, out)); 2908*7887SLiane.Praza@Sun.COM } 2909*7887SLiane.Praza@Sun.COM 2910*7887SLiane.Praza@Sun.COM /* 2911*7887SLiane.Praza@Sun.COM * returns an allocated string that must be freed 2912*7887SLiane.Praza@Sun.COM * 2913*7887SLiane.Praza@Sun.COM * Returns NULL on failure, sets scf_error() to: 2914*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2915*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2916*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2917*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 2918*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2919*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 2920*7887SLiane.Praza@Sun.COM * name not a valid property name 2921*7887SLiane.Praza@Sun.COM * name and locale are too long to make a property name 2922*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 2923*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 2924*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 2925*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 2926*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 2927*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 2928*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 2929*7887SLiane.Praza@Sun.COM */ 2930*7887SLiane.Praza@Sun.COM static char * 2931*7887SLiane.Praza@Sun.COM _read_localized_astring_from_pg(scf_propertygroup_t *pg, const char *name, 2932*7887SLiane.Praza@Sun.COM const char *locale) 2933*7887SLiane.Praza@Sun.COM { 2934*7887SLiane.Praza@Sun.COM char *str; 2935*7887SLiane.Praza@Sun.COM char *lname_prop; 2936*7887SLiane.Praza@Sun.COM 2937*7887SLiane.Praza@Sun.COM str = _add_locale_to_name(name, locale); 2938*7887SLiane.Praza@Sun.COM if (str == NULL) 2939*7887SLiane.Praza@Sun.COM return (NULL); 2940*7887SLiane.Praza@Sun.COM lname_prop = _scf_read_single_astring_from_pg(pg, str); 2941*7887SLiane.Praza@Sun.COM if (lname_prop == NULL) { 2942*7887SLiane.Praza@Sun.COM free(str); 2943*7887SLiane.Praza@Sun.COM if (scf_error() != SCF_ERROR_NOT_FOUND) 2944*7887SLiane.Praza@Sun.COM return (NULL); 2945*7887SLiane.Praza@Sun.COM str = _add_locale_to_name(name, "C"); 2946*7887SLiane.Praza@Sun.COM if (str == NULL) 2947*7887SLiane.Praza@Sun.COM return (NULL); 2948*7887SLiane.Praza@Sun.COM lname_prop = _scf_read_single_astring_from_pg(pg, str); 2949*7887SLiane.Praza@Sun.COM } 2950*7887SLiane.Praza@Sun.COM free(str); 2951*7887SLiane.Praza@Sun.COM if (lname_prop == NULL) { 2952*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_TYPE_MISMATCH || 2953*7887SLiane.Praza@Sun.COM scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) 2954*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 2955*7887SLiane.Praza@Sun.COM } 2956*7887SLiane.Praza@Sun.COM return (lname_prop); 2957*7887SLiane.Praza@Sun.COM } 2958*7887SLiane.Praza@Sun.COM 2959*7887SLiane.Praza@Sun.COM /* 2960*7887SLiane.Praza@Sun.COM * returns an allocated string that must be freed 2961*7887SLiane.Praza@Sun.COM * 2962*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 2963*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2964*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2965*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2966*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 2967*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2968*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 2969*7887SLiane.Praza@Sun.COM * locale is too long to make a valid property name 2970*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 2971*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 2972*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 2973*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 2974*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 2975*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 2976*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 2977*7887SLiane.Praza@Sun.COM */ 2978*7887SLiane.Praza@Sun.COM ssize_t 2979*7887SLiane.Praza@Sun.COM scf_tmpl_pg_common_name(const scf_pg_tmpl_t *t, const char *locale, char **out) 2980*7887SLiane.Praza@Sun.COM { 2981*7887SLiane.Praza@Sun.COM assert(out != NULL); 2982*7887SLiane.Praza@Sun.COM if ((*out = _read_localized_astring_from_pg(t->pt_pg, 2983*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_COMMON_NAME_PREFIX, locale)) == NULL) 2984*7887SLiane.Praza@Sun.COM return (-1); 2985*7887SLiane.Praza@Sun.COM 2986*7887SLiane.Praza@Sun.COM return (strlen(*out)); 2987*7887SLiane.Praza@Sun.COM } 2988*7887SLiane.Praza@Sun.COM 2989*7887SLiane.Praza@Sun.COM /* 2990*7887SLiane.Praza@Sun.COM * returns an allocated string that must be freed 2991*7887SLiane.Praza@Sun.COM * 2992*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 2993*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 2994*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 2995*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 2996*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 2997*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 2998*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 2999*7887SLiane.Praza@Sun.COM * locale is too long to make a valid property name 3000*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3001*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3002*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3003*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3004*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3005*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3006*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3007*7887SLiane.Praza@Sun.COM */ 3008*7887SLiane.Praza@Sun.COM ssize_t 3009*7887SLiane.Praza@Sun.COM scf_tmpl_pg_description(const scf_pg_tmpl_t *t, const char *locale, char **out) 3010*7887SLiane.Praza@Sun.COM { 3011*7887SLiane.Praza@Sun.COM assert(out != NULL); 3012*7887SLiane.Praza@Sun.COM if ((*out = _read_localized_astring_from_pg(t->pt_pg, 3013*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_DESCRIPTION_PREFIX, locale)) == NULL) 3014*7887SLiane.Praza@Sun.COM return (-1); 3015*7887SLiane.Praza@Sun.COM 3016*7887SLiane.Praza@Sun.COM return (strlen(*out)); 3017*7887SLiane.Praza@Sun.COM } 3018*7887SLiane.Praza@Sun.COM 3019*7887SLiane.Praza@Sun.COM /* 3020*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3021*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3022*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3023*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3024*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3025*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3026*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3027*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3028*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3029*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3030*7887SLiane.Praza@Sun.COM * 'type' property doesn't exist or exists and has no value. 3031*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3032*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3033*7887SLiane.Praza@Sun.COM * 'type' property is not SCF_TYPE_ASTRING or has more than one value. 3034*7887SLiane.Praza@Sun.COM */ 3035*7887SLiane.Praza@Sun.COM ssize_t 3036*7887SLiane.Praza@Sun.COM scf_tmpl_pg_type(const scf_pg_tmpl_t *t, char **out) 3037*7887SLiane.Praza@Sun.COM { 3038*7887SLiane.Praza@Sun.COM return (_scf_tmpl_prop_value(t->pt_pg, SCF_PROPERTY_TM_TYPE, out)); 3039*7887SLiane.Praza@Sun.COM } 3040*7887SLiane.Praza@Sun.COM 3041*7887SLiane.Praza@Sun.COM /* 3042*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 3043*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3044*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3045*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3046*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3047*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3048*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3049*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3050*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3051*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3052*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3053*7887SLiane.Praza@Sun.COM * required property is not SCF_TYPE_BOOLEAN or has more than one value. 3054*7887SLiane.Praza@Sun.COM */ 3055*7887SLiane.Praza@Sun.COM int 3056*7887SLiane.Praza@Sun.COM scf_tmpl_pg_required(const scf_pg_tmpl_t *t, uint8_t *out) 3057*7887SLiane.Praza@Sun.COM { 3058*7887SLiane.Praza@Sun.COM 3059*7887SLiane.Praza@Sun.COM if (_read_single_boolean_from_pg(t->pt_pg, SCF_PROPERTY_TM_REQUIRED, 3060*7887SLiane.Praza@Sun.COM out) == -1) { 3061*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3062*7887SLiane.Praza@Sun.COM return (-1); 3063*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3064*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3065*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3066*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3067*7887SLiane.Praza@Sun.COM return (-1); 3068*7887SLiane.Praza@Sun.COM 3069*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3070*7887SLiane.Praza@Sun.COM *out = 0; 3071*7887SLiane.Praza@Sun.COM return (0); 3072*7887SLiane.Praza@Sun.COM 3073*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3074*7887SLiane.Praza@Sun.COM default: 3075*7887SLiane.Praza@Sun.COM assert(0); 3076*7887SLiane.Praza@Sun.COM abort(); 3077*7887SLiane.Praza@Sun.COM } 3078*7887SLiane.Praza@Sun.COM } 3079*7887SLiane.Praza@Sun.COM 3080*7887SLiane.Praza@Sun.COM return (0); 3081*7887SLiane.Praza@Sun.COM } 3082*7887SLiane.Praza@Sun.COM 3083*7887SLiane.Praza@Sun.COM /* 3084*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3085*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3086*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3087*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3088*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3089*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3090*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3091*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3092*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3093*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3094*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3095*7887SLiane.Praza@Sun.COM * target property is not SCF_TYPE_ASTRING or has more than one value. 3096*7887SLiane.Praza@Sun.COM */ 3097*7887SLiane.Praza@Sun.COM ssize_t 3098*7887SLiane.Praza@Sun.COM scf_tmpl_pg_target(const scf_pg_tmpl_t *t, char **out) 3099*7887SLiane.Praza@Sun.COM { 3100*7887SLiane.Praza@Sun.COM *out = _scf_read_single_astring_from_pg(t->pt_pg, 3101*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_TARGET); 3102*7887SLiane.Praza@Sun.COM 3103*7887SLiane.Praza@Sun.COM if (*out == NULL) { 3104*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3105*7887SLiane.Praza@Sun.COM return (-1); 3106*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3107*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3108*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3109*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3110*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3111*7887SLiane.Praza@Sun.COM return (-1); 3112*7887SLiane.Praza@Sun.COM 3113*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3114*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3115*7887SLiane.Praza@Sun.COM default: 3116*7887SLiane.Praza@Sun.COM assert(0); 3117*7887SLiane.Praza@Sun.COM abort(); 3118*7887SLiane.Praza@Sun.COM } 3119*7887SLiane.Praza@Sun.COM } 3120*7887SLiane.Praza@Sun.COM 3121*7887SLiane.Praza@Sun.COM return (strlen(*out)); 3122*7887SLiane.Praza@Sun.COM } 3123*7887SLiane.Praza@Sun.COM 3124*7887SLiane.Praza@Sun.COM /* 3125*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3126*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3127*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3128*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3129*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3130*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3131*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3132*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3133*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3134*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3135*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3136*7887SLiane.Praza@Sun.COM */ 3137*7887SLiane.Praza@Sun.COM ssize_t 3138*7887SLiane.Praza@Sun.COM scf_tmpl_prop_name(const scf_prop_tmpl_t *t, char **out) 3139*7887SLiane.Praza@Sun.COM { 3140*7887SLiane.Praza@Sun.COM *out = _scf_read_single_astring_from_pg(t->prt_pg, 3141*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_NAME); 3142*7887SLiane.Praza@Sun.COM 3143*7887SLiane.Praza@Sun.COM if (*out != NULL && *out[0] == '\0') { 3144*7887SLiane.Praza@Sun.COM free(*out); 3145*7887SLiane.Praza@Sun.COM *out = NULL; 3146*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3147*7887SLiane.Praza@Sun.COM } 3148*7887SLiane.Praza@Sun.COM if (*out == NULL) { 3149*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3150*7887SLiane.Praza@Sun.COM return (-1); 3151*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3152*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3153*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3154*7887SLiane.Praza@Sun.COM case SCF_ERROR_TEMPLATE_INVALID: 3155*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3156*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3157*7887SLiane.Praza@Sun.COM return (-1); 3158*7887SLiane.Praza@Sun.COM 3159*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3160*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3161*7887SLiane.Praza@Sun.COM default: 3162*7887SLiane.Praza@Sun.COM assert(0); 3163*7887SLiane.Praza@Sun.COM abort(); 3164*7887SLiane.Praza@Sun.COM } 3165*7887SLiane.Praza@Sun.COM } 3166*7887SLiane.Praza@Sun.COM 3167*7887SLiane.Praza@Sun.COM return (strlen(*out)); 3168*7887SLiane.Praza@Sun.COM } 3169*7887SLiane.Praza@Sun.COM 3170*7887SLiane.Praza@Sun.COM /* 3171*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3172*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3173*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3174*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3175*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3176*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3177*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3178*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3179*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3180*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3181*7887SLiane.Praza@Sun.COM * 'type' property doesn't exist or exists and has no value. 3182*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3183*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3184*7887SLiane.Praza@Sun.COM * 'type' property is not SCF_TYPE_ASTRING, has more than one value, 3185*7887SLiane.Praza@Sun.COM * is SCF_TYPE_INVALID, or is the empty string. 3186*7887SLiane.Praza@Sun.COM */ 3187*7887SLiane.Praza@Sun.COM int 3188*7887SLiane.Praza@Sun.COM scf_tmpl_prop_type(const scf_prop_tmpl_t *t, scf_type_t *out) 3189*7887SLiane.Praza@Sun.COM { 3190*7887SLiane.Praza@Sun.COM char *type; 3191*7887SLiane.Praza@Sun.COM 3192*7887SLiane.Praza@Sun.COM type = _scf_read_single_astring_from_pg(t->prt_pg, 3193*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_TYPE); 3194*7887SLiane.Praza@Sun.COM if (type != NULL && type[0] == '\0') { 3195*7887SLiane.Praza@Sun.COM free(type); 3196*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 3197*7887SLiane.Praza@Sun.COM return (-1); 3198*7887SLiane.Praza@Sun.COM } 3199*7887SLiane.Praza@Sun.COM if (type == NULL) { 3200*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3201*7887SLiane.Praza@Sun.COM return (-1); 3202*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3203*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3204*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3205*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3206*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 3207*7887SLiane.Praza@Sun.COM 3208*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3209*7887SLiane.Praza@Sun.COM return (-1); 3210*7887SLiane.Praza@Sun.COM 3211*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3212*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3213*7887SLiane.Praza@Sun.COM default: 3214*7887SLiane.Praza@Sun.COM assert(0); 3215*7887SLiane.Praza@Sun.COM abort(); 3216*7887SLiane.Praza@Sun.COM } 3217*7887SLiane.Praza@Sun.COM } 3218*7887SLiane.Praza@Sun.COM 3219*7887SLiane.Praza@Sun.COM *out = scf_string_to_type(type); 3220*7887SLiane.Praza@Sun.COM free(type); 3221*7887SLiane.Praza@Sun.COM 3222*7887SLiane.Praza@Sun.COM if (*out == SCF_TYPE_INVALID) { 3223*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3224*7887SLiane.Praza@Sun.COM return (-1); 3225*7887SLiane.Praza@Sun.COM } 3226*7887SLiane.Praza@Sun.COM 3227*7887SLiane.Praza@Sun.COM return (0); 3228*7887SLiane.Praza@Sun.COM } 3229*7887SLiane.Praza@Sun.COM 3230*7887SLiane.Praza@Sun.COM /* 3231*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 3232*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3233*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3234*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3235*7887SLiane.Praza@Sun.COM * Property group which represents t was deleted. 3236*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3237*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3238*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3239*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3240*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3241*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3242*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3243*7887SLiane.Praza@Sun.COM * required property is not SCF_TYPE_ASTRING has more than one value. 3244*7887SLiane.Praza@Sun.COM */ 3245*7887SLiane.Praza@Sun.COM int 3246*7887SLiane.Praza@Sun.COM scf_tmpl_prop_required(const scf_prop_tmpl_t *t, uint8_t *out) 3247*7887SLiane.Praza@Sun.COM { 3248*7887SLiane.Praza@Sun.COM if (_read_single_boolean_from_pg(t->prt_pg, SCF_PROPERTY_TM_REQUIRED, 3249*7887SLiane.Praza@Sun.COM out) == -1) { 3250*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3251*7887SLiane.Praza@Sun.COM return (-1); 3252*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3253*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3254*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3255*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3256*7887SLiane.Praza@Sun.COM return (-1); 3257*7887SLiane.Praza@Sun.COM 3258*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3259*7887SLiane.Praza@Sun.COM *out = 0; 3260*7887SLiane.Praza@Sun.COM return (0); 3261*7887SLiane.Praza@Sun.COM 3262*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3263*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3264*7887SLiane.Praza@Sun.COM default: 3265*7887SLiane.Praza@Sun.COM assert(0); 3266*7887SLiane.Praza@Sun.COM abort(); 3267*7887SLiane.Praza@Sun.COM } 3268*7887SLiane.Praza@Sun.COM } 3269*7887SLiane.Praza@Sun.COM 3270*7887SLiane.Praza@Sun.COM return (0); 3271*7887SLiane.Praza@Sun.COM } 3272*7887SLiane.Praza@Sun.COM 3273*7887SLiane.Praza@Sun.COM /* 3274*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3275*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3276*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3277*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3278*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3279*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3280*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3281*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3282*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3283*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3284*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3285*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 3286*7887SLiane.Praza@Sun.COM * locale is too long to make a property name 3287*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3288*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3289*7887SLiane.Praza@Sun.COM * common_name property is not SCF_TYPE_ASTRING has more than one value. 3290*7887SLiane.Praza@Sun.COM */ 3291*7887SLiane.Praza@Sun.COM ssize_t 3292*7887SLiane.Praza@Sun.COM scf_tmpl_prop_common_name(const scf_prop_tmpl_t *t, const char *locale, 3293*7887SLiane.Praza@Sun.COM char **out) 3294*7887SLiane.Praza@Sun.COM { 3295*7887SLiane.Praza@Sun.COM assert(out != NULL); 3296*7887SLiane.Praza@Sun.COM if ((*out = _read_localized_astring_from_pg(t->prt_pg, 3297*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_COMMON_NAME_PREFIX, locale)) == NULL) 3298*7887SLiane.Praza@Sun.COM return (-1); 3299*7887SLiane.Praza@Sun.COM 3300*7887SLiane.Praza@Sun.COM return (strlen(*out)); 3301*7887SLiane.Praza@Sun.COM } 3302*7887SLiane.Praza@Sun.COM 3303*7887SLiane.Praza@Sun.COM /* 3304*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3305*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3306*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3307*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3308*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3309*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3310*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3311*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3312*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3313*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3314*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3315*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 3316*7887SLiane.Praza@Sun.COM * locale is too long to make a property name 3317*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3318*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3319*7887SLiane.Praza@Sun.COM * description property is not SCF_TYPE_ASTRING has more than one value. 3320*7887SLiane.Praza@Sun.COM */ 3321*7887SLiane.Praza@Sun.COM ssize_t 3322*7887SLiane.Praza@Sun.COM scf_tmpl_prop_description(const scf_prop_tmpl_t *t, const char *locale, 3323*7887SLiane.Praza@Sun.COM char **out) 3324*7887SLiane.Praza@Sun.COM { 3325*7887SLiane.Praza@Sun.COM assert(out != NULL); 3326*7887SLiane.Praza@Sun.COM if ((*out = _read_localized_astring_from_pg(t->prt_pg, 3327*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_DESCRIPTION_PREFIX, locale)) == NULL) 3328*7887SLiane.Praza@Sun.COM return (-1); 3329*7887SLiane.Praza@Sun.COM 3330*7887SLiane.Praza@Sun.COM return (strlen(*out)); 3331*7887SLiane.Praza@Sun.COM } 3332*7887SLiane.Praza@Sun.COM 3333*7887SLiane.Praza@Sun.COM /* 3334*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3335*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3336*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3337*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3338*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3339*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3340*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3341*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3342*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3343*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3344*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3345*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 3346*7887SLiane.Praza@Sun.COM * locale is too long to make a property name 3347*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3348*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3349*7887SLiane.Praza@Sun.COM * units property is not SCF_TYPE_ASTRING has more than one value. 3350*7887SLiane.Praza@Sun.COM */ 3351*7887SLiane.Praza@Sun.COM ssize_t 3352*7887SLiane.Praza@Sun.COM scf_tmpl_prop_units(const scf_prop_tmpl_t *t, const char *locale, char **out) 3353*7887SLiane.Praza@Sun.COM { 3354*7887SLiane.Praza@Sun.COM assert(out != NULL); 3355*7887SLiane.Praza@Sun.COM if ((*out = _read_localized_astring_from_pg(t->prt_pg, 3356*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_UNITS_PREFIX, locale)) == NULL) 3357*7887SLiane.Praza@Sun.COM return (-1); 3358*7887SLiane.Praza@Sun.COM 3359*7887SLiane.Praza@Sun.COM return (strlen(*out)); 3360*7887SLiane.Praza@Sun.COM } 3361*7887SLiane.Praza@Sun.COM 3362*7887SLiane.Praza@Sun.COM /* 3363*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3364*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3365*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3366*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3367*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3368*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3369*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3370*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3371*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3372*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3373*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3374*7887SLiane.Praza@Sun.COM * visibility property is not SCF_TYPE_ASTRING has more than one value. 3375*7887SLiane.Praza@Sun.COM */ 3376*7887SLiane.Praza@Sun.COM int 3377*7887SLiane.Praza@Sun.COM scf_tmpl_prop_visibility(const scf_prop_tmpl_t *t, uint8_t *out) 3378*7887SLiane.Praza@Sun.COM { 3379*7887SLiane.Praza@Sun.COM char *visibility; 3380*7887SLiane.Praza@Sun.COM 3381*7887SLiane.Praza@Sun.COM visibility = _scf_read_single_astring_from_pg(t->prt_pg, 3382*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_VISIBILITY); 3383*7887SLiane.Praza@Sun.COM if (visibility == NULL) { 3384*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3385*7887SLiane.Praza@Sun.COM return (-1); 3386*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3387*7887SLiane.Praza@Sun.COM /* prop doesn't exist we take the default value */ 3388*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3389*7887SLiane.Praza@Sun.COM *out = SCF_TMPL_VISIBILITY_READWRITE; 3390*7887SLiane.Praza@Sun.COM return (0); 3391*7887SLiane.Praza@Sun.COM 3392*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3393*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3394*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3395*7887SLiane.Praza@Sun.COM return (-1); 3396*7887SLiane.Praza@Sun.COM 3397*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3398*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3399*7887SLiane.Praza@Sun.COM default: 3400*7887SLiane.Praza@Sun.COM assert(0); 3401*7887SLiane.Praza@Sun.COM abort(); 3402*7887SLiane.Praza@Sun.COM } 3403*7887SLiane.Praza@Sun.COM } else if (strcmp(visibility, SCF_TM_VISIBILITY_READWRITE) == 0) { 3404*7887SLiane.Praza@Sun.COM *out = SCF_TMPL_VISIBILITY_READWRITE; 3405*7887SLiane.Praza@Sun.COM } else if (strcmp(visibility, SCF_TM_VISIBILITY_HIDDEN) == 0) { 3406*7887SLiane.Praza@Sun.COM *out = SCF_TMPL_VISIBILITY_HIDDEN; 3407*7887SLiane.Praza@Sun.COM } else if (strcmp(visibility, SCF_TM_VISIBILITY_READONLY) == 0) { 3408*7887SLiane.Praza@Sun.COM *out = SCF_TMPL_VISIBILITY_READONLY; 3409*7887SLiane.Praza@Sun.COM } else { 3410*7887SLiane.Praza@Sun.COM free(visibility); 3411*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3412*7887SLiane.Praza@Sun.COM return (-1); 3413*7887SLiane.Praza@Sun.COM } 3414*7887SLiane.Praza@Sun.COM 3415*7887SLiane.Praza@Sun.COM free(visibility); 3416*7887SLiane.Praza@Sun.COM return (0); 3417*7887SLiane.Praza@Sun.COM } 3418*7887SLiane.Praza@Sun.COM 3419*7887SLiane.Praza@Sun.COM /* 3420*7887SLiane.Praza@Sun.COM * Return an allocated string containing the value that must be freed 3421*7887SLiane.Praza@Sun.COM * with free(). 3422*7887SLiane.Praza@Sun.COM * 3423*7887SLiane.Praza@Sun.COM * On error set scf_error() _NO_MEMORY, or _NOT_SET (val has not been set 3424*7887SLiane.Praza@Sun.COM * to a value). 3425*7887SLiane.Praza@Sun.COM */ 3426*7887SLiane.Praza@Sun.COM static char * 3427*7887SLiane.Praza@Sun.COM _scf_value_get_as_string(scf_value_t *val) 3428*7887SLiane.Praza@Sun.COM { 3429*7887SLiane.Praza@Sun.COM ssize_t sz = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH) + 1; 3430*7887SLiane.Praza@Sun.COM char *buf = malloc(sz); 3431*7887SLiane.Praza@Sun.COM 3432*7887SLiane.Praza@Sun.COM if (buf == NULL) { 3433*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 3434*7887SLiane.Praza@Sun.COM } else if (scf_value_get_as_string(val, buf, sz) == -1) { 3435*7887SLiane.Praza@Sun.COM free(buf); 3436*7887SLiane.Praza@Sun.COM buf = NULL; 3437*7887SLiane.Praza@Sun.COM } 3438*7887SLiane.Praza@Sun.COM 3439*7887SLiane.Praza@Sun.COM return (buf); 3440*7887SLiane.Praza@Sun.COM } 3441*7887SLiane.Praza@Sun.COM 3442*7887SLiane.Praza@Sun.COM /* 3443*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 3444*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3445*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3446*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3447*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3448*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3449*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3450*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3451*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3452*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3453*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3454*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3455*7887SLiane.Praza@Sun.COM */ 3456*7887SLiane.Praza@Sun.COM int 3457*7887SLiane.Praza@Sun.COM scf_tmpl_prop_cardinality(const scf_prop_tmpl_t *t, uint64_t *min, 3458*7887SLiane.Praza@Sun.COM uint64_t *max) 3459*7887SLiane.Praza@Sun.COM { 3460*7887SLiane.Praza@Sun.COM scf_value_t *val_min = NULL; 3461*7887SLiane.Praza@Sun.COM scf_value_t *val_max = NULL; 3462*7887SLiane.Praza@Sun.COM int ret = 0; 3463*7887SLiane.Praza@Sun.COM 3464*7887SLiane.Praza@Sun.COM if (_read_single_value_from_pg(t->prt_pg, 3465*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_CARDINALITY_MIN, &val_min) == 0) { 3466*7887SLiane.Praza@Sun.COM if (scf_value_get_count(val_min, min) < 0) 3467*7887SLiane.Praza@Sun.COM goto error; 3468*7887SLiane.Praza@Sun.COM } else { 3469*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_NOT_FOUND) 3470*7887SLiane.Praza@Sun.COM *min = 0; 3471*7887SLiane.Praza@Sun.COM else 3472*7887SLiane.Praza@Sun.COM goto error; 3473*7887SLiane.Praza@Sun.COM } 3474*7887SLiane.Praza@Sun.COM 3475*7887SLiane.Praza@Sun.COM if (_read_single_value_from_pg(t->prt_pg, 3476*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_CARDINALITY_MAX, &val_max) == 0) { 3477*7887SLiane.Praza@Sun.COM if (scf_value_get_count(val_max, max) < 0) 3478*7887SLiane.Praza@Sun.COM goto error; 3479*7887SLiane.Praza@Sun.COM } else { 3480*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_NOT_FOUND) 3481*7887SLiane.Praza@Sun.COM *max = UINT64_MAX; 3482*7887SLiane.Praza@Sun.COM else 3483*7887SLiane.Praza@Sun.COM goto error; 3484*7887SLiane.Praza@Sun.COM } 3485*7887SLiane.Praza@Sun.COM goto cleanup; 3486*7887SLiane.Praza@Sun.COM 3487*7887SLiane.Praza@Sun.COM error: 3488*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3489*7887SLiane.Praza@Sun.COM ret = -1; 3490*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3491*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3492*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3493*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3494*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 3495*7887SLiane.Praza@Sun.COM 3496*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3497*7887SLiane.Praza@Sun.COM case SCF_ERROR_TEMPLATE_INVALID: 3498*7887SLiane.Praza@Sun.COM ret = -1; 3499*7887SLiane.Praza@Sun.COM break; 3500*7887SLiane.Praza@Sun.COM 3501*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3502*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3503*7887SLiane.Praza@Sun.COM default: 3504*7887SLiane.Praza@Sun.COM assert(0); 3505*7887SLiane.Praza@Sun.COM abort(); 3506*7887SLiane.Praza@Sun.COM } 3507*7887SLiane.Praza@Sun.COM 3508*7887SLiane.Praza@Sun.COM cleanup: 3509*7887SLiane.Praza@Sun.COM scf_value_destroy(val_min); 3510*7887SLiane.Praza@Sun.COM scf_value_destroy(val_max); 3511*7887SLiane.Praza@Sun.COM 3512*7887SLiane.Praza@Sun.COM return (ret); 3513*7887SLiane.Praza@Sun.COM } 3514*7887SLiane.Praza@Sun.COM 3515*7887SLiane.Praza@Sun.COM /* 3516*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3517*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3518*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3519*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3520*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3521*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3522*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3523*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3524*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3525*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3526*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3527*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3528*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3529*7887SLiane.Praza@Sun.COM */ 3530*7887SLiane.Praza@Sun.COM int 3531*7887SLiane.Praza@Sun.COM scf_tmpl_prop_internal_seps(const scf_prop_tmpl_t *t, scf_values_t *vals) 3532*7887SLiane.Praza@Sun.COM { 3533*7887SLiane.Praza@Sun.COM if (_read_astrings_values(t->prt_pg, 3534*7887SLiane.Praza@Sun.COM SCF_PROPERTY_INTERNAL_SEPARATORS, vals) == NULL) { 3535*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3536*7887SLiane.Praza@Sun.COM return (-1); 3537*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3538*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3539*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3540*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3541*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 3542*7887SLiane.Praza@Sun.COM 3543*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3544*7887SLiane.Praza@Sun.COM return (-1); 3545*7887SLiane.Praza@Sun.COM 3546*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3547*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3548*7887SLiane.Praza@Sun.COM default: 3549*7887SLiane.Praza@Sun.COM assert(0); 3550*7887SLiane.Praza@Sun.COM abort(); 3551*7887SLiane.Praza@Sun.COM } 3552*7887SLiane.Praza@Sun.COM } else if (vals->value_count == 0) { 3553*7887SLiane.Praza@Sun.COM /* property has no value */ 3554*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 3555*7887SLiane.Praza@Sun.COM scf_values_destroy(vals); 3556*7887SLiane.Praza@Sun.COM return (-1); 3557*7887SLiane.Praza@Sun.COM } 3558*7887SLiane.Praza@Sun.COM 3559*7887SLiane.Praza@Sun.COM return (0); 3560*7887SLiane.Praza@Sun.COM } 3561*7887SLiane.Praza@Sun.COM 3562*7887SLiane.Praza@Sun.COM /* 3563*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3564*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3565*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3566*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3567*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3568*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3569*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3570*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3571*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3572*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3573*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3574*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3575*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3576*7887SLiane.Praza@Sun.COM */ 3577*7887SLiane.Praza@Sun.COM int 3578*7887SLiane.Praza@Sun.COM scf_tmpl_value_name_constraints(const scf_prop_tmpl_t *t, 3579*7887SLiane.Praza@Sun.COM scf_values_t *vals) 3580*7887SLiane.Praza@Sun.COM { 3581*7887SLiane.Praza@Sun.COM char **ret; 3582*7887SLiane.Praza@Sun.COM 3583*7887SLiane.Praza@Sun.COM ret = _read_astrings_values(t->prt_pg, 3584*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_CONSTRAINT_NAME, vals); 3585*7887SLiane.Praza@Sun.COM 3586*7887SLiane.Praza@Sun.COM if (ret == NULL) { 3587*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3588*7887SLiane.Praza@Sun.COM return (-1); 3589*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3590*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3591*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3592*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3593*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 3594*7887SLiane.Praza@Sun.COM 3595*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3596*7887SLiane.Praza@Sun.COM return (-1); 3597*7887SLiane.Praza@Sun.COM 3598*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3599*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3600*7887SLiane.Praza@Sun.COM default: 3601*7887SLiane.Praza@Sun.COM assert(0); 3602*7887SLiane.Praza@Sun.COM abort(); 3603*7887SLiane.Praza@Sun.COM } 3604*7887SLiane.Praza@Sun.COM } else if (vals->value_count == 0) { 3605*7887SLiane.Praza@Sun.COM /* property has no value */ 3606*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 3607*7887SLiane.Praza@Sun.COM scf_values_destroy(vals); 3608*7887SLiane.Praza@Sun.COM return (-1); 3609*7887SLiane.Praza@Sun.COM } 3610*7887SLiane.Praza@Sun.COM 3611*7887SLiane.Praza@Sun.COM return (0); 3612*7887SLiane.Praza@Sun.COM } 3613*7887SLiane.Praza@Sun.COM 3614*7887SLiane.Praza@Sun.COM /* 3615*7887SLiane.Praza@Sun.COM * Returns NULL on failure. Sets scf_error(): 3616*7887SLiane.Praza@Sun.COM * Caller is responsible for freeing returned pointer after use. 3617*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 3618*7887SLiane.Praza@Sun.COM * More tokens than the array size supplied. 3619*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3620*7887SLiane.Praza@Sun.COM */ 3621*7887SLiane.Praza@Sun.COM static void * 3622*7887SLiane.Praza@Sun.COM _separate_by_separator(char *string, const char *sep, char **array, int size) 3623*7887SLiane.Praza@Sun.COM { 3624*7887SLiane.Praza@Sun.COM char *str, *token; 3625*7887SLiane.Praza@Sun.COM char *lasts; 3626*7887SLiane.Praza@Sun.COM int n = 0; 3627*7887SLiane.Praza@Sun.COM 3628*7887SLiane.Praza@Sun.COM assert(array != NULL); 3629*7887SLiane.Praza@Sun.COM assert(string != NULL); 3630*7887SLiane.Praza@Sun.COM assert(sep != NULL); 3631*7887SLiane.Praza@Sun.COM assert(size > 0); 3632*7887SLiane.Praza@Sun.COM 3633*7887SLiane.Praza@Sun.COM str = strdup(string); 3634*7887SLiane.Praza@Sun.COM if (str == NULL) { 3635*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 3636*7887SLiane.Praza@Sun.COM return (NULL); 3637*7887SLiane.Praza@Sun.COM } 3638*7887SLiane.Praza@Sun.COM 3639*7887SLiane.Praza@Sun.COM if ((array[n] = strtok_r(str, sep, &lasts)) == NULL) { 3640*7887SLiane.Praza@Sun.COM assert(0); 3641*7887SLiane.Praza@Sun.COM abort(); 3642*7887SLiane.Praza@Sun.COM } 3643*7887SLiane.Praza@Sun.COM 3644*7887SLiane.Praza@Sun.COM n++; 3645*7887SLiane.Praza@Sun.COM while ((token = strtok_r(NULL, sep, &lasts)) != NULL) { 3646*7887SLiane.Praza@Sun.COM if (n >= size) { 3647*7887SLiane.Praza@Sun.COM goto error; 3648*7887SLiane.Praza@Sun.COM } 3649*7887SLiane.Praza@Sun.COM array[n] = token; 3650*7887SLiane.Praza@Sun.COM n++; 3651*7887SLiane.Praza@Sun.COM } 3652*7887SLiane.Praza@Sun.COM if (n < size) { 3653*7887SLiane.Praza@Sun.COM goto error; 3654*7887SLiane.Praza@Sun.COM } 3655*7887SLiane.Praza@Sun.COM 3656*7887SLiane.Praza@Sun.COM return (str); 3657*7887SLiane.Praza@Sun.COM error: 3658*7887SLiane.Praza@Sun.COM free(str); 3659*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED); 3660*7887SLiane.Praza@Sun.COM return (NULL); 3661*7887SLiane.Praza@Sun.COM } 3662*7887SLiane.Praza@Sun.COM 3663*7887SLiane.Praza@Sun.COM /* 3664*7887SLiane.Praza@Sun.COM * check if name is among values of CHOICES_INCLUDE_VALUES 3665*7887SLiane.Praza@Sun.COM * return 0 if name is present, 1 name is not present, -1 on failure 3666*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3667*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3668*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3669*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3670*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3671*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3672*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3673*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3674*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3675*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3676*7887SLiane.Praza@Sun.COM */ 3677*7887SLiane.Praza@Sun.COM static int 3678*7887SLiane.Praza@Sun.COM _check_choices_include_values(scf_propertygroup_t *pg, const char *name) 3679*7887SLiane.Praza@Sun.COM { 3680*7887SLiane.Praza@Sun.COM int n = 0, r = 1; 3681*7887SLiane.Praza@Sun.COM char **ret; 3682*7887SLiane.Praza@Sun.COM scf_values_t vals; 3683*7887SLiane.Praza@Sun.COM 3684*7887SLiane.Praza@Sun.COM if ((ret = _read_astrings_values(pg, 3685*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_CHOICES_INCLUDE_VALUES, &vals)) == NULL) { 3686*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3687*7887SLiane.Praza@Sun.COM return (-1); 3688*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3689*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3690*7887SLiane.Praza@Sun.COM return (1); 3691*7887SLiane.Praza@Sun.COM 3692*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3693*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3694*7887SLiane.Praza@Sun.COM return (-1); 3695*7887SLiane.Praza@Sun.COM 3696*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3697*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3698*7887SLiane.Praza@Sun.COM default: 3699*7887SLiane.Praza@Sun.COM assert(0); 3700*7887SLiane.Praza@Sun.COM abort(); 3701*7887SLiane.Praza@Sun.COM } 3702*7887SLiane.Praza@Sun.COM } 3703*7887SLiane.Praza@Sun.COM 3704*7887SLiane.Praza@Sun.COM for (n = 0; n < vals.value_count; ++n) { 3705*7887SLiane.Praza@Sun.COM if (strcmp(name, ret[n]) == 0) { 3706*7887SLiane.Praza@Sun.COM r = 0; 3707*7887SLiane.Praza@Sun.COM break; 3708*7887SLiane.Praza@Sun.COM } 3709*7887SLiane.Praza@Sun.COM } 3710*7887SLiane.Praza@Sun.COM scf_values_destroy(&vals); 3711*7887SLiane.Praza@Sun.COM return (r); 3712*7887SLiane.Praza@Sun.COM } 3713*7887SLiane.Praza@Sun.COM 3714*7887SLiane.Praza@Sun.COM void 3715*7887SLiane.Praza@Sun.COM scf_count_ranges_destroy(scf_count_ranges_t *ranges) 3716*7887SLiane.Praza@Sun.COM { 3717*7887SLiane.Praza@Sun.COM if (ranges == NULL) 3718*7887SLiane.Praza@Sun.COM return; 3719*7887SLiane.Praza@Sun.COM 3720*7887SLiane.Praza@Sun.COM ranges->scr_num_ranges = 0; 3721*7887SLiane.Praza@Sun.COM free(ranges->scr_min); 3722*7887SLiane.Praza@Sun.COM free(ranges->scr_max); 3723*7887SLiane.Praza@Sun.COM ranges->scr_min = NULL; 3724*7887SLiane.Praza@Sun.COM ranges->scr_max = NULL; 3725*7887SLiane.Praza@Sun.COM } 3726*7887SLiane.Praza@Sun.COM 3727*7887SLiane.Praza@Sun.COM void 3728*7887SLiane.Praza@Sun.COM scf_int_ranges_destroy(scf_int_ranges_t *ranges) 3729*7887SLiane.Praza@Sun.COM { 3730*7887SLiane.Praza@Sun.COM if (ranges == NULL) 3731*7887SLiane.Praza@Sun.COM return; 3732*7887SLiane.Praza@Sun.COM 3733*7887SLiane.Praza@Sun.COM ranges->sir_num_ranges = 0; 3734*7887SLiane.Praza@Sun.COM free(ranges->sir_min); 3735*7887SLiane.Praza@Sun.COM free(ranges->sir_max); 3736*7887SLiane.Praza@Sun.COM ranges->sir_min = NULL; 3737*7887SLiane.Praza@Sun.COM ranges->sir_max = NULL; 3738*7887SLiane.Praza@Sun.COM } 3739*7887SLiane.Praza@Sun.COM 3740*7887SLiane.Praza@Sun.COM /* 3741*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3742*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3743*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3744*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 3745*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3746*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3747*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3748*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3749*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3750*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3751*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3752*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3753*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3754*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3755*7887SLiane.Praza@Sun.COM */ 3756*7887SLiane.Praza@Sun.COM static int 3757*7887SLiane.Praza@Sun.COM _scf_tmpl_get_count_ranges(const scf_prop_tmpl_t *t, const char *prop, 3758*7887SLiane.Praza@Sun.COM scf_count_ranges_t *ranges) 3759*7887SLiane.Praza@Sun.COM { 3760*7887SLiane.Praza@Sun.COM scf_values_t vals; 3761*7887SLiane.Praza@Sun.COM int i = 0; 3762*7887SLiane.Praza@Sun.COM char **ret; 3763*7887SLiane.Praza@Sun.COM char *one_range[2]; 3764*7887SLiane.Praza@Sun.COM char *endptr; 3765*7887SLiane.Praza@Sun.COM char *str = NULL; 3766*7887SLiane.Praza@Sun.COM uint64_t *min = NULL; 3767*7887SLiane.Praza@Sun.COM uint64_t *max = NULL; 3768*7887SLiane.Praza@Sun.COM 3769*7887SLiane.Praza@Sun.COM assert(ranges != NULL); 3770*7887SLiane.Praza@Sun.COM if ((ret = _read_astrings_values(t->prt_pg, prop, &vals)) == NULL) 3771*7887SLiane.Praza@Sun.COM goto error; 3772*7887SLiane.Praza@Sun.COM if (vals.value_count == 0) { 3773*7887SLiane.Praza@Sun.COM /* range values are empty */ 3774*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 3775*7887SLiane.Praza@Sun.COM goto cleanup; 3776*7887SLiane.Praza@Sun.COM } 3777*7887SLiane.Praza@Sun.COM 3778*7887SLiane.Praza@Sun.COM min = malloc(vals.value_count * sizeof (uint64_t)); 3779*7887SLiane.Praza@Sun.COM max = malloc(vals.value_count * sizeof (uint64_t)); 3780*7887SLiane.Praza@Sun.COM if (min == NULL || max == NULL) { 3781*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 3782*7887SLiane.Praza@Sun.COM goto cleanup; 3783*7887SLiane.Praza@Sun.COM } 3784*7887SLiane.Praza@Sun.COM for (i = 0; i < vals.value_count; ++i) { 3785*7887SLiane.Praza@Sun.COM /* min and max should be separated by a "," */ 3786*7887SLiane.Praza@Sun.COM if ((str = _separate_by_separator(ret[i], ",", one_range, 3787*7887SLiane.Praza@Sun.COM 2)) == NULL) 3788*7887SLiane.Praza@Sun.COM goto cleanup; 3789*7887SLiane.Praza@Sun.COM errno = 0; 3790*7887SLiane.Praza@Sun.COM min[i] = strtoull(one_range[0], &endptr, 10); 3791*7887SLiane.Praza@Sun.COM if (errno != 0 || endptr == one_range[0] || *endptr) { 3792*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED); 3793*7887SLiane.Praza@Sun.COM goto cleanup; 3794*7887SLiane.Praza@Sun.COM } 3795*7887SLiane.Praza@Sun.COM errno = 0; 3796*7887SLiane.Praza@Sun.COM max[i] = strtoull(one_range[1], &endptr, 10); 3797*7887SLiane.Praza@Sun.COM if (errno != 0 || endptr == one_range[1] || *endptr) { 3798*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED); 3799*7887SLiane.Praza@Sun.COM goto cleanup; 3800*7887SLiane.Praza@Sun.COM } 3801*7887SLiane.Praza@Sun.COM if (min[i] > max[i]) { 3802*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED); 3803*7887SLiane.Praza@Sun.COM goto cleanup; 3804*7887SLiane.Praza@Sun.COM } 3805*7887SLiane.Praza@Sun.COM free(str); 3806*7887SLiane.Praza@Sun.COM str = NULL; 3807*7887SLiane.Praza@Sun.COM } 3808*7887SLiane.Praza@Sun.COM ranges->scr_num_ranges = vals.value_count; 3809*7887SLiane.Praza@Sun.COM ranges->scr_min = min; 3810*7887SLiane.Praza@Sun.COM ranges->scr_max = max; 3811*7887SLiane.Praza@Sun.COM scf_values_destroy(&vals); 3812*7887SLiane.Praza@Sun.COM return (0); 3813*7887SLiane.Praza@Sun.COM cleanup: 3814*7887SLiane.Praza@Sun.COM free(str); 3815*7887SLiane.Praza@Sun.COM free(min); 3816*7887SLiane.Praza@Sun.COM free(max); 3817*7887SLiane.Praza@Sun.COM scf_values_destroy(&vals); 3818*7887SLiane.Praza@Sun.COM error: 3819*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3820*7887SLiane.Praza@Sun.COM return (-1); 3821*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3822*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3823*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3824*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 3825*7887SLiane.Praza@Sun.COM 3826*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3827*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3828*7887SLiane.Praza@Sun.COM return (-1); 3829*7887SLiane.Praza@Sun.COM 3830*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3831*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3832*7887SLiane.Praza@Sun.COM default: 3833*7887SLiane.Praza@Sun.COM assert(0); 3834*7887SLiane.Praza@Sun.COM abort(); 3835*7887SLiane.Praza@Sun.COM } 3836*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 3837*7887SLiane.Praza@Sun.COM } 3838*7887SLiane.Praza@Sun.COM 3839*7887SLiane.Praza@Sun.COM /* 3840*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3841*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3842*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3843*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 3844*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3845*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3846*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3847*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3848*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3849*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3850*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3851*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3852*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3853*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3854*7887SLiane.Praza@Sun.COM */ 3855*7887SLiane.Praza@Sun.COM static int 3856*7887SLiane.Praza@Sun.COM _scf_tmpl_get_int_ranges(const scf_prop_tmpl_t *t, const char *prop, 3857*7887SLiane.Praza@Sun.COM scf_int_ranges_t *ranges) 3858*7887SLiane.Praza@Sun.COM { 3859*7887SLiane.Praza@Sun.COM scf_values_t vals; 3860*7887SLiane.Praza@Sun.COM int n = 0; 3861*7887SLiane.Praza@Sun.COM char **ret; 3862*7887SLiane.Praza@Sun.COM char *one_range[2]; 3863*7887SLiane.Praza@Sun.COM char *endptr; 3864*7887SLiane.Praza@Sun.COM char *str = NULL; 3865*7887SLiane.Praza@Sun.COM int64_t *min = NULL; 3866*7887SLiane.Praza@Sun.COM int64_t *max = NULL; 3867*7887SLiane.Praza@Sun.COM 3868*7887SLiane.Praza@Sun.COM assert(ranges != NULL); 3869*7887SLiane.Praza@Sun.COM if ((ret = _read_astrings_values(t->prt_pg, prop, &vals)) == NULL) 3870*7887SLiane.Praza@Sun.COM goto error; 3871*7887SLiane.Praza@Sun.COM if (vals.value_count == 0) { 3872*7887SLiane.Praza@Sun.COM /* range values are empty */ 3873*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 3874*7887SLiane.Praza@Sun.COM goto cleanup; 3875*7887SLiane.Praza@Sun.COM } 3876*7887SLiane.Praza@Sun.COM 3877*7887SLiane.Praza@Sun.COM min = malloc(vals.value_count * sizeof (int64_t)); 3878*7887SLiane.Praza@Sun.COM max = malloc(vals.value_count * sizeof (int64_t)); 3879*7887SLiane.Praza@Sun.COM if (min == NULL || max == NULL) { 3880*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 3881*7887SLiane.Praza@Sun.COM goto cleanup; 3882*7887SLiane.Praza@Sun.COM } 3883*7887SLiane.Praza@Sun.COM while (n < vals.value_count) { 3884*7887SLiane.Praza@Sun.COM /* min and max should be separated by a "," */ 3885*7887SLiane.Praza@Sun.COM if ((str = _separate_by_separator(ret[n], ",", one_range, 2)) 3886*7887SLiane.Praza@Sun.COM == NULL) 3887*7887SLiane.Praza@Sun.COM goto cleanup; 3888*7887SLiane.Praza@Sun.COM errno = 0; 3889*7887SLiane.Praza@Sun.COM min[n] = strtoll(one_range[0], &endptr, 10); 3890*7887SLiane.Praza@Sun.COM if (errno != 0 || endptr == one_range[0] || *endptr) { 3891*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED); 3892*7887SLiane.Praza@Sun.COM goto cleanup; 3893*7887SLiane.Praza@Sun.COM } 3894*7887SLiane.Praza@Sun.COM errno = 0; 3895*7887SLiane.Praza@Sun.COM max[n] = strtoll(one_range[1], &endptr, 10); 3896*7887SLiane.Praza@Sun.COM if (errno != 0 || endptr == one_range[1] || *endptr) { 3897*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED); 3898*7887SLiane.Praza@Sun.COM goto cleanup; 3899*7887SLiane.Praza@Sun.COM } 3900*7887SLiane.Praza@Sun.COM if (min[n] > max[n]) { 3901*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3902*7887SLiane.Praza@Sun.COM goto cleanup; 3903*7887SLiane.Praza@Sun.COM } 3904*7887SLiane.Praza@Sun.COM ++n; 3905*7887SLiane.Praza@Sun.COM free(str); 3906*7887SLiane.Praza@Sun.COM str = NULL; 3907*7887SLiane.Praza@Sun.COM } 3908*7887SLiane.Praza@Sun.COM ranges->sir_num_ranges = vals.value_count; 3909*7887SLiane.Praza@Sun.COM ranges->sir_min = min; 3910*7887SLiane.Praza@Sun.COM ranges->sir_max = max; 3911*7887SLiane.Praza@Sun.COM scf_values_destroy(&vals); 3912*7887SLiane.Praza@Sun.COM return (0); 3913*7887SLiane.Praza@Sun.COM cleanup: 3914*7887SLiane.Praza@Sun.COM free(str); 3915*7887SLiane.Praza@Sun.COM free(min); 3916*7887SLiane.Praza@Sun.COM free(max); 3917*7887SLiane.Praza@Sun.COM scf_values_destroy(&vals); 3918*7887SLiane.Praza@Sun.COM error: 3919*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 3920*7887SLiane.Praza@Sun.COM return (-1); 3921*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 3922*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 3923*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 3924*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 3925*7887SLiane.Praza@Sun.COM 3926*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 3927*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 3928*7887SLiane.Praza@Sun.COM case SCF_ERROR_TEMPLATE_INVALID: 3929*7887SLiane.Praza@Sun.COM return (-1); 3930*7887SLiane.Praza@Sun.COM 3931*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 3932*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 3933*7887SLiane.Praza@Sun.COM default: 3934*7887SLiane.Praza@Sun.COM assert(0); 3935*7887SLiane.Praza@Sun.COM abort(); 3936*7887SLiane.Praza@Sun.COM } 3937*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 3938*7887SLiane.Praza@Sun.COM } 3939*7887SLiane.Praza@Sun.COM 3940*7887SLiane.Praza@Sun.COM /* 3941*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3942*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3943*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3944*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONSTRAINT_VIOLATED 3945*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3946*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3947*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3948*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3949*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3950*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3951*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3952*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 3953*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 3954*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 3955*7887SLiane.Praza@Sun.COM */ 3956*7887SLiane.Praza@Sun.COM int 3957*7887SLiane.Praza@Sun.COM scf_tmpl_value_count_range_constraints(const scf_prop_tmpl_t *t, 3958*7887SLiane.Praza@Sun.COM scf_count_ranges_t *ranges) 3959*7887SLiane.Praza@Sun.COM { 3960*7887SLiane.Praza@Sun.COM return (_scf_tmpl_get_count_ranges(t, SCF_PROPERTY_TM_CONSTRAINT_RANGE, 3961*7887SLiane.Praza@Sun.COM ranges)); 3962*7887SLiane.Praza@Sun.COM } 3963*7887SLiane.Praza@Sun.COM 3964*7887SLiane.Praza@Sun.COM int 3965*7887SLiane.Praza@Sun.COM scf_tmpl_value_int_range_constraints(const scf_prop_tmpl_t *t, 3966*7887SLiane.Praza@Sun.COM scf_int_ranges_t *ranges) 3967*7887SLiane.Praza@Sun.COM { 3968*7887SLiane.Praza@Sun.COM return (_scf_tmpl_get_int_ranges(t, SCF_PROPERTY_TM_CONSTRAINT_RANGE, 3969*7887SLiane.Praza@Sun.COM ranges)); 3970*7887SLiane.Praza@Sun.COM } 3971*7887SLiane.Praza@Sun.COM 3972*7887SLiane.Praza@Sun.COM int 3973*7887SLiane.Praza@Sun.COM scf_tmpl_value_count_range_choices(const scf_prop_tmpl_t *t, 3974*7887SLiane.Praza@Sun.COM scf_count_ranges_t *ranges) 3975*7887SLiane.Praza@Sun.COM { 3976*7887SLiane.Praza@Sun.COM return (_scf_tmpl_get_count_ranges(t, SCF_PROPERTY_TM_CHOICES_RANGE, 3977*7887SLiane.Praza@Sun.COM ranges)); 3978*7887SLiane.Praza@Sun.COM } 3979*7887SLiane.Praza@Sun.COM 3980*7887SLiane.Praza@Sun.COM int 3981*7887SLiane.Praza@Sun.COM scf_tmpl_value_int_range_choices(const scf_prop_tmpl_t *t, 3982*7887SLiane.Praza@Sun.COM scf_int_ranges_t *ranges) 3983*7887SLiane.Praza@Sun.COM { 3984*7887SLiane.Praza@Sun.COM return (_scf_tmpl_get_int_ranges(t, SCF_PROPERTY_TM_CHOICES_RANGE, 3985*7887SLiane.Praza@Sun.COM ranges)); 3986*7887SLiane.Praza@Sun.COM } 3987*7887SLiane.Praza@Sun.COM 3988*7887SLiane.Praza@Sun.COM /* 3989*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 3990*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 3991*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 3992*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 3993*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 3994*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 3995*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 3996*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 3997*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 3998*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 3999*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 4000*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 4001*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 4002*7887SLiane.Praza@Sun.COM */ 4003*7887SLiane.Praza@Sun.COM int 4004*7887SLiane.Praza@Sun.COM scf_tmpl_value_name_choices(const scf_prop_tmpl_t *t, scf_values_t *vals) 4005*7887SLiane.Praza@Sun.COM { 4006*7887SLiane.Praza@Sun.COM int c_flag = 0; /* have not read any value yet */ 4007*7887SLiane.Praza@Sun.COM int r; 4008*7887SLiane.Praza@Sun.COM char **ret; 4009*7887SLiane.Praza@Sun.COM 4010*7887SLiane.Praza@Sun.COM /* First, look for explicitly declared choices. */ 4011*7887SLiane.Praza@Sun.COM if ((ret = _read_astrings_values(t->prt_pg, 4012*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_CHOICES_NAME, vals)) != NULL) { 4013*7887SLiane.Praza@Sun.COM c_flag = 1; 4014*7887SLiane.Praza@Sun.COM } else if (scf_error() != SCF_ERROR_NOT_FOUND) { 4015*7887SLiane.Praza@Sun.COM goto error; 4016*7887SLiane.Praza@Sun.COM } 4017*7887SLiane.Praza@Sun.COM 4018*7887SLiane.Praza@Sun.COM /* Next, check for choices included by 'values'. */ 4019*7887SLiane.Praza@Sun.COM if ((r = _check_choices_include_values(t->prt_pg, "values")) == 0) { 4020*7887SLiane.Praza@Sun.COM /* read values_name */ 4021*7887SLiane.Praza@Sun.COM if (c_flag == 1) 4022*7887SLiane.Praza@Sun.COM /* append values */ 4023*7887SLiane.Praza@Sun.COM ret = _append_astrings_values(t->prt_pg, 4024*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_VALUES_NAME, vals); 4025*7887SLiane.Praza@Sun.COM else 4026*7887SLiane.Praza@Sun.COM /* read values */ 4027*7887SLiane.Praza@Sun.COM ret = _read_astrings_values(t->prt_pg, 4028*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_VALUES_NAME, vals); 4029*7887SLiane.Praza@Sun.COM if (ret != NULL) { 4030*7887SLiane.Praza@Sun.COM c_flag = 1; 4031*7887SLiane.Praza@Sun.COM } else if (scf_error() != SCF_ERROR_NOT_FOUND) { 4032*7887SLiane.Praza@Sun.COM goto error; 4033*7887SLiane.Praza@Sun.COM } 4034*7887SLiane.Praza@Sun.COM } else if (r == -1) { 4035*7887SLiane.Praza@Sun.COM goto error; 4036*7887SLiane.Praza@Sun.COM } 4037*7887SLiane.Praza@Sun.COM 4038*7887SLiane.Praza@Sun.COM /* Finally check for choices included by 'constraints'. */ 4039*7887SLiane.Praza@Sun.COM if ((r = _check_choices_include_values(t->prt_pg, "constraints")) == 4040*7887SLiane.Praza@Sun.COM 0) { 4041*7887SLiane.Praza@Sun.COM /* read constraint_name */ 4042*7887SLiane.Praza@Sun.COM if (c_flag == 1) 4043*7887SLiane.Praza@Sun.COM /* append values */ 4044*7887SLiane.Praza@Sun.COM ret = _append_astrings_values(t->prt_pg, 4045*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_CONSTRAINT_NAME, vals); 4046*7887SLiane.Praza@Sun.COM else 4047*7887SLiane.Praza@Sun.COM /* read values */ 4048*7887SLiane.Praza@Sun.COM ret = _read_astrings_values(t->prt_pg, 4049*7887SLiane.Praza@Sun.COM SCF_PROPERTY_TM_CONSTRAINT_NAME, vals); 4050*7887SLiane.Praza@Sun.COM if (ret != NULL) { 4051*7887SLiane.Praza@Sun.COM c_flag = 1; 4052*7887SLiane.Praza@Sun.COM } else if (scf_error() != SCF_ERROR_NOT_FOUND) { 4053*7887SLiane.Praza@Sun.COM goto error; 4054*7887SLiane.Praza@Sun.COM } 4055*7887SLiane.Praza@Sun.COM } else if (r == -1) { 4056*7887SLiane.Praza@Sun.COM goto error; 4057*7887SLiane.Praza@Sun.COM } 4058*7887SLiane.Praza@Sun.COM 4059*7887SLiane.Praza@Sun.COM if (c_flag == 0 || vals->value_count == 0) { 4060*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 4061*7887SLiane.Praza@Sun.COM return (-1); 4062*7887SLiane.Praza@Sun.COM } 4063*7887SLiane.Praza@Sun.COM 4064*7887SLiane.Praza@Sun.COM return (0); 4065*7887SLiane.Praza@Sun.COM 4066*7887SLiane.Praza@Sun.COM error: 4067*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 4068*7887SLiane.Praza@Sun.COM return (-1); 4069*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 4070*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 4071*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 4072*7887SLiane.Praza@Sun.COM return (-1); 4073*7887SLiane.Praza@Sun.COM 4074*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 4075*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 4076*7887SLiane.Praza@Sun.COM default: 4077*7887SLiane.Praza@Sun.COM assert(0); 4078*7887SLiane.Praza@Sun.COM abort(); 4079*7887SLiane.Praza@Sun.COM } 4080*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 4081*7887SLiane.Praza@Sun.COM } 4082*7887SLiane.Praza@Sun.COM 4083*7887SLiane.Praza@Sun.COM void 4084*7887SLiane.Praza@Sun.COM scf_values_destroy(scf_values_t *vals) 4085*7887SLiane.Praza@Sun.COM { 4086*7887SLiane.Praza@Sun.COM int i; 4087*7887SLiane.Praza@Sun.COM char **items = NULL; 4088*7887SLiane.Praza@Sun.COM char **str = vals->values_as_strings; 4089*7887SLiane.Praza@Sun.COM 4090*7887SLiane.Praza@Sun.COM if (vals == NULL) 4091*7887SLiane.Praza@Sun.COM return; 4092*7887SLiane.Praza@Sun.COM 4093*7887SLiane.Praza@Sun.COM /* free values */ 4094*7887SLiane.Praza@Sun.COM switch (vals->value_type) { 4095*7887SLiane.Praza@Sun.COM case SCF_TYPE_BOOLEAN: 4096*7887SLiane.Praza@Sun.COM free(vals->values.v_boolean); 4097*7887SLiane.Praza@Sun.COM break; 4098*7887SLiane.Praza@Sun.COM case SCF_TYPE_COUNT: 4099*7887SLiane.Praza@Sun.COM free(vals->values.v_count); 4100*7887SLiane.Praza@Sun.COM break; 4101*7887SLiane.Praza@Sun.COM case SCF_TYPE_INTEGER: 4102*7887SLiane.Praza@Sun.COM free(vals->values.v_integer); 4103*7887SLiane.Praza@Sun.COM break; 4104*7887SLiane.Praza@Sun.COM case SCF_TYPE_ASTRING: 4105*7887SLiane.Praza@Sun.COM items = vals->values.v_astring; 4106*7887SLiane.Praza@Sun.COM str = NULL; 4107*7887SLiane.Praza@Sun.COM break; 4108*7887SLiane.Praza@Sun.COM case SCF_TYPE_USTRING: 4109*7887SLiane.Praza@Sun.COM items = vals->values.v_ustring; 4110*7887SLiane.Praza@Sun.COM str = NULL; 4111*7887SLiane.Praza@Sun.COM break; 4112*7887SLiane.Praza@Sun.COM case SCF_TYPE_OPAQUE: 4113*7887SLiane.Praza@Sun.COM items = vals->values.v_opaque; 4114*7887SLiane.Praza@Sun.COM str = NULL; 4115*7887SLiane.Praza@Sun.COM break; 4116*7887SLiane.Praza@Sun.COM case SCF_TYPE_TIME: 4117*7887SLiane.Praza@Sun.COM free(vals->values.v_time); 4118*7887SLiane.Praza@Sun.COM break; 4119*7887SLiane.Praza@Sun.COM default: 4120*7887SLiane.Praza@Sun.COM assert(0); 4121*7887SLiane.Praza@Sun.COM abort(); 4122*7887SLiane.Praza@Sun.COM } 4123*7887SLiane.Praza@Sun.COM for (i = 0; i < vals->value_count; ++i) { 4124*7887SLiane.Praza@Sun.COM if (items != NULL) 4125*7887SLiane.Praza@Sun.COM free(items[i]); 4126*7887SLiane.Praza@Sun.COM if (str != NULL) 4127*7887SLiane.Praza@Sun.COM free(str[i]); 4128*7887SLiane.Praza@Sun.COM } 4129*7887SLiane.Praza@Sun.COM vals->value_count = 0; 4130*7887SLiane.Praza@Sun.COM free(items); 4131*7887SLiane.Praza@Sun.COM free(str); 4132*7887SLiane.Praza@Sun.COM } 4133*7887SLiane.Praza@Sun.COM 4134*7887SLiane.Praza@Sun.COM /* 4135*7887SLiane.Praza@Sun.COM * char *_make_value_name() 4136*7887SLiane.Praza@Sun.COM * 4137*7887SLiane.Praza@Sun.COM * Construct the prefix for a value common name or value description property. 4138*7887SLiane.Praza@Sun.COM * It takes the form: 4139*7887SLiane.Praza@Sun.COM * value_<BASE32 name>_<common_name|description>_ 4140*7887SLiane.Praza@Sun.COM * This is then combined with a localized suffix by the caller to look 4141*7887SLiane.Praza@Sun.COM * up the property in the repository: 4142*7887SLiane.Praza@Sun.COM * value_<BASE32 name>_<common_name|description>_<lang> 4143*7887SLiane.Praza@Sun.COM * 4144*7887SLiane.Praza@Sun.COM * Returns NULL on failure. Sets scf_error(): 4145*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 4146*7887SLiane.Praza@Sun.COM * Name isn't short enough make a value name with. 4147*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 4148*7887SLiane.Praza@Sun.COM */ 4149*7887SLiane.Praza@Sun.COM static char * 4150*7887SLiane.Praza@Sun.COM _make_value_name(char *desc_name, const char *value) 4151*7887SLiane.Praza@Sun.COM { 4152*7887SLiane.Praza@Sun.COM char *name = NULL; 4153*7887SLiane.Praza@Sun.COM char *encoded = NULL; 4154*7887SLiane.Praza@Sun.COM ssize_t sz = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 4155*7887SLiane.Praza@Sun.COM 4156*7887SLiane.Praza@Sun.COM name = malloc(sz); 4157*7887SLiane.Praza@Sun.COM encoded = malloc(sz); 4158*7887SLiane.Praza@Sun.COM if (name == NULL || encoded == NULL) { 4159*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4160*7887SLiane.Praza@Sun.COM free(name); 4161*7887SLiane.Praza@Sun.COM free(encoded); 4162*7887SLiane.Praza@Sun.COM return (NULL); 4163*7887SLiane.Praza@Sun.COM } 4164*7887SLiane.Praza@Sun.COM 4165*7887SLiane.Praza@Sun.COM if (scf_encode32(value, strlen(value), encoded, sz, NULL, 4166*7887SLiane.Praza@Sun.COM SCF_ENCODE32_PAD) != 0) { 4167*7887SLiane.Praza@Sun.COM /* Shouldn't happen. */ 4168*7887SLiane.Praza@Sun.COM assert(0); 4169*7887SLiane.Praza@Sun.COM } 4170*7887SLiane.Praza@Sun.COM 4171*7887SLiane.Praza@Sun.COM (void) strlcpy(name, SCF_PROPERTY_TM_VALUE_PREFIX, sz); 4172*7887SLiane.Praza@Sun.COM 4173*7887SLiane.Praza@Sun.COM if (strlcat(name, encoded, sz) >= sz) { 4174*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 4175*7887SLiane.Praza@Sun.COM free(name); 4176*7887SLiane.Praza@Sun.COM free(encoded); 4177*7887SLiane.Praza@Sun.COM return (NULL); 4178*7887SLiane.Praza@Sun.COM } 4179*7887SLiane.Praza@Sun.COM 4180*7887SLiane.Praza@Sun.COM if (strlcat(name, "_", sz) >= sz) { 4181*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 4182*7887SLiane.Praza@Sun.COM free(name); 4183*7887SLiane.Praza@Sun.COM free(encoded); 4184*7887SLiane.Praza@Sun.COM return (NULL); 4185*7887SLiane.Praza@Sun.COM } 4186*7887SLiane.Praza@Sun.COM 4187*7887SLiane.Praza@Sun.COM if (strlcat(name, desc_name, sz) >= sz) { 4188*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 4189*7887SLiane.Praza@Sun.COM free(name); 4190*7887SLiane.Praza@Sun.COM free(encoded); 4191*7887SLiane.Praza@Sun.COM return (NULL); 4192*7887SLiane.Praza@Sun.COM } 4193*7887SLiane.Praza@Sun.COM 4194*7887SLiane.Praza@Sun.COM if (strlcat(name, "_", sz) >= sz) { 4195*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 4196*7887SLiane.Praza@Sun.COM free(name); 4197*7887SLiane.Praza@Sun.COM free(encoded); 4198*7887SLiane.Praza@Sun.COM return (NULL); 4199*7887SLiane.Praza@Sun.COM } 4200*7887SLiane.Praza@Sun.COM 4201*7887SLiane.Praza@Sun.COM free(encoded); 4202*7887SLiane.Praza@Sun.COM return (name); 4203*7887SLiane.Praza@Sun.COM } 4204*7887SLiane.Praza@Sun.COM 4205*7887SLiane.Praza@Sun.COM /* 4206*7887SLiane.Praza@Sun.COM * ssize_t scf_tmpl_value_common_name() 4207*7887SLiane.Praza@Sun.COM * 4208*7887SLiane.Praza@Sun.COM * Populates "out" with an allocated string containing the value's 4209*7887SLiane.Praza@Sun.COM * common name. Returns the size of the string on successful return. 4210*7887SLiane.Praza@Sun.COM * out must be freed with free() on successful return. 4211*7887SLiane.Praza@Sun.COM * 4212*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 4213*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 4214*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 4215*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 4216*7887SLiane.Praza@Sun.COM * Property group was deleted. 4217*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 4218*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 4219*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 4220*7887SLiane.Praza@Sun.COM * name not a valid property name 4221*7887SLiane.Praza@Sun.COM * name and locale are too long to make a property name 4222*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 4223*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 4224*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 4225*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 4226*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 4227*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 4228*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 4229*7887SLiane.Praza@Sun.COM * property is not SCF_TYPE_ASTRING has more than one value. 4230*7887SLiane.Praza@Sun.COM */ 4231*7887SLiane.Praza@Sun.COM ssize_t 4232*7887SLiane.Praza@Sun.COM scf_tmpl_value_common_name(const scf_prop_tmpl_t *t, const char *locale, 4233*7887SLiane.Praza@Sun.COM const char *value, char **out) 4234*7887SLiane.Praza@Sun.COM { 4235*7887SLiane.Praza@Sun.COM char *value_name = NULL; 4236*7887SLiane.Praza@Sun.COM 4237*7887SLiane.Praza@Sun.COM value_name = _make_value_name("common_name", value); 4238*7887SLiane.Praza@Sun.COM if (value_name == NULL) 4239*7887SLiane.Praza@Sun.COM return (-1); 4240*7887SLiane.Praza@Sun.COM 4241*7887SLiane.Praza@Sun.COM *out = _read_localized_astring_from_pg(t->prt_pg, value_name, locale); 4242*7887SLiane.Praza@Sun.COM 4243*7887SLiane.Praza@Sun.COM free(value_name); 4244*7887SLiane.Praza@Sun.COM 4245*7887SLiane.Praza@Sun.COM if (*out == NULL) 4246*7887SLiane.Praza@Sun.COM return (-1); 4247*7887SLiane.Praza@Sun.COM 4248*7887SLiane.Praza@Sun.COM return (strlen(*out)); 4249*7887SLiane.Praza@Sun.COM } 4250*7887SLiane.Praza@Sun.COM 4251*7887SLiane.Praza@Sun.COM /* 4252*7887SLiane.Praza@Sun.COM * ssize_t scf_tmpl_value_description() 4253*7887SLiane.Praza@Sun.COM * 4254*7887SLiane.Praza@Sun.COM * Populates "out" with an allocated string containing the value's 4255*7887SLiane.Praza@Sun.COM * description. Returns the size of the string on successful return. 4256*7887SLiane.Praza@Sun.COM * out must be freed with free() on successful return. 4257*7887SLiane.Praza@Sun.COM * 4258*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 4259*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 4260*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 4261*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 4262*7887SLiane.Praza@Sun.COM * Property group was deleted. 4263*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 4264*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 4265*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 4266*7887SLiane.Praza@Sun.COM * name not a valid property name 4267*7887SLiane.Praza@Sun.COM * name and locale are too long to make a property name 4268*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 4269*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 4270*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 4271*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 4272*7887SLiane.Praza@Sun.COM * Property doesn't exist or exists and has no value. 4273*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 4274*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 4275*7887SLiane.Praza@Sun.COM * property is not SCF_TYPE_ASTRING has more than one value. 4276*7887SLiane.Praza@Sun.COM */ 4277*7887SLiane.Praza@Sun.COM ssize_t 4278*7887SLiane.Praza@Sun.COM scf_tmpl_value_description(const scf_prop_tmpl_t *t, const char *locale, 4279*7887SLiane.Praza@Sun.COM const char *value, char **out) 4280*7887SLiane.Praza@Sun.COM { 4281*7887SLiane.Praza@Sun.COM char *value_name = NULL; 4282*7887SLiane.Praza@Sun.COM 4283*7887SLiane.Praza@Sun.COM value_name = _make_value_name("description", value); 4284*7887SLiane.Praza@Sun.COM if (value_name == NULL) 4285*7887SLiane.Praza@Sun.COM return (-1); 4286*7887SLiane.Praza@Sun.COM 4287*7887SLiane.Praza@Sun.COM 4288*7887SLiane.Praza@Sun.COM *out = _read_localized_astring_from_pg(t->prt_pg, value_name, locale); 4289*7887SLiane.Praza@Sun.COM 4290*7887SLiane.Praza@Sun.COM free(value_name); 4291*7887SLiane.Praza@Sun.COM 4292*7887SLiane.Praza@Sun.COM if (*out == NULL) 4293*7887SLiane.Praza@Sun.COM return (-1); 4294*7887SLiane.Praza@Sun.COM 4295*7887SLiane.Praza@Sun.COM return (strlen(*out)); 4296*7887SLiane.Praza@Sun.COM } 4297*7887SLiane.Praza@Sun.COM 4298*7887SLiane.Praza@Sun.COM /* 4299*7887SLiane.Praza@Sun.COM * Templates error messages format, in human readable form. 4300*7887SLiane.Praza@Sun.COM * Each line is one error item: 4301*7887SLiane.Praza@Sun.COM * 4302*7887SLiane.Praza@Sun.COM * prefix error message 4303*7887SLiane.Praza@Sun.COM * FMRI="err->te_errs->tes_fmri" 4304*7887SLiane.Praza@Sun.COM * Property group="err->te_pg_name" 4305*7887SLiane.Praza@Sun.COM * Property name="err->te_prop_name" 4306*7887SLiane.Praza@Sun.COM * expected value 1="err->te_ev1" 4307*7887SLiane.Praza@Sun.COM * expected value 2="err->te_ev2" 4308*7887SLiane.Praza@Sun.COM * actual value="err->te_actual" 4309*7887SLiane.Praza@Sun.COM * Tempalte source="err->te_tmpl_fmri" 4310*7887SLiane.Praza@Sun.COM * pg_pattern name="err->tmpl_pg_name" 4311*7887SLiane.Praza@Sun.COM * pg_pattern type="err->tmpl_pg_type" 4312*7887SLiane.Praza@Sun.COM * prop_pattern name="err->tmpl_prop_name" 4313*7887SLiane.Praza@Sun.COM * prop_pattern type="err->tmpl_prop_type" 4314*7887SLiane.Praza@Sun.COM * 4315*7887SLiane.Praza@Sun.COM * To add a new error type, include scf_tmpl_error_type_t in libscf.h 4316*7887SLiane.Praza@Sun.COM * add one entry in em_desc[], and update the functions pointed by the 4317*7887SLiane.Praza@Sun.COM * _tmpl_error_access array with the new error code. Also, update the 4318*7887SLiane.Praza@Sun.COM * scf_tmpl_error_* functions to provide access to desired 4319*7887SLiane.Praza@Sun.COM * scf_tmpl_error_t fields. 4320*7887SLiane.Praza@Sun.COM * 4321*7887SLiane.Praza@Sun.COM * To add a new error item, add a new field to scf_tmpl_error_t, a new field 4322*7887SLiane.Praza@Sun.COM * in _scf_tmpl_error_desc or a new non-error-dependent string, add a new entry 4323*7887SLiane.Praza@Sun.COM * in _tmpl_error_access array and create the appropriate get_val, get_desc 4324*7887SLiane.Praza@Sun.COM * functions. 4325*7887SLiane.Praza@Sun.COM * 4326*7887SLiane.Praza@Sun.COM * Changes to both the validation logic and the error types and items must 4327*7887SLiane.Praza@Sun.COM * be coordinated with the code in svccfg to ensure both libscf and svccfg's 4328*7887SLiane.Praza@Sun.COM * manifest validation validate the same things. 4329*7887SLiane.Praza@Sun.COM */ 4330*7887SLiane.Praza@Sun.COM 4331*7887SLiane.Praza@Sun.COM /* 4332*7887SLiane.Praza@Sun.COM * Container for all template errors on a validated object. 4333*7887SLiane.Praza@Sun.COM */ 4334*7887SLiane.Praza@Sun.COM struct scf_tmpl_errors { 4335*7887SLiane.Praza@Sun.COM int tes_index; 4336*7887SLiane.Praza@Sun.COM int tes_num_errs; 4337*7887SLiane.Praza@Sun.COM scf_tmpl_error_t **tes_errs; 4338*7887SLiane.Praza@Sun.COM int tes_errs_size; 4339*7887SLiane.Praza@Sun.COM const char *tes_fmri; 4340*7887SLiane.Praza@Sun.COM const char *tes_prefix; 4341*7887SLiane.Praza@Sun.COM int tes_flag; /* if set, scf_tmpl_error_destroy */ 4342*7887SLiane.Praza@Sun.COM /* will free strings in tes_errs */ 4343*7887SLiane.Praza@Sun.COM }; 4344*7887SLiane.Praza@Sun.COM 4345*7887SLiane.Praza@Sun.COM /* 4346*7887SLiane.Praza@Sun.COM * Templates error-dependent labels 4347*7887SLiane.Praza@Sun.COM */ 4348*7887SLiane.Praza@Sun.COM struct _scf_tmpl_error_desc { 4349*7887SLiane.Praza@Sun.COM const char *em_msg; 4350*7887SLiane.Praza@Sun.COM const char *em_ev1; 4351*7887SLiane.Praza@Sun.COM const char *em_ev2; 4352*7887SLiane.Praza@Sun.COM const char *em_actual; 4353*7887SLiane.Praza@Sun.COM }; 4354*7887SLiane.Praza@Sun.COM 4355*7887SLiane.Praza@Sun.COM /* 4356*7887SLiane.Praza@Sun.COM * This array MUST be kept in synch with the template error definition of 4357*7887SLiane.Praza@Sun.COM * scf_tmpl_error_type_t in libscf.h 4358*7887SLiane.Praza@Sun.COM */ 4359*7887SLiane.Praza@Sun.COM static struct _scf_tmpl_error_desc em_desc[] = { 4360*7887SLiane.Praza@Sun.COM /* SCF_TERR_MISSING_PG */ 4361*7887SLiane.Praza@Sun.COM { "Required property group missing", "Name of missing property group", 4362*7887SLiane.Praza@Sun.COM "Type of missing property group", NULL }, 4363*7887SLiane.Praza@Sun.COM /* SCF_TERR_WRONG_PG_TYPE */ 4364*7887SLiane.Praza@Sun.COM { "Property group has bad type", "Specified type", NULL, 4365*7887SLiane.Praza@Sun.COM "Actual type" }, 4366*7887SLiane.Praza@Sun.COM /* SCF_TERR_MISSING_PROP */ 4367*7887SLiane.Praza@Sun.COM { "Required property missing", "Name of missing property", NULL, NULL }, 4368*7887SLiane.Praza@Sun.COM /* SCF_TERR_WRONG_PROP_TYPE */ 4369*7887SLiane.Praza@Sun.COM { "Property has bad type", "Specified property type", NULL, 4370*7887SLiane.Praza@Sun.COM "Actual property type" }, 4371*7887SLiane.Praza@Sun.COM /* SCF_TERR_CARDINALITY_VIOLATION */ 4372*7887SLiane.Praza@Sun.COM { "Number of property values violates cardinality restriction", 4373*7887SLiane.Praza@Sun.COM "Cardinality minimum", "Cardinality maximum", 4374*7887SLiane.Praza@Sun.COM "Actual number of values" }, 4375*7887SLiane.Praza@Sun.COM /* SCF_TERR_VALUE_CONSTRAINT_VIOLATED */ 4376*7887SLiane.Praza@Sun.COM { "Property has illegal value", NULL, NULL, "Illegal value" }, 4377*7887SLiane.Praza@Sun.COM /* SCF_TERR_RANGE_VIOLATION */ 4378*7887SLiane.Praza@Sun.COM { "Property value is out of range", NULL, NULL, "Actual value" }, 4379*7887SLiane.Praza@Sun.COM /* SCF_TERR_PG_REDEFINE */ 4380*7887SLiane.Praza@Sun.COM { "Instance redefines pg_pattern", "Instance pg_pattern name", 4381*7887SLiane.Praza@Sun.COM "Instance pg_pattern type", NULL }, 4382*7887SLiane.Praza@Sun.COM /* SCF_TERR_PROP_TYPE_MISMATCH */ 4383*7887SLiane.Praza@Sun.COM { "Property type and value type mismatch", NULL, NULL, "Value type" }, 4384*7887SLiane.Praza@Sun.COM /* SCF_TERR_VALUE_OUT_OF_RANGE */ 4385*7887SLiane.Praza@Sun.COM { "Value is out of range", NULL, NULL, "Value" }, 4386*7887SLiane.Praza@Sun.COM /* SCF_TERR_INVALID_VALUE */ 4387*7887SLiane.Praza@Sun.COM { "Value is not valid", NULL, NULL, "Value" }, 4388*7887SLiane.Praza@Sun.COM /* SCF_TERR_PG_PATTERN_CONFLICT */ 4389*7887SLiane.Praza@Sun.COM { "Conflicting pg_pattern specifications", "Template source", 4390*7887SLiane.Praza@Sun.COM "pg_pattern name", "pg_pattern type" }, 4391*7887SLiane.Praza@Sun.COM /* SCF_TERR_PROP_PATTERN_CONFLICT */ 4392*7887SLiane.Praza@Sun.COM { "Conflicting prop_pattern specifications", "Template source", 4393*7887SLiane.Praza@Sun.COM "prop_pattern name", "prop_pattern type" }, 4394*7887SLiane.Praza@Sun.COM /* SCF_TERR_GENERAL_REDEFINE */ 4395*7887SLiane.Praza@Sun.COM { "Service or instance pg_pattern redefines a global or restarter " 4396*7887SLiane.Praza@Sun.COM "pg_pattern", "Template source", "pg_pattern name", 4397*7887SLiane.Praza@Sun.COM "pg_pattern type" }, 4398*7887SLiane.Praza@Sun.COM /* SCF_TERR_INCLUDE_VALUES */ 4399*7887SLiane.Praza@Sun.COM { "Missing constraints or values for include_values element", 4400*7887SLiane.Praza@Sun.COM "include_values type", NULL, NULL }, 4401*7887SLiane.Praza@Sun.COM /* SCF_TERR_PG_PATTERN_INCOMPLETE */ 4402*7887SLiane.Praza@Sun.COM { "Required pg_pattern is missing a name or type attribute", 4403*7887SLiane.Praza@Sun.COM NULL, NULL, NULL }, 4404*7887SLiane.Praza@Sun.COM /* SCF_TERR_PROP_PATTERN_INCOMPLETE */ 4405*7887SLiane.Praza@Sun.COM { "Required prop_pattern is missing a type attribute", 4406*7887SLiane.Praza@Sun.COM NULL, NULL, NULL } 4407*7887SLiane.Praza@Sun.COM }; 4408*7887SLiane.Praza@Sun.COM 4409*7887SLiane.Praza@Sun.COM /* 4410*7887SLiane.Praza@Sun.COM * Templates non error-dependent labels 4411*7887SLiane.Praza@Sun.COM */ 4412*7887SLiane.Praza@Sun.COM static const char *em_fmri = "FMRI"; 4413*7887SLiane.Praza@Sun.COM static const char *em_pg_name = "Property group"; 4414*7887SLiane.Praza@Sun.COM static const char *em_prop_name = "Property name"; 4415*7887SLiane.Praza@Sun.COM static const char *em_tmpl_fmri = "Template source"; 4416*7887SLiane.Praza@Sun.COM static const char *em_tmpl_pg_name = "pg_pattern name"; 4417*7887SLiane.Praza@Sun.COM static const char *em_tmpl_pg_type = "pg_pattern type"; 4418*7887SLiane.Praza@Sun.COM static const char *em_tmpl_prop_name = "prop_pattern name"; 4419*7887SLiane.Praza@Sun.COM static const char *em_tmpl_prop_type = "prop_pattern type"; 4420*7887SLiane.Praza@Sun.COM 4421*7887SLiane.Praza@Sun.COM static const char * 4422*7887SLiane.Praza@Sun.COM _get_fmri_desc(scf_tmpl_error_t *err) 4423*7887SLiane.Praza@Sun.COM { 4424*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4425*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4426*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4427*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4428*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4429*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4430*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4431*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4432*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4433*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4434*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4435*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4436*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_fmri)); 4437*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4438*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4439*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4440*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4441*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4442*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4443*7887SLiane.Praza@Sun.COM default: 4444*7887SLiane.Praza@Sun.COM return (NULL); 4445*7887SLiane.Praza@Sun.COM } 4446*7887SLiane.Praza@Sun.COM } 4447*7887SLiane.Praza@Sun.COM 4448*7887SLiane.Praza@Sun.COM static const char * 4449*7887SLiane.Praza@Sun.COM _get_pg_name_desc(scf_tmpl_error_t *err) 4450*7887SLiane.Praza@Sun.COM { 4451*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4452*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4453*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4454*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4455*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4456*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4457*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4458*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_pg_name)); 4459*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4460*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4461*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4462*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4463*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4464*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4465*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4466*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4467*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4468*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4469*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4470*7887SLiane.Praza@Sun.COM default: 4471*7887SLiane.Praza@Sun.COM return (NULL); 4472*7887SLiane.Praza@Sun.COM } 4473*7887SLiane.Praza@Sun.COM } 4474*7887SLiane.Praza@Sun.COM 4475*7887SLiane.Praza@Sun.COM static const char * 4476*7887SLiane.Praza@Sun.COM _get_prop_name_desc(scf_tmpl_error_t *err) 4477*7887SLiane.Praza@Sun.COM { 4478*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4479*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4480*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4481*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4482*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4483*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_prop_name)); 4484*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4485*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4486*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4487*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4488*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4489*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4490*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4491*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4492*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4493*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4494*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4495*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4496*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4497*7887SLiane.Praza@Sun.COM default: 4498*7887SLiane.Praza@Sun.COM return (NULL); 4499*7887SLiane.Praza@Sun.COM } 4500*7887SLiane.Praza@Sun.COM } 4501*7887SLiane.Praza@Sun.COM 4502*7887SLiane.Praza@Sun.COM static const char * 4503*7887SLiane.Praza@Sun.COM _get_ev1_desc(scf_tmpl_error_t *err) 4504*7887SLiane.Praza@Sun.COM { 4505*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4506*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4507*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4508*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4509*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4510*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4511*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4512*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4513*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4514*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4515*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4516*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4517*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_desc[err->te_type].em_ev1)); 4518*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4519*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4520*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4521*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4522*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4523*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4524*7887SLiane.Praza@Sun.COM default: 4525*7887SLiane.Praza@Sun.COM return (NULL); 4526*7887SLiane.Praza@Sun.COM } 4527*7887SLiane.Praza@Sun.COM } 4528*7887SLiane.Praza@Sun.COM 4529*7887SLiane.Praza@Sun.COM static const char * 4530*7887SLiane.Praza@Sun.COM _get_ev2_desc(scf_tmpl_error_t *err) 4531*7887SLiane.Praza@Sun.COM { 4532*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4533*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4534*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4535*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4536*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4537*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4538*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4539*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4540*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_desc[err->te_type].em_ev2)); 4541*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4542*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4543*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4544*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4545*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4546*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4547*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4548*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4549*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4550*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4551*7887SLiane.Praza@Sun.COM default: 4552*7887SLiane.Praza@Sun.COM return (NULL); 4553*7887SLiane.Praza@Sun.COM } 4554*7887SLiane.Praza@Sun.COM } 4555*7887SLiane.Praza@Sun.COM 4556*7887SLiane.Praza@Sun.COM static const char * 4557*7887SLiane.Praza@Sun.COM _get_actual_desc(scf_tmpl_error_t *err) 4558*7887SLiane.Praza@Sun.COM { 4559*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4560*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4561*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4562*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4563*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4564*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4565*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4566*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4567*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4568*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4569*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4570*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4571*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4572*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4573*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, 4574*7887SLiane.Praza@Sun.COM em_desc[err->te_type].em_actual)); 4575*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4576*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4577*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4578*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4579*7887SLiane.Praza@Sun.COM default: 4580*7887SLiane.Praza@Sun.COM return (NULL); 4581*7887SLiane.Praza@Sun.COM } 4582*7887SLiane.Praza@Sun.COM } 4583*7887SLiane.Praza@Sun.COM 4584*7887SLiane.Praza@Sun.COM static const char * 4585*7887SLiane.Praza@Sun.COM _get_tmpl_fmri_desc(scf_tmpl_error_t *err) 4586*7887SLiane.Praza@Sun.COM { 4587*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4588*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4589*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4590*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4591*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4592*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4593*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4594*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4595*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4596*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4597*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4598*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4599*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4600*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4601*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4602*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4603*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4604*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4605*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_tmpl_fmri)); 4606*7887SLiane.Praza@Sun.COM default: 4607*7887SLiane.Praza@Sun.COM return (NULL); 4608*7887SLiane.Praza@Sun.COM } 4609*7887SLiane.Praza@Sun.COM } 4610*7887SLiane.Praza@Sun.COM 4611*7887SLiane.Praza@Sun.COM static const char * 4612*7887SLiane.Praza@Sun.COM _get_tmpl_pg_name_desc(scf_tmpl_error_t *err) 4613*7887SLiane.Praza@Sun.COM { 4614*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4615*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4616*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4617*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4618*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4619*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4620*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4621*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4622*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4623*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4624*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4625*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4626*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4627*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4628*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4629*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4630*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4631*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4632*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_tmpl_pg_name)); 4633*7887SLiane.Praza@Sun.COM default: 4634*7887SLiane.Praza@Sun.COM return (NULL); 4635*7887SLiane.Praza@Sun.COM } 4636*7887SLiane.Praza@Sun.COM } 4637*7887SLiane.Praza@Sun.COM 4638*7887SLiane.Praza@Sun.COM static const char * 4639*7887SLiane.Praza@Sun.COM _get_tmpl_pg_type_desc(scf_tmpl_error_t *err) 4640*7887SLiane.Praza@Sun.COM { 4641*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4642*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4643*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4644*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4645*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4646*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4647*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4648*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4649*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4650*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4651*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4652*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4653*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4654*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4655*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4656*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4657*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4658*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4659*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_tmpl_pg_type)); 4660*7887SLiane.Praza@Sun.COM default: 4661*7887SLiane.Praza@Sun.COM return (NULL); 4662*7887SLiane.Praza@Sun.COM } 4663*7887SLiane.Praza@Sun.COM } 4664*7887SLiane.Praza@Sun.COM 4665*7887SLiane.Praza@Sun.COM static const char * 4666*7887SLiane.Praza@Sun.COM _get_tmpl_prop_name_desc(scf_tmpl_error_t *err) 4667*7887SLiane.Praza@Sun.COM { 4668*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4669*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4670*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4671*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4672*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4673*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4674*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4675*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4676*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4677*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4678*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4679*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4680*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_tmpl_prop_name)); 4681*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4682*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4683*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4684*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4685*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4686*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4687*7887SLiane.Praza@Sun.COM default: 4688*7887SLiane.Praza@Sun.COM return (NULL); 4689*7887SLiane.Praza@Sun.COM } 4690*7887SLiane.Praza@Sun.COM } 4691*7887SLiane.Praza@Sun.COM 4692*7887SLiane.Praza@Sun.COM static const char * 4693*7887SLiane.Praza@Sun.COM _get_tmpl_prop_type_desc(scf_tmpl_error_t *err) 4694*7887SLiane.Praza@Sun.COM { 4695*7887SLiane.Praza@Sun.COM switch (err->te_type) { 4696*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 4697*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 4698*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 4699*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 4700*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 4701*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 4702*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 4703*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 4704*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_CONFLICT: 4705*7887SLiane.Praza@Sun.COM case SCF_TERR_INCLUDE_VALUES: 4706*7887SLiane.Praza@Sun.COM return (dgettext(TEXT_DOMAIN, em_tmpl_prop_type)); 4707*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 4708*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 4709*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 4710*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_CONFLICT: 4711*7887SLiane.Praza@Sun.COM case SCF_TERR_GENERAL_REDEFINE: 4712*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_PATTERN_INCOMPLETE: 4713*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_PATTERN_INCOMPLETE: 4714*7887SLiane.Praza@Sun.COM default: 4715*7887SLiane.Praza@Sun.COM return (NULL); 4716*7887SLiane.Praza@Sun.COM } 4717*7887SLiane.Praza@Sun.COM } 4718*7887SLiane.Praza@Sun.COM 4719*7887SLiane.Praza@Sun.COM static const char * 4720*7887SLiane.Praza@Sun.COM _get_fmri_val(scf_tmpl_error_t *err) 4721*7887SLiane.Praza@Sun.COM { 4722*7887SLiane.Praza@Sun.COM assert(err != NULL && err->te_errs != NULL && 4723*7887SLiane.Praza@Sun.COM err->te_errs->tes_fmri != NULL); 4724*7887SLiane.Praza@Sun.COM return (err->te_errs->tes_fmri); 4725*7887SLiane.Praza@Sun.COM } 4726*7887SLiane.Praza@Sun.COM 4727*7887SLiane.Praza@Sun.COM static const char * 4728*7887SLiane.Praza@Sun.COM _get_pg_name_val(scf_tmpl_error_t *err) 4729*7887SLiane.Praza@Sun.COM { 4730*7887SLiane.Praza@Sun.COM assert(err != NULL); 4731*7887SLiane.Praza@Sun.COM return (err->te_pg_name); 4732*7887SLiane.Praza@Sun.COM } 4733*7887SLiane.Praza@Sun.COM 4734*7887SLiane.Praza@Sun.COM static const char * 4735*7887SLiane.Praza@Sun.COM _get_prop_name_val(scf_tmpl_error_t *err) 4736*7887SLiane.Praza@Sun.COM { 4737*7887SLiane.Praza@Sun.COM assert(err != NULL); 4738*7887SLiane.Praza@Sun.COM return (err->te_prop_name); 4739*7887SLiane.Praza@Sun.COM } 4740*7887SLiane.Praza@Sun.COM 4741*7887SLiane.Praza@Sun.COM static const char * 4742*7887SLiane.Praza@Sun.COM _get_ev1_val(scf_tmpl_error_t *err) 4743*7887SLiane.Praza@Sun.COM { 4744*7887SLiane.Praza@Sun.COM assert(err != NULL); 4745*7887SLiane.Praza@Sun.COM return (err->te_ev1); 4746*7887SLiane.Praza@Sun.COM } 4747*7887SLiane.Praza@Sun.COM 4748*7887SLiane.Praza@Sun.COM static const char * 4749*7887SLiane.Praza@Sun.COM _get_ev2_val(scf_tmpl_error_t *err) 4750*7887SLiane.Praza@Sun.COM { 4751*7887SLiane.Praza@Sun.COM assert(err != NULL); 4752*7887SLiane.Praza@Sun.COM return (err->te_ev2); 4753*7887SLiane.Praza@Sun.COM } 4754*7887SLiane.Praza@Sun.COM 4755*7887SLiane.Praza@Sun.COM static const char * 4756*7887SLiane.Praza@Sun.COM _get_actual_val(scf_tmpl_error_t *err) 4757*7887SLiane.Praza@Sun.COM { 4758*7887SLiane.Praza@Sun.COM assert(err != NULL); 4759*7887SLiane.Praza@Sun.COM return (err->te_actual); 4760*7887SLiane.Praza@Sun.COM } 4761*7887SLiane.Praza@Sun.COM 4762*7887SLiane.Praza@Sun.COM static const char * 4763*7887SLiane.Praza@Sun.COM _get_tmpl_fmri_val(scf_tmpl_error_t *err) 4764*7887SLiane.Praza@Sun.COM { 4765*7887SLiane.Praza@Sun.COM assert(err != NULL); 4766*7887SLiane.Praza@Sun.COM return (err->te_tmpl_fmri); 4767*7887SLiane.Praza@Sun.COM } 4768*7887SLiane.Praza@Sun.COM 4769*7887SLiane.Praza@Sun.COM static const char * 4770*7887SLiane.Praza@Sun.COM _get_tmpl_pg_name_val(scf_tmpl_error_t *err) 4771*7887SLiane.Praza@Sun.COM { 4772*7887SLiane.Praza@Sun.COM assert(err != NULL); 4773*7887SLiane.Praza@Sun.COM return (err->te_tmpl_pg_name); 4774*7887SLiane.Praza@Sun.COM } 4775*7887SLiane.Praza@Sun.COM 4776*7887SLiane.Praza@Sun.COM static const char * 4777*7887SLiane.Praza@Sun.COM _get_tmpl_pg_type_val(scf_tmpl_error_t *err) 4778*7887SLiane.Praza@Sun.COM { 4779*7887SLiane.Praza@Sun.COM assert(err != NULL); 4780*7887SLiane.Praza@Sun.COM return (err->te_tmpl_pg_type); 4781*7887SLiane.Praza@Sun.COM } 4782*7887SLiane.Praza@Sun.COM 4783*7887SLiane.Praza@Sun.COM static const char * 4784*7887SLiane.Praza@Sun.COM _get_tmpl_prop_name_val(scf_tmpl_error_t *err) 4785*7887SLiane.Praza@Sun.COM { 4786*7887SLiane.Praza@Sun.COM assert(err != NULL); 4787*7887SLiane.Praza@Sun.COM return (err->te_tmpl_prop_name); 4788*7887SLiane.Praza@Sun.COM } 4789*7887SLiane.Praza@Sun.COM 4790*7887SLiane.Praza@Sun.COM static const char * 4791*7887SLiane.Praza@Sun.COM _get_tmpl_prop_type_val(scf_tmpl_error_t *err) 4792*7887SLiane.Praza@Sun.COM { 4793*7887SLiane.Praza@Sun.COM assert(err != NULL); 4794*7887SLiane.Praza@Sun.COM return (err->te_tmpl_prop_type); 4795*7887SLiane.Praza@Sun.COM } 4796*7887SLiane.Praza@Sun.COM 4797*7887SLiane.Praza@Sun.COM /* 4798*7887SLiane.Praza@Sun.COM * Templates error item retrival functions 4799*7887SLiane.Praza@Sun.COM */ 4800*7887SLiane.Praza@Sun.COM typedef const char *(*get_em)(scf_tmpl_error_t *); 4801*7887SLiane.Praza@Sun.COM 4802*7887SLiane.Praza@Sun.COM /* 4803*7887SLiane.Praza@Sun.COM * if new items (lines) are added to the templates error messages, 4804*7887SLiane.Praza@Sun.COM * new entries in this array (and new fuctions) will be required. 4805*7887SLiane.Praza@Sun.COM */ 4806*7887SLiane.Praza@Sun.COM static struct _tmpl_error_access { 4807*7887SLiane.Praza@Sun.COM get_em get_desc; 4808*7887SLiane.Praza@Sun.COM get_em get_val; 4809*7887SLiane.Praza@Sun.COM } _tmpl_error_items[] = { 4810*7887SLiane.Praza@Sun.COM { (get_em)_get_fmri_desc, (get_em)_get_fmri_val }, 4811*7887SLiane.Praza@Sun.COM { (get_em)_get_pg_name_desc, (get_em)_get_pg_name_val }, 4812*7887SLiane.Praza@Sun.COM { (get_em)_get_prop_name_desc, (get_em)_get_prop_name_val }, 4813*7887SLiane.Praza@Sun.COM { (get_em)_get_ev1_desc, (get_em)_get_ev1_val }, 4814*7887SLiane.Praza@Sun.COM { (get_em)_get_ev2_desc, (get_em)_get_ev2_val }, 4815*7887SLiane.Praza@Sun.COM { (get_em)_get_actual_desc, (get_em)_get_actual_val }, 4816*7887SLiane.Praza@Sun.COM { (get_em)_get_tmpl_fmri_desc, (get_em)_get_tmpl_fmri_val }, 4817*7887SLiane.Praza@Sun.COM { (get_em)_get_tmpl_pg_name_desc, (get_em)_get_tmpl_pg_name_val }, 4818*7887SLiane.Praza@Sun.COM { (get_em)_get_tmpl_pg_type_desc, (get_em)_get_tmpl_pg_type_val }, 4819*7887SLiane.Praza@Sun.COM { (get_em)_get_tmpl_prop_name_desc, (get_em)_get_tmpl_prop_name_val }, 4820*7887SLiane.Praza@Sun.COM { (get_em)_get_tmpl_prop_type_desc, (get_em)_get_tmpl_prop_type_val }, 4821*7887SLiane.Praza@Sun.COM { NULL } 4822*7887SLiane.Praza@Sun.COM }; 4823*7887SLiane.Praza@Sun.COM 4824*7887SLiane.Praza@Sun.COM /* 4825*7887SLiane.Praza@Sun.COM * Allocate a new scf_tmpl_error_t and add it to the errs list provided. 4826*7887SLiane.Praza@Sun.COM * Returns NULL on failure. Sets scf_error(): 4827*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 4828*7887SLiane.Praza@Sun.COM */ 4829*7887SLiane.Praza@Sun.COM static scf_tmpl_error_t * 4830*7887SLiane.Praza@Sun.COM _create_error(scf_tmpl_errors_t *errs) 4831*7887SLiane.Praza@Sun.COM { 4832*7887SLiane.Praza@Sun.COM scf_tmpl_error_t *ret; 4833*7887SLiane.Praza@Sun.COM scf_tmpl_error_t **saved_errs; 4834*7887SLiane.Praza@Sun.COM 4835*7887SLiane.Praza@Sun.COM assert(errs != NULL); 4836*7887SLiane.Praza@Sun.COM ret = calloc(1, sizeof (scf_tmpl_error_t)); 4837*7887SLiane.Praza@Sun.COM if (ret == NULL) { 4838*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4839*7887SLiane.Praza@Sun.COM return (NULL); 4840*7887SLiane.Praza@Sun.COM } 4841*7887SLiane.Praza@Sun.COM 4842*7887SLiane.Praza@Sun.COM ret->te_errs = errs; 4843*7887SLiane.Praza@Sun.COM 4844*7887SLiane.Praza@Sun.COM assert(errs->tes_num_errs <= errs->tes_errs_size); 4845*7887SLiane.Praza@Sun.COM if (errs->tes_num_errs == errs->tes_errs_size) { 4846*7887SLiane.Praza@Sun.COM /* Time to grow the pointer array. */ 4847*7887SLiane.Praza@Sun.COM saved_errs = errs->tes_errs; 4848*7887SLiane.Praza@Sun.COM errs->tes_errs = calloc(2 * errs->tes_errs_size, 4849*7887SLiane.Praza@Sun.COM sizeof (scf_tmpl_error_t *)); 4850*7887SLiane.Praza@Sun.COM if (errs->tes_errs == NULL) { 4851*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4852*7887SLiane.Praza@Sun.COM errs->tes_errs = saved_errs; 4853*7887SLiane.Praza@Sun.COM free(ret); 4854*7887SLiane.Praza@Sun.COM return (NULL); 4855*7887SLiane.Praza@Sun.COM } 4856*7887SLiane.Praza@Sun.COM (void) memcpy(errs->tes_errs, saved_errs, errs->tes_errs_size * 4857*7887SLiane.Praza@Sun.COM sizeof (scf_tmpl_error_t *)); 4858*7887SLiane.Praza@Sun.COM errs->tes_errs_size = 2 * errs->tes_errs_size; 4859*7887SLiane.Praza@Sun.COM free(saved_errs); 4860*7887SLiane.Praza@Sun.COM } 4861*7887SLiane.Praza@Sun.COM 4862*7887SLiane.Praza@Sun.COM errs->tes_errs[errs->tes_num_errs] = ret; 4863*7887SLiane.Praza@Sun.COM errs->tes_num_errs++; 4864*7887SLiane.Praza@Sun.COM 4865*7887SLiane.Praza@Sun.COM return (ret); 4866*7887SLiane.Praza@Sun.COM } 4867*7887SLiane.Praza@Sun.COM 4868*7887SLiane.Praza@Sun.COM /* 4869*7887SLiane.Praza@Sun.COM * 4870*7887SLiane.Praza@Sun.COM * If destroy_strings is set, scf_tmpl_errors_destroy will free the 4871*7887SLiane.Praza@Sun.COM * strings in scf_tmpl_error_t entries. 4872*7887SLiane.Praza@Sun.COM * 4873*7887SLiane.Praza@Sun.COM * Returns NULL on failure. Sets scf_error(): 4874*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 4875*7887SLiane.Praza@Sun.COM */ 4876*7887SLiane.Praza@Sun.COM scf_tmpl_errors_t * 4877*7887SLiane.Praza@Sun.COM _scf_create_errors(const char *fmri, int destroy_strings) 4878*7887SLiane.Praza@Sun.COM { 4879*7887SLiane.Praza@Sun.COM scf_tmpl_errors_t *ret; 4880*7887SLiane.Praza@Sun.COM int errs_size = 20; 4881*7887SLiane.Praza@Sun.COM 4882*7887SLiane.Praza@Sun.COM assert(fmri != NULL); 4883*7887SLiane.Praza@Sun.COM 4884*7887SLiane.Praza@Sun.COM ret = calloc(1, sizeof (scf_tmpl_errors_t)); 4885*7887SLiane.Praza@Sun.COM if (ret == NULL) { 4886*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4887*7887SLiane.Praza@Sun.COM return (NULL); 4888*7887SLiane.Praza@Sun.COM } 4889*7887SLiane.Praza@Sun.COM 4890*7887SLiane.Praza@Sun.COM ret->tes_index = 0; 4891*7887SLiane.Praza@Sun.COM ret->tes_num_errs = 0; 4892*7887SLiane.Praza@Sun.COM if ((ret->tes_fmri = strdup(fmri)) == NULL) { 4893*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4894*7887SLiane.Praza@Sun.COM free(ret); 4895*7887SLiane.Praza@Sun.COM return (NULL); 4896*7887SLiane.Praza@Sun.COM } 4897*7887SLiane.Praza@Sun.COM 4898*7887SLiane.Praza@Sun.COM ret->tes_prefix = strdup(""); 4899*7887SLiane.Praza@Sun.COM if (ret->tes_prefix == NULL) { 4900*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4901*7887SLiane.Praza@Sun.COM free((char *)ret->tes_fmri); 4902*7887SLiane.Praza@Sun.COM free(ret); 4903*7887SLiane.Praza@Sun.COM return (NULL); 4904*7887SLiane.Praza@Sun.COM } 4905*7887SLiane.Praza@Sun.COM ret->tes_flag = destroy_strings; 4906*7887SLiane.Praza@Sun.COM 4907*7887SLiane.Praza@Sun.COM /* Make space for a few errors. */ 4908*7887SLiane.Praza@Sun.COM ret->tes_errs = calloc(errs_size, sizeof (scf_tmpl_error_t *)); 4909*7887SLiane.Praza@Sun.COM if (ret->tes_errs == NULL) { 4910*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4911*7887SLiane.Praza@Sun.COM free((char *)ret->tes_fmri); 4912*7887SLiane.Praza@Sun.COM free((char *)ret->tes_prefix); 4913*7887SLiane.Praza@Sun.COM free(ret); 4914*7887SLiane.Praza@Sun.COM return (NULL); 4915*7887SLiane.Praza@Sun.COM } 4916*7887SLiane.Praza@Sun.COM ret->tes_errs_size = errs_size; 4917*7887SLiane.Praza@Sun.COM 4918*7887SLiane.Praza@Sun.COM return (ret); 4919*7887SLiane.Praza@Sun.COM } 4920*7887SLiane.Praza@Sun.COM 4921*7887SLiane.Praza@Sun.COM /* 4922*7887SLiane.Praza@Sun.COM * return 0 on success, if fails set scf_error() to: 4923*7887SLiane.Praza@Sun.COM * 4924*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 4925*7887SLiane.Praza@Sun.COM */ 4926*7887SLiane.Praza@Sun.COM int 4927*7887SLiane.Praza@Sun.COM _scf_tmpl_error_set_prefix(scf_tmpl_errors_t *errs, const char *prefix) 4928*7887SLiane.Praza@Sun.COM { 4929*7887SLiane.Praza@Sun.COM free((void *) errs->tes_prefix); 4930*7887SLiane.Praza@Sun.COM if (prefix == NULL) 4931*7887SLiane.Praza@Sun.COM errs->tes_prefix = strdup(""); 4932*7887SLiane.Praza@Sun.COM else 4933*7887SLiane.Praza@Sun.COM errs->tes_prefix = strdup(prefix); 4934*7887SLiane.Praza@Sun.COM if (errs->tes_prefix == NULL) { 4935*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4936*7887SLiane.Praza@Sun.COM return (-1); 4937*7887SLiane.Praza@Sun.COM } 4938*7887SLiane.Praza@Sun.COM return (0); 4939*7887SLiane.Praza@Sun.COM } 4940*7887SLiane.Praza@Sun.COM 4941*7887SLiane.Praza@Sun.COM /* 4942*7887SLiane.Praza@Sun.COM * 4943*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 4944*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 4945*7887SLiane.Praza@Sun.COM */ 4946*7887SLiane.Praza@Sun.COM int 4947*7887SLiane.Praza@Sun.COM _scf_tmpl_add_error(scf_tmpl_errors_t *errs, scf_tmpl_error_type_t type, 4948*7887SLiane.Praza@Sun.COM const char *pg_name, const char *prop_name, 4949*7887SLiane.Praza@Sun.COM const char *ev1, const char *ev2, const char *actual, 4950*7887SLiane.Praza@Sun.COM const char *tmpl_fmri, const char *tmpl_pg_name, const char *tmpl_pg_type, 4951*7887SLiane.Praza@Sun.COM const char *tmpl_prop_name, const char *tmpl_prop_type) 4952*7887SLiane.Praza@Sun.COM { 4953*7887SLiane.Praza@Sun.COM scf_tmpl_error_t *err; 4954*7887SLiane.Praza@Sun.COM 4955*7887SLiane.Praza@Sun.COM assert(errs != NULL); 4956*7887SLiane.Praza@Sun.COM assert(tmpl_fmri != NULL); 4957*7887SLiane.Praza@Sun.COM 4958*7887SLiane.Praza@Sun.COM err = _create_error(errs); 4959*7887SLiane.Praza@Sun.COM if (err == NULL) 4960*7887SLiane.Praza@Sun.COM return (-1); 4961*7887SLiane.Praza@Sun.COM 4962*7887SLiane.Praza@Sun.COM err->te_type = type; 4963*7887SLiane.Praza@Sun.COM err->te_pg_name = pg_name; 4964*7887SLiane.Praza@Sun.COM err->te_prop_name = prop_name; 4965*7887SLiane.Praza@Sun.COM err->te_ev1 = ev1; 4966*7887SLiane.Praza@Sun.COM err->te_ev2 = ev2; 4967*7887SLiane.Praza@Sun.COM err->te_actual = actual; 4968*7887SLiane.Praza@Sun.COM err->te_tmpl_fmri = tmpl_fmri; 4969*7887SLiane.Praza@Sun.COM err->te_tmpl_pg_name = tmpl_pg_name; 4970*7887SLiane.Praza@Sun.COM err->te_tmpl_pg_type = tmpl_pg_type; 4971*7887SLiane.Praza@Sun.COM err->te_tmpl_prop_name = tmpl_prop_name; 4972*7887SLiane.Praza@Sun.COM err->te_tmpl_prop_type = tmpl_prop_type; 4973*7887SLiane.Praza@Sun.COM 4974*7887SLiane.Praza@Sun.COM return (0); 4975*7887SLiane.Praza@Sun.COM } 4976*7887SLiane.Praza@Sun.COM 4977*7887SLiane.Praza@Sun.COM /* 4978*7887SLiane.Praza@Sun.COM * returns an allocated string that must be freed with free() 4979*7887SLiane.Praza@Sun.COM * string contains converted 64-bit integer value 4980*7887SLiane.Praza@Sun.COM * flag set for signed values 4981*7887SLiane.Praza@Sun.COM * if fails return NULL and set scf_error() to: 4982*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 4983*7887SLiane.Praza@Sun.COM */ 4984*7887SLiane.Praza@Sun.COM static char * 4985*7887SLiane.Praza@Sun.COM _val_to_string(uint64_t val, int flag) 4986*7887SLiane.Praza@Sun.COM { 4987*7887SLiane.Praza@Sun.COM ssize_t sz = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH) + 1; 4988*7887SLiane.Praza@Sun.COM char *buf; 4989*7887SLiane.Praza@Sun.COM 4990*7887SLiane.Praza@Sun.COM buf = malloc(sz); 4991*7887SLiane.Praza@Sun.COM if (buf == NULL) { 4992*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 4993*7887SLiane.Praza@Sun.COM return (NULL); 4994*7887SLiane.Praza@Sun.COM } 4995*7887SLiane.Praza@Sun.COM 4996*7887SLiane.Praza@Sun.COM if (flag == 0) 4997*7887SLiane.Praza@Sun.COM (void) snprintf(buf, sz, "%" PRIu64, val); 4998*7887SLiane.Praza@Sun.COM else 4999*7887SLiane.Praza@Sun.COM (void) snprintf(buf, sz, "%" PRIi64, (int64_t)val); 5000*7887SLiane.Praza@Sun.COM 5001*7887SLiane.Praza@Sun.COM return (buf); 5002*7887SLiane.Praza@Sun.COM } 5003*7887SLiane.Praza@Sun.COM 5004*7887SLiane.Praza@Sun.COM /* 5005*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5006*7887SLiane.Praza@Sun.COM * set scf_error() to: 5007*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5008*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5009*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5010*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5011*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5012*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5013*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5014*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5015*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5016*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5017*7887SLiane.Praza@Sun.COM */ 5018*7887SLiane.Praza@Sun.COM static int 5019*7887SLiane.Praza@Sun.COM _add_tmpl_missing_pg_error(scf_tmpl_errors_t *errs, scf_pg_tmpl_t *t) 5020*7887SLiane.Praza@Sun.COM { 5021*7887SLiane.Praza@Sun.COM char *ev1 = NULL; 5022*7887SLiane.Praza@Sun.COM char *ev2 = NULL; 5023*7887SLiane.Praza@Sun.COM char *t_fmri = NULL; 5024*7887SLiane.Praza@Sun.COM char *t_pg_name = NULL; 5025*7887SLiane.Praza@Sun.COM char *t_pg_type = NULL; 5026*7887SLiane.Praza@Sun.COM 5027*7887SLiane.Praza@Sun.COM if ((t_fmri = _scf_tmpl_get_fmri(t)) == NULL) 5028*7887SLiane.Praza@Sun.COM return (-1); 5029*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(t, &t_pg_name) == -1) { 5030*7887SLiane.Praza@Sun.COM goto cleanup; 5031*7887SLiane.Praza@Sun.COM } 5032*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(t, &t_pg_type) == -1) { 5033*7887SLiane.Praza@Sun.COM goto cleanup; 5034*7887SLiane.Praza@Sun.COM } 5035*7887SLiane.Praza@Sun.COM if ((ev1 = strdup(t_pg_name)) == NULL) { 5036*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5037*7887SLiane.Praza@Sun.COM goto cleanup; 5038*7887SLiane.Praza@Sun.COM } 5039*7887SLiane.Praza@Sun.COM if ((ev2 = strdup(t_pg_type)) == NULL) { 5040*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5041*7887SLiane.Praza@Sun.COM goto cleanup; 5042*7887SLiane.Praza@Sun.COM } 5043*7887SLiane.Praza@Sun.COM 5044*7887SLiane.Praza@Sun.COM return (_scf_tmpl_add_error(errs, SCF_TERR_MISSING_PG, NULL, NULL, ev1, 5045*7887SLiane.Praza@Sun.COM ev2, NULL, t_fmri, t_pg_name, t_pg_type, NULL, NULL)); 5046*7887SLiane.Praza@Sun.COM cleanup: 5047*7887SLiane.Praza@Sun.COM free(ev1); 5048*7887SLiane.Praza@Sun.COM free(ev2); 5049*7887SLiane.Praza@Sun.COM free(t_fmri); 5050*7887SLiane.Praza@Sun.COM free(t_pg_name); 5051*7887SLiane.Praza@Sun.COM free(t_pg_type); 5052*7887SLiane.Praza@Sun.COM return (-1); 5053*7887SLiane.Praza@Sun.COM } 5054*7887SLiane.Praza@Sun.COM 5055*7887SLiane.Praza@Sun.COM /* 5056*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5057*7887SLiane.Praza@Sun.COM * set scf_error() to: 5058*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5059*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5060*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5061*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5062*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5063*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5064*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5065*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5066*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5067*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5068*7887SLiane.Praza@Sun.COM */ 5069*7887SLiane.Praza@Sun.COM static int 5070*7887SLiane.Praza@Sun.COM _add_tmpl_wrong_pg_type_error(scf_tmpl_errors_t *errs, scf_pg_tmpl_t *t, 5071*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg) 5072*7887SLiane.Praza@Sun.COM { 5073*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 5074*7887SLiane.Praza@Sun.COM char *ev1 = NULL; 5075*7887SLiane.Praza@Sun.COM char *actual = NULL; 5076*7887SLiane.Praza@Sun.COM char *t_fmri = NULL; 5077*7887SLiane.Praza@Sun.COM char *t_pg_name = NULL; 5078*7887SLiane.Praza@Sun.COM char *t_pg_type = NULL; 5079*7887SLiane.Praza@Sun.COM 5080*7887SLiane.Praza@Sun.COM if ((t_fmri = _scf_tmpl_get_fmri(t)) == NULL) 5081*7887SLiane.Praza@Sun.COM return (-1); 5082*7887SLiane.Praza@Sun.COM if ((pg_name = _scf_get_pg_name(pg)) == NULL) 5083*7887SLiane.Praza@Sun.COM goto cleanup; 5084*7887SLiane.Praza@Sun.COM if ((actual = _scf_get_pg_type(pg)) == NULL) 5085*7887SLiane.Praza@Sun.COM goto cleanup; 5086*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(t, &t_pg_name) == -1) { 5087*7887SLiane.Praza@Sun.COM goto cleanup; 5088*7887SLiane.Praza@Sun.COM } 5089*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(t, &t_pg_type) == -1) { 5090*7887SLiane.Praza@Sun.COM goto cleanup; 5091*7887SLiane.Praza@Sun.COM } 5092*7887SLiane.Praza@Sun.COM if ((ev1 = strdup(t_pg_type)) == NULL) { 5093*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5094*7887SLiane.Praza@Sun.COM goto cleanup; 5095*7887SLiane.Praza@Sun.COM } 5096*7887SLiane.Praza@Sun.COM 5097*7887SLiane.Praza@Sun.COM return (_scf_tmpl_add_error(errs, SCF_TERR_WRONG_PG_TYPE, pg_name, NULL, 5098*7887SLiane.Praza@Sun.COM ev1, NULL, actual, t_fmri, t_pg_name, t_pg_type, NULL, NULL)); 5099*7887SLiane.Praza@Sun.COM cleanup: 5100*7887SLiane.Praza@Sun.COM free(pg_name); 5101*7887SLiane.Praza@Sun.COM free(ev1); 5102*7887SLiane.Praza@Sun.COM free(actual); 5103*7887SLiane.Praza@Sun.COM free(t_fmri); 5104*7887SLiane.Praza@Sun.COM free(t_pg_name); 5105*7887SLiane.Praza@Sun.COM free(t_pg_type); 5106*7887SLiane.Praza@Sun.COM return (-1); 5107*7887SLiane.Praza@Sun.COM } 5108*7887SLiane.Praza@Sun.COM 5109*7887SLiane.Praza@Sun.COM /* 5110*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5111*7887SLiane.Praza@Sun.COM * set scf_error() to: 5112*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5113*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5114*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5115*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5116*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5117*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5118*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5119*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5120*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5121*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5122*7887SLiane.Praza@Sun.COM */ 5123*7887SLiane.Praza@Sun.COM static int 5124*7887SLiane.Praza@Sun.COM _add_tmpl_missing_prop_error(scf_tmpl_errors_t *errs, scf_pg_tmpl_t *t, 5125*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg, const scf_prop_tmpl_t *pt) 5126*7887SLiane.Praza@Sun.COM { 5127*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 5128*7887SLiane.Praza@Sun.COM char *ev1 = NULL; 5129*7887SLiane.Praza@Sun.COM char *t_fmri = NULL; 5130*7887SLiane.Praza@Sun.COM char *t_pg_name = NULL; 5131*7887SLiane.Praza@Sun.COM char *t_pg_type = NULL; 5132*7887SLiane.Praza@Sun.COM char *t_prop_name = NULL; 5133*7887SLiane.Praza@Sun.COM char *t_prop_type = NULL; 5134*7887SLiane.Praza@Sun.COM 5135*7887SLiane.Praza@Sun.COM if ((t_fmri = _scf_tmpl_get_fmri(t)) == NULL) 5136*7887SLiane.Praza@Sun.COM return (-1); 5137*7887SLiane.Praza@Sun.COM if ((pg_name = _scf_get_pg_name(pg)) == NULL) 5138*7887SLiane.Praza@Sun.COM goto cleanup; 5139*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(t, &t_pg_name) == -1) { 5140*7887SLiane.Praza@Sun.COM goto cleanup; 5141*7887SLiane.Praza@Sun.COM } 5142*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(t, &t_pg_type) == -1) { 5143*7887SLiane.Praza@Sun.COM goto cleanup; 5144*7887SLiane.Praza@Sun.COM } 5145*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_name(pt, &t_prop_name) == -1) { 5146*7887SLiane.Praza@Sun.COM goto cleanup; 5147*7887SLiane.Praza@Sun.COM } 5148*7887SLiane.Praza@Sun.COM t_prop_type = _scf_read_tmpl_prop_type_as_string(pt); 5149*7887SLiane.Praza@Sun.COM if (t_prop_type != NULL && t_prop_type[0] == '\0') { 5150*7887SLiane.Praza@Sun.COM free(t_prop_type); 5151*7887SLiane.Praza@Sun.COM t_prop_type = NULL; 5152*7887SLiane.Praza@Sun.COM } else if (t_prop_type == NULL) { 5153*7887SLiane.Praza@Sun.COM goto cleanup; 5154*7887SLiane.Praza@Sun.COM } 5155*7887SLiane.Praza@Sun.COM if (t_prop_type == NULL) 5156*7887SLiane.Praza@Sun.COM if ((t_prop_type = strdup(SCF_TMPL_WILDCARD)) == NULL) { 5157*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5158*7887SLiane.Praza@Sun.COM goto cleanup; 5159*7887SLiane.Praza@Sun.COM } 5160*7887SLiane.Praza@Sun.COM if ((ev1 = strdup(t_prop_name)) == NULL) { 5161*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5162*7887SLiane.Praza@Sun.COM goto cleanup; 5163*7887SLiane.Praza@Sun.COM } 5164*7887SLiane.Praza@Sun.COM 5165*7887SLiane.Praza@Sun.COM return (_scf_tmpl_add_error(errs, SCF_TERR_MISSING_PROP, pg_name, NULL, 5166*7887SLiane.Praza@Sun.COM ev1, NULL, NULL, t_fmri, t_pg_name, t_pg_type, t_prop_name, 5167*7887SLiane.Praza@Sun.COM t_prop_type)); 5168*7887SLiane.Praza@Sun.COM cleanup: 5169*7887SLiane.Praza@Sun.COM free(pg_name); 5170*7887SLiane.Praza@Sun.COM free(ev1); 5171*7887SLiane.Praza@Sun.COM free(t_fmri); 5172*7887SLiane.Praza@Sun.COM free(t_pg_name); 5173*7887SLiane.Praza@Sun.COM free(t_pg_type); 5174*7887SLiane.Praza@Sun.COM free(t_prop_name); 5175*7887SLiane.Praza@Sun.COM free(t_prop_type); 5176*7887SLiane.Praza@Sun.COM return (-1); 5177*7887SLiane.Praza@Sun.COM } 5178*7887SLiane.Praza@Sun.COM 5179*7887SLiane.Praza@Sun.COM /* 5180*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5181*7887SLiane.Praza@Sun.COM * set scf_error() to: 5182*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5183*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5184*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5185*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5186*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5187*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5188*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5189*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5190*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5191*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5192*7887SLiane.Praza@Sun.COM */ 5193*7887SLiane.Praza@Sun.COM static int 5194*7887SLiane.Praza@Sun.COM _add_tmpl_wrong_prop_type_error(scf_tmpl_errors_t *errs, 5195*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg, const scf_prop_tmpl_t *pt, scf_property_t *prop) 5196*7887SLiane.Praza@Sun.COM { 5197*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 5198*7887SLiane.Praza@Sun.COM char *prop_name = NULL; 5199*7887SLiane.Praza@Sun.COM char *ev1 = NULL; 5200*7887SLiane.Praza@Sun.COM char *actual = NULL; 5201*7887SLiane.Praza@Sun.COM char *t_fmri = NULL; 5202*7887SLiane.Praza@Sun.COM char *t_pg_name = NULL; 5203*7887SLiane.Praza@Sun.COM char *t_pg_type = NULL; 5204*7887SLiane.Praza@Sun.COM char *t_prop_name = NULL; 5205*7887SLiane.Praza@Sun.COM char *t_prop_type = NULL; 5206*7887SLiane.Praza@Sun.COM 5207*7887SLiane.Praza@Sun.COM if ((t_fmri = _scf_tmpl_get_fmri(pt->prt_t)) == NULL) 5208*7887SLiane.Praza@Sun.COM return (-1); 5209*7887SLiane.Praza@Sun.COM if ((pg_name = _scf_get_pg_name(pg)) == NULL) 5210*7887SLiane.Praza@Sun.COM goto cleanup; 5211*7887SLiane.Praza@Sun.COM if ((prop_name = _scf_get_prop_name(prop)) == NULL) 5212*7887SLiane.Praza@Sun.COM goto cleanup; 5213*7887SLiane.Praza@Sun.COM if ((actual = _scf_get_prop_type(prop)) == NULL) 5214*7887SLiane.Praza@Sun.COM goto cleanup; 5215*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(pt->prt_t, &t_pg_name) == -1) { 5216*7887SLiane.Praza@Sun.COM goto cleanup; 5217*7887SLiane.Praza@Sun.COM } 5218*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(pt->prt_t, &t_pg_type) == -1) { 5219*7887SLiane.Praza@Sun.COM goto cleanup; 5220*7887SLiane.Praza@Sun.COM } 5221*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_name(pt, &t_prop_name) == -1) { 5222*7887SLiane.Praza@Sun.COM goto cleanup; 5223*7887SLiane.Praza@Sun.COM } 5224*7887SLiane.Praza@Sun.COM t_prop_type = _scf_read_tmpl_prop_type_as_string(pt); 5225*7887SLiane.Praza@Sun.COM if (t_prop_type != NULL && t_prop_type[0] == '\0') { 5226*7887SLiane.Praza@Sun.COM free(t_prop_type); 5227*7887SLiane.Praza@Sun.COM t_prop_type = NULL; 5228*7887SLiane.Praza@Sun.COM } else if (t_prop_type == NULL) { 5229*7887SLiane.Praza@Sun.COM goto cleanup; 5230*7887SLiane.Praza@Sun.COM } 5231*7887SLiane.Praza@Sun.COM if (t_prop_type == NULL) 5232*7887SLiane.Praza@Sun.COM if ((t_prop_type = strdup(SCF_TMPL_WILDCARD)) == NULL) { 5233*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5234*7887SLiane.Praza@Sun.COM goto cleanup; 5235*7887SLiane.Praza@Sun.COM } 5236*7887SLiane.Praza@Sun.COM if ((ev1 = strdup(t_prop_type)) == NULL) { 5237*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5238*7887SLiane.Praza@Sun.COM goto cleanup; 5239*7887SLiane.Praza@Sun.COM } 5240*7887SLiane.Praza@Sun.COM 5241*7887SLiane.Praza@Sun.COM return (_scf_tmpl_add_error(errs, SCF_TERR_WRONG_PROP_TYPE, pg_name, 5242*7887SLiane.Praza@Sun.COM prop_name, ev1, NULL, actual, t_fmri, t_pg_name, t_pg_type, 5243*7887SLiane.Praza@Sun.COM t_prop_name, t_prop_type)); 5244*7887SLiane.Praza@Sun.COM cleanup: 5245*7887SLiane.Praza@Sun.COM free(pg_name); 5246*7887SLiane.Praza@Sun.COM free(prop_name); 5247*7887SLiane.Praza@Sun.COM free(ev1); 5248*7887SLiane.Praza@Sun.COM free(actual); 5249*7887SLiane.Praza@Sun.COM free(t_fmri); 5250*7887SLiane.Praza@Sun.COM free(t_pg_name); 5251*7887SLiane.Praza@Sun.COM free(t_pg_type); 5252*7887SLiane.Praza@Sun.COM free(t_prop_name); 5253*7887SLiane.Praza@Sun.COM free(t_prop_type); 5254*7887SLiane.Praza@Sun.COM return (-1); 5255*7887SLiane.Praza@Sun.COM } 5256*7887SLiane.Praza@Sun.COM 5257*7887SLiane.Praza@Sun.COM /* 5258*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5259*7887SLiane.Praza@Sun.COM * set scf_error() to: 5260*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5261*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5262*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5263*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5264*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5265*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5266*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5267*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5268*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5269*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5270*7887SLiane.Praza@Sun.COM */ 5271*7887SLiane.Praza@Sun.COM static int 5272*7887SLiane.Praza@Sun.COM _add_tmpl_count_error(scf_tmpl_errors_t *errs, scf_tmpl_error_type_t type, 5273*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg, const scf_prop_tmpl_t *pt, scf_property_t *prop, 5274*7887SLiane.Praza@Sun.COM uint64_t count, uint64_t *min, uint64_t *max) 5275*7887SLiane.Praza@Sun.COM { 5276*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 5277*7887SLiane.Praza@Sun.COM char *prop_name = NULL; 5278*7887SLiane.Praza@Sun.COM char *s_min = NULL; 5279*7887SLiane.Praza@Sun.COM char *s_max = NULL; 5280*7887SLiane.Praza@Sun.COM char *num = NULL; 5281*7887SLiane.Praza@Sun.COM char *t_fmri = NULL; 5282*7887SLiane.Praza@Sun.COM char *t_pg_name = NULL; 5283*7887SLiane.Praza@Sun.COM char *t_pg_type = NULL; 5284*7887SLiane.Praza@Sun.COM char *t_prop_name = NULL; 5285*7887SLiane.Praza@Sun.COM char *t_prop_type = NULL; 5286*7887SLiane.Praza@Sun.COM 5287*7887SLiane.Praza@Sun.COM if ((t_fmri = _scf_tmpl_get_fmri(pt->prt_t)) == NULL) 5288*7887SLiane.Praza@Sun.COM return (-1); 5289*7887SLiane.Praza@Sun.COM switch (type) { 5290*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 5291*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 5292*7887SLiane.Praza@Sun.COM if ((pg_name = _scf_get_pg_name(pg)) == NULL) 5293*7887SLiane.Praza@Sun.COM goto cleanup; 5294*7887SLiane.Praza@Sun.COM if ((prop_name = _scf_get_prop_name(prop)) == NULL) 5295*7887SLiane.Praza@Sun.COM goto cleanup; 5296*7887SLiane.Praza@Sun.COM break; 5297*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 5298*7887SLiane.Praza@Sun.COM /* keep pg_name = NULL and prop_name = NULL */ 5299*7887SLiane.Praza@Sun.COM break; 5300*7887SLiane.Praza@Sun.COM } 5301*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(pt->prt_t, &t_pg_name) == -1) { 5302*7887SLiane.Praza@Sun.COM goto cleanup; 5303*7887SLiane.Praza@Sun.COM } 5304*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(pt->prt_t, &t_pg_type) == -1) { 5305*7887SLiane.Praza@Sun.COM goto cleanup; 5306*7887SLiane.Praza@Sun.COM } 5307*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_name(pt, &t_prop_name) == -1) { 5308*7887SLiane.Praza@Sun.COM goto cleanup; 5309*7887SLiane.Praza@Sun.COM } 5310*7887SLiane.Praza@Sun.COM t_prop_type = _scf_read_tmpl_prop_type_as_string(pt); 5311*7887SLiane.Praza@Sun.COM if (t_prop_type != NULL && t_prop_type[0] == '\0') { 5312*7887SLiane.Praza@Sun.COM free(t_prop_type); 5313*7887SLiane.Praza@Sun.COM t_prop_type = NULL; 5314*7887SLiane.Praza@Sun.COM } else if (t_prop_type == NULL) { 5315*7887SLiane.Praza@Sun.COM goto cleanup; 5316*7887SLiane.Praza@Sun.COM } 5317*7887SLiane.Praza@Sun.COM if (t_prop_type == NULL) 5318*7887SLiane.Praza@Sun.COM if ((t_prop_type = strdup(SCF_TMPL_WILDCARD)) == NULL) { 5319*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5320*7887SLiane.Praza@Sun.COM goto cleanup; 5321*7887SLiane.Praza@Sun.COM } 5322*7887SLiane.Praza@Sun.COM if (min == NULL) { 5323*7887SLiane.Praza@Sun.COM if ((s_min = strdup("")) == NULL) { 5324*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5325*7887SLiane.Praza@Sun.COM goto cleanup; 5326*7887SLiane.Praza@Sun.COM } 5327*7887SLiane.Praza@Sun.COM } else { 5328*7887SLiane.Praza@Sun.COM if ((s_min = _val_to_string(*min, 0)) == NULL) { 5329*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5330*7887SLiane.Praza@Sun.COM goto cleanup; 5331*7887SLiane.Praza@Sun.COM } 5332*7887SLiane.Praza@Sun.COM } 5333*7887SLiane.Praza@Sun.COM if (max == NULL) { 5334*7887SLiane.Praza@Sun.COM if ((s_max = strdup("")) == NULL) { 5335*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5336*7887SLiane.Praza@Sun.COM goto cleanup; 5337*7887SLiane.Praza@Sun.COM } 5338*7887SLiane.Praza@Sun.COM } else { 5339*7887SLiane.Praza@Sun.COM if ((s_max = _val_to_string(*max, 0)) == NULL) { 5340*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5341*7887SLiane.Praza@Sun.COM goto cleanup; 5342*7887SLiane.Praza@Sun.COM } 5343*7887SLiane.Praza@Sun.COM } 5344*7887SLiane.Praza@Sun.COM if ((num = _val_to_string(count, 0)) == NULL) { 5345*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5346*7887SLiane.Praza@Sun.COM goto cleanup; 5347*7887SLiane.Praza@Sun.COM } 5348*7887SLiane.Praza@Sun.COM 5349*7887SLiane.Praza@Sun.COM return (_scf_tmpl_add_error(errs, type, pg_name, prop_name, s_min, 5350*7887SLiane.Praza@Sun.COM s_max, num, t_fmri, t_pg_name, t_pg_type, t_prop_name, 5351*7887SLiane.Praza@Sun.COM t_prop_type)); 5352*7887SLiane.Praza@Sun.COM cleanup: 5353*7887SLiane.Praza@Sun.COM free(pg_name); 5354*7887SLiane.Praza@Sun.COM free(prop_name); 5355*7887SLiane.Praza@Sun.COM free(s_min); 5356*7887SLiane.Praza@Sun.COM free(s_max); 5357*7887SLiane.Praza@Sun.COM free(num); 5358*7887SLiane.Praza@Sun.COM free(t_fmri); 5359*7887SLiane.Praza@Sun.COM free(t_pg_name); 5360*7887SLiane.Praza@Sun.COM free(t_pg_type); 5361*7887SLiane.Praza@Sun.COM free(t_prop_name); 5362*7887SLiane.Praza@Sun.COM free(t_prop_type); 5363*7887SLiane.Praza@Sun.COM return (-1); 5364*7887SLiane.Praza@Sun.COM } 5365*7887SLiane.Praza@Sun.COM 5366*7887SLiane.Praza@Sun.COM /* 5367*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5368*7887SLiane.Praza@Sun.COM * set scf_error() to: 5369*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5370*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5371*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5372*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5373*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5374*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5375*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5376*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5377*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5378*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5379*7887SLiane.Praza@Sun.COM */ 5380*7887SLiane.Praza@Sun.COM static int 5381*7887SLiane.Praza@Sun.COM _add_tmpl_constraint_error(scf_tmpl_errors_t *errs, scf_tmpl_error_type_t type, 5382*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg, const scf_prop_tmpl_t *pt, scf_property_t *prop, 5383*7887SLiane.Praza@Sun.COM scf_value_t *val) 5384*7887SLiane.Praza@Sun.COM { 5385*7887SLiane.Praza@Sun.COM scf_type_t val_type; 5386*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 5387*7887SLiane.Praza@Sun.COM char *prop_name = NULL; 5388*7887SLiane.Praza@Sun.COM char *value = NULL; 5389*7887SLiane.Praza@Sun.COM char *t_fmri = NULL; 5390*7887SLiane.Praza@Sun.COM char *t_pg_name = NULL; 5391*7887SLiane.Praza@Sun.COM char *t_pg_type = NULL; 5392*7887SLiane.Praza@Sun.COM char *t_prop_name = NULL; 5393*7887SLiane.Praza@Sun.COM char *t_prop_type = NULL; 5394*7887SLiane.Praza@Sun.COM 5395*7887SLiane.Praza@Sun.COM if ((t_fmri = _scf_tmpl_get_fmri(pt->prt_t)) == NULL) 5396*7887SLiane.Praza@Sun.COM return (-1); 5397*7887SLiane.Praza@Sun.COM switch (type) { 5398*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 5399*7887SLiane.Praza@Sun.COM if ((pg_name = _scf_get_pg_name(pg)) == NULL) 5400*7887SLiane.Praza@Sun.COM goto cleanup; 5401*7887SLiane.Praza@Sun.COM if ((prop_name = _scf_get_prop_name(prop)) == NULL) 5402*7887SLiane.Praza@Sun.COM goto cleanup; 5403*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 5404*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 5405*7887SLiane.Praza@Sun.COM /* keep pg_name = NULL and prop_name = NULL */ 5406*7887SLiane.Praza@Sun.COM if ((value = _scf_value_get_as_string(val)) == NULL) 5407*7887SLiane.Praza@Sun.COM goto cleanup; 5408*7887SLiane.Praza@Sun.COM break; 5409*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 5410*7887SLiane.Praza@Sun.COM /* keep pg_name = NULL and prop_name = NULL */ 5411*7887SLiane.Praza@Sun.COM /* use value for value type */ 5412*7887SLiane.Praza@Sun.COM val_type = scf_value_type(val); 5413*7887SLiane.Praza@Sun.COM if ((value = strdup(scf_type_to_string(val_type))) == 5414*7887SLiane.Praza@Sun.COM NULL) { 5415*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5416*7887SLiane.Praza@Sun.COM goto cleanup; 5417*7887SLiane.Praza@Sun.COM } 5418*7887SLiane.Praza@Sun.COM break; 5419*7887SLiane.Praza@Sun.COM } 5420*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(pt->prt_t, &t_pg_name) == -1) { 5421*7887SLiane.Praza@Sun.COM goto cleanup; 5422*7887SLiane.Praza@Sun.COM } 5423*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(pt->prt_t, &t_pg_type) == -1) { 5424*7887SLiane.Praza@Sun.COM goto cleanup; 5425*7887SLiane.Praza@Sun.COM } 5426*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_name(pt, &t_prop_name) == -1) { 5427*7887SLiane.Praza@Sun.COM goto cleanup; 5428*7887SLiane.Praza@Sun.COM } 5429*7887SLiane.Praza@Sun.COM t_prop_type = _scf_read_tmpl_prop_type_as_string(pt); 5430*7887SLiane.Praza@Sun.COM if (t_prop_type != NULL && t_prop_type[0] == '\0') { 5431*7887SLiane.Praza@Sun.COM free(t_prop_type); 5432*7887SLiane.Praza@Sun.COM t_prop_type = NULL; 5433*7887SLiane.Praza@Sun.COM } else if (t_prop_type == NULL) { 5434*7887SLiane.Praza@Sun.COM goto cleanup; 5435*7887SLiane.Praza@Sun.COM } 5436*7887SLiane.Praza@Sun.COM if (t_prop_type == NULL) 5437*7887SLiane.Praza@Sun.COM if ((t_prop_type = strdup(SCF_TMPL_WILDCARD)) == NULL) { 5438*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5439*7887SLiane.Praza@Sun.COM goto cleanup; 5440*7887SLiane.Praza@Sun.COM } 5441*7887SLiane.Praza@Sun.COM 5442*7887SLiane.Praza@Sun.COM return (_scf_tmpl_add_error(errs, type, pg_name, prop_name, NULL, NULL, 5443*7887SLiane.Praza@Sun.COM value, t_fmri, t_pg_name, t_pg_type, t_prop_name, t_prop_type)); 5444*7887SLiane.Praza@Sun.COM cleanup: 5445*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 5446*7887SLiane.Praza@Sun.COM free(pg_name); 5447*7887SLiane.Praza@Sun.COM free(prop_name); 5448*7887SLiane.Praza@Sun.COM free(value); 5449*7887SLiane.Praza@Sun.COM free(t_fmri); 5450*7887SLiane.Praza@Sun.COM free(t_pg_name); 5451*7887SLiane.Praza@Sun.COM free(t_pg_type); 5452*7887SLiane.Praza@Sun.COM free(t_prop_name); 5453*7887SLiane.Praza@Sun.COM free(t_prop_type); 5454*7887SLiane.Praza@Sun.COM return (-1); 5455*7887SLiane.Praza@Sun.COM } 5456*7887SLiane.Praza@Sun.COM 5457*7887SLiane.Praza@Sun.COM /* 5458*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5459*7887SLiane.Praza@Sun.COM * set scf_error() to: 5460*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5461*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5462*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5463*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5464*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5465*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5466*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5467*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5468*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5469*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5470*7887SLiane.Praza@Sun.COM */ 5471*7887SLiane.Praza@Sun.COM static int 5472*7887SLiane.Praza@Sun.COM _add_tmpl_int_error(scf_tmpl_errors_t *errs, scf_tmpl_error_type_t type, 5473*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg, const scf_prop_tmpl_t *pt, scf_property_t *prop, 5474*7887SLiane.Praza@Sun.COM int64_t val, int64_t *min, int64_t *max) 5475*7887SLiane.Praza@Sun.COM { 5476*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 5477*7887SLiane.Praza@Sun.COM char *prop_name = NULL; 5478*7887SLiane.Praza@Sun.COM char *s_min = NULL; 5479*7887SLiane.Praza@Sun.COM char *s_max = NULL; 5480*7887SLiane.Praza@Sun.COM char *value = NULL; 5481*7887SLiane.Praza@Sun.COM char *t_fmri = NULL; 5482*7887SLiane.Praza@Sun.COM char *t_pg_name = NULL; 5483*7887SLiane.Praza@Sun.COM char *t_pg_type = NULL; 5484*7887SLiane.Praza@Sun.COM char *t_prop_name = NULL; 5485*7887SLiane.Praza@Sun.COM char *t_prop_type = NULL; 5486*7887SLiane.Praza@Sun.COM 5487*7887SLiane.Praza@Sun.COM if ((t_fmri = _scf_tmpl_get_fmri(pt->prt_t)) == NULL) 5488*7887SLiane.Praza@Sun.COM return (-1); 5489*7887SLiane.Praza@Sun.COM 5490*7887SLiane.Praza@Sun.COM switch (type) { 5491*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 5492*7887SLiane.Praza@Sun.COM if ((pg_name = _scf_get_pg_name(pg)) == NULL) 5493*7887SLiane.Praza@Sun.COM goto cleanup; 5494*7887SLiane.Praza@Sun.COM if ((prop_name = _scf_get_prop_name(prop)) == NULL) 5495*7887SLiane.Praza@Sun.COM goto cleanup; 5496*7887SLiane.Praza@Sun.COM break; 5497*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 5498*7887SLiane.Praza@Sun.COM /* keep pg_name = NULL and prop_name = NULL */ 5499*7887SLiane.Praza@Sun.COM break; 5500*7887SLiane.Praza@Sun.COM } 5501*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(pt->prt_t, &t_pg_name) == -1) { 5502*7887SLiane.Praza@Sun.COM goto cleanup; 5503*7887SLiane.Praza@Sun.COM } 5504*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(pt->prt_t, &t_pg_type) == -1) { 5505*7887SLiane.Praza@Sun.COM goto cleanup; 5506*7887SLiane.Praza@Sun.COM } 5507*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_name(pt, &t_prop_name) == -1) { 5508*7887SLiane.Praza@Sun.COM goto cleanup; 5509*7887SLiane.Praza@Sun.COM } 5510*7887SLiane.Praza@Sun.COM t_prop_type = _scf_read_tmpl_prop_type_as_string(pt); 5511*7887SLiane.Praza@Sun.COM if (t_prop_type != NULL && t_prop_type[0] == '\0') { 5512*7887SLiane.Praza@Sun.COM free(t_prop_type); 5513*7887SLiane.Praza@Sun.COM t_prop_type = NULL; 5514*7887SLiane.Praza@Sun.COM } else if (t_prop_type == NULL) { 5515*7887SLiane.Praza@Sun.COM goto cleanup; 5516*7887SLiane.Praza@Sun.COM } 5517*7887SLiane.Praza@Sun.COM if (t_prop_type == NULL) 5518*7887SLiane.Praza@Sun.COM if ((t_prop_type = strdup(SCF_TMPL_WILDCARD)) == NULL) { 5519*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5520*7887SLiane.Praza@Sun.COM goto cleanup; 5521*7887SLiane.Praza@Sun.COM } 5522*7887SLiane.Praza@Sun.COM if (min == NULL) { 5523*7887SLiane.Praza@Sun.COM if ((s_min = strdup("")) == NULL) { 5524*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5525*7887SLiane.Praza@Sun.COM goto cleanup; 5526*7887SLiane.Praza@Sun.COM } 5527*7887SLiane.Praza@Sun.COM } else { 5528*7887SLiane.Praza@Sun.COM if ((s_min = _val_to_string(*((uint64_t *)min), 1)) == NULL) { 5529*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5530*7887SLiane.Praza@Sun.COM goto cleanup; 5531*7887SLiane.Praza@Sun.COM } 5532*7887SLiane.Praza@Sun.COM } 5533*7887SLiane.Praza@Sun.COM if (max == NULL) { 5534*7887SLiane.Praza@Sun.COM if ((s_max = strdup("")) == NULL) { 5535*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5536*7887SLiane.Praza@Sun.COM goto cleanup; 5537*7887SLiane.Praza@Sun.COM } 5538*7887SLiane.Praza@Sun.COM } else { 5539*7887SLiane.Praza@Sun.COM if ((s_max = _val_to_string(*((uint64_t *)max), 1)) == NULL) { 5540*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5541*7887SLiane.Praza@Sun.COM goto cleanup; 5542*7887SLiane.Praza@Sun.COM } 5543*7887SLiane.Praza@Sun.COM } 5544*7887SLiane.Praza@Sun.COM if ((value = _val_to_string((uint64_t)val, 1)) == NULL) { 5545*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5546*7887SLiane.Praza@Sun.COM goto cleanup; 5547*7887SLiane.Praza@Sun.COM } 5548*7887SLiane.Praza@Sun.COM 5549*7887SLiane.Praza@Sun.COM return (_scf_tmpl_add_error(errs, type, pg_name, prop_name, s_min, 5550*7887SLiane.Praza@Sun.COM s_max, value, t_fmri, t_pg_name, t_pg_type, t_prop_name, 5551*7887SLiane.Praza@Sun.COM t_prop_type)); 5552*7887SLiane.Praza@Sun.COM cleanup: 5553*7887SLiane.Praza@Sun.COM free(pg_name); 5554*7887SLiane.Praza@Sun.COM free(prop_name); 5555*7887SLiane.Praza@Sun.COM free(s_min); 5556*7887SLiane.Praza@Sun.COM free(s_max); 5557*7887SLiane.Praza@Sun.COM free(value); 5558*7887SLiane.Praza@Sun.COM free(t_fmri); 5559*7887SLiane.Praza@Sun.COM free(t_pg_name); 5560*7887SLiane.Praza@Sun.COM free(t_pg_type); 5561*7887SLiane.Praza@Sun.COM free(t_prop_name); 5562*7887SLiane.Praza@Sun.COM free(t_prop_type); 5563*7887SLiane.Praza@Sun.COM return (-1); 5564*7887SLiane.Praza@Sun.COM } 5565*7887SLiane.Praza@Sun.COM 5566*7887SLiane.Praza@Sun.COM /* 5567*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5568*7887SLiane.Praza@Sun.COM * set scf_error() to: 5569*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5570*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5571*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5572*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5573*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5574*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5575*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5576*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5577*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5578*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5579*7887SLiane.Praza@Sun.COM */ 5580*7887SLiane.Praza@Sun.COM static int 5581*7887SLiane.Praza@Sun.COM _add_tmpl_pg_redefine_error(scf_tmpl_errors_t *errs, scf_pg_tmpl_t *t, 5582*7887SLiane.Praza@Sun.COM scf_pg_tmpl_t *r) 5583*7887SLiane.Praza@Sun.COM { 5584*7887SLiane.Praza@Sun.COM char *ev1 = NULL; 5585*7887SLiane.Praza@Sun.COM char *ev2 = NULL; 5586*7887SLiane.Praza@Sun.COM char *t_fmri = NULL; 5587*7887SLiane.Praza@Sun.COM char *t_pg_name = NULL; 5588*7887SLiane.Praza@Sun.COM char *t_pg_type = NULL; 5589*7887SLiane.Praza@Sun.COM 5590*7887SLiane.Praza@Sun.COM if ((t_fmri = _scf_tmpl_get_fmri(r)) == NULL) 5591*7887SLiane.Praza@Sun.COM return (-1); 5592*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(r, &t_pg_name) == -1) { 5593*7887SLiane.Praza@Sun.COM goto cleanup; 5594*7887SLiane.Praza@Sun.COM } 5595*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(r, &t_pg_type) == -1) { 5596*7887SLiane.Praza@Sun.COM goto cleanup; 5597*7887SLiane.Praza@Sun.COM } 5598*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(t, &ev1) == -1) { 5599*7887SLiane.Praza@Sun.COM goto cleanup; 5600*7887SLiane.Praza@Sun.COM } 5601*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(t, &ev2) == -1) { 5602*7887SLiane.Praza@Sun.COM goto cleanup; 5603*7887SLiane.Praza@Sun.COM } 5604*7887SLiane.Praza@Sun.COM 5605*7887SLiane.Praza@Sun.COM return (_scf_tmpl_add_error(errs, SCF_TERR_PG_REDEFINE, NULL, NULL, 5606*7887SLiane.Praza@Sun.COM ev1, ev2, NULL, t_fmri, t_pg_name, t_pg_type, NULL, NULL)); 5607*7887SLiane.Praza@Sun.COM cleanup: 5608*7887SLiane.Praza@Sun.COM free(ev1); 5609*7887SLiane.Praza@Sun.COM free(ev2); 5610*7887SLiane.Praza@Sun.COM free(t_fmri); 5611*7887SLiane.Praza@Sun.COM free(t_pg_name); 5612*7887SLiane.Praza@Sun.COM free(t_pg_type); 5613*7887SLiane.Praza@Sun.COM return (-1); 5614*7887SLiane.Praza@Sun.COM } 5615*7887SLiane.Praza@Sun.COM 5616*7887SLiane.Praza@Sun.COM /* 5617*7887SLiane.Praza@Sun.COM * return 0 if value is within count ranges constraint. 5618*7887SLiane.Praza@Sun.COM * return -1 otherwise 5619*7887SLiane.Praza@Sun.COM */ 5620*7887SLiane.Praza@Sun.COM static int 5621*7887SLiane.Praza@Sun.COM _check_count_ranges(scf_count_ranges_t *cr, uint64_t v) 5622*7887SLiane.Praza@Sun.COM { 5623*7887SLiane.Praza@Sun.COM int i; 5624*7887SLiane.Praza@Sun.COM 5625*7887SLiane.Praza@Sun.COM for (i = 0; i < cr->scr_num_ranges; ++i) { 5626*7887SLiane.Praza@Sun.COM if (v >= cr->scr_min[i] && 5627*7887SLiane.Praza@Sun.COM v <= cr->scr_max[i]) { 5628*7887SLiane.Praza@Sun.COM /* value is within ranges constraint */ 5629*7887SLiane.Praza@Sun.COM return (0); 5630*7887SLiane.Praza@Sun.COM } 5631*7887SLiane.Praza@Sun.COM } 5632*7887SLiane.Praza@Sun.COM return (-1); 5633*7887SLiane.Praza@Sun.COM } 5634*7887SLiane.Praza@Sun.COM 5635*7887SLiane.Praza@Sun.COM /* 5636*7887SLiane.Praza@Sun.COM * return 0 if value is within count ranges constraint. 5637*7887SLiane.Praza@Sun.COM * return -1 otherwise 5638*7887SLiane.Praza@Sun.COM */ 5639*7887SLiane.Praza@Sun.COM static int 5640*7887SLiane.Praza@Sun.COM _check_int_ranges(scf_int_ranges_t *ir, int64_t v) 5641*7887SLiane.Praza@Sun.COM { 5642*7887SLiane.Praza@Sun.COM int i; 5643*7887SLiane.Praza@Sun.COM 5644*7887SLiane.Praza@Sun.COM for (i = 0; i < ir->sir_num_ranges; ++i) { 5645*7887SLiane.Praza@Sun.COM if (v >= ir->sir_min[i] && 5646*7887SLiane.Praza@Sun.COM v <= ir->sir_max[i]) { 5647*7887SLiane.Praza@Sun.COM /* value is within integer ranges constraint */ 5648*7887SLiane.Praza@Sun.COM return (0); 5649*7887SLiane.Praza@Sun.COM } 5650*7887SLiane.Praza@Sun.COM } 5651*7887SLiane.Praza@Sun.COM return (-1); 5652*7887SLiane.Praza@Sun.COM } 5653*7887SLiane.Praza@Sun.COM 5654*7887SLiane.Praza@Sun.COM /* 5655*7887SLiane.Praza@Sun.COM * int _value_in_constraint() 5656*7887SLiane.Praza@Sun.COM * 5657*7887SLiane.Praza@Sun.COM * Checks whether the supplied value violates any of the constraints 5658*7887SLiane.Praza@Sun.COM * specified in the supplied property template. If it does, an appropriate 5659*7887SLiane.Praza@Sun.COM * error is appended to "errs". pg and prop, if supplied, are used to 5660*7887SLiane.Praza@Sun.COM * augment the information in the error. Returns 0 on success. 5661*7887SLiane.Praza@Sun.COM * 5662*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 5663*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5664*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5665*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5666*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5667*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5668*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 5669*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5670*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5671*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5672*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5673*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5674*7887SLiane.Praza@Sun.COM */ 5675*7887SLiane.Praza@Sun.COM static int 5676*7887SLiane.Praza@Sun.COM _value_in_constraint(scf_propertygroup_t *pg, scf_property_t *prop, 5677*7887SLiane.Praza@Sun.COM const scf_prop_tmpl_t *pt, scf_value_t *value, scf_tmpl_errors_t *errs) 5678*7887SLiane.Praza@Sun.COM { 5679*7887SLiane.Praza@Sun.COM scf_type_t type, tmpl_type; 5680*7887SLiane.Praza@Sun.COM scf_values_t vals; 5681*7887SLiane.Praza@Sun.COM scf_tmpl_error_type_t terr_type; 5682*7887SLiane.Praza@Sun.COM uint64_t v_count; 5683*7887SLiane.Praza@Sun.COM int64_t v_int; 5684*7887SLiane.Praza@Sun.COM char *vstr; 5685*7887SLiane.Praza@Sun.COM ssize_t sz = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH) + 1; 5686*7887SLiane.Praza@Sun.COM ssize_t ret = 0; 5687*7887SLiane.Praza@Sun.COM char **constraints; 5688*7887SLiane.Praza@Sun.COM int n = 0; 5689*7887SLiane.Praza@Sun.COM int r; 5690*7887SLiane.Praza@Sun.COM int err_flag = 0; 5691*7887SLiane.Praza@Sun.COM scf_count_ranges_t cr; 5692*7887SLiane.Praza@Sun.COM scf_int_ranges_t ir; 5693*7887SLiane.Praza@Sun.COM 5694*7887SLiane.Praza@Sun.COM type = scf_value_type(value); 5695*7887SLiane.Praza@Sun.COM if (type == SCF_TYPE_INVALID) { 5696*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 5697*7887SLiane.Praza@Sun.COM return (-1); 5698*7887SLiane.Praza@Sun.COM } 5699*7887SLiane.Praza@Sun.COM 5700*7887SLiane.Praza@Sun.COM /* Check if template type matches value type. */ 5701*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_type(pt, &tmpl_type) == -1) { 5702*7887SLiane.Praza@Sun.COM if (scf_error() != SCF_ERROR_NOT_FOUND) 5703*7887SLiane.Praza@Sun.COM /* type is not wildcarded */ 5704*7887SLiane.Praza@Sun.COM return (-1); 5705*7887SLiane.Praza@Sun.COM } else if (tmpl_type != type) { 5706*7887SLiane.Praza@Sun.COM if (errs != NULL) { 5707*7887SLiane.Praza@Sun.COM if (pg == NULL && prop == NULL) { 5708*7887SLiane.Praza@Sun.COM if (_add_tmpl_constraint_error(errs, 5709*7887SLiane.Praza@Sun.COM SCF_TERR_PROP_TYPE_MISMATCH, NULL, pt, 5710*7887SLiane.Praza@Sun.COM NULL, value) == -1) 5711*7887SLiane.Praza@Sun.COM return (-1); 5712*7887SLiane.Praza@Sun.COM } else { 5713*7887SLiane.Praza@Sun.COM if (_add_tmpl_wrong_prop_type_error(errs, pg, 5714*7887SLiane.Praza@Sun.COM pt, prop) == -1) 5715*7887SLiane.Praza@Sun.COM return (-1); 5716*7887SLiane.Praza@Sun.COM } 5717*7887SLiane.Praza@Sun.COM } 5718*7887SLiane.Praza@Sun.COM return (1); 5719*7887SLiane.Praza@Sun.COM } 5720*7887SLiane.Praza@Sun.COM 5721*7887SLiane.Praza@Sun.COM /* Numeric values should be checked against any range constraints. */ 5722*7887SLiane.Praza@Sun.COM switch (type) { 5723*7887SLiane.Praza@Sun.COM case SCF_TYPE_COUNT: 5724*7887SLiane.Praza@Sun.COM r = scf_value_get_count(value, &v_count); 5725*7887SLiane.Praza@Sun.COM assert(r == 0); 5726*7887SLiane.Praza@Sun.COM 5727*7887SLiane.Praza@Sun.COM if (scf_tmpl_value_count_range_constraints(pt, &cr) != 0) { 5728*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_NOT_FOUND) 5729*7887SLiane.Praza@Sun.COM break; 5730*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) 5731*7887SLiane.Praza@Sun.COM (void) scf_set_error( 5732*7887SLiane.Praza@Sun.COM SCF_ERROR_TEMPLATE_INVALID); 5733*7887SLiane.Praza@Sun.COM return (-1); 5734*7887SLiane.Praza@Sun.COM } else { 5735*7887SLiane.Praza@Sun.COM if (_check_count_ranges(&cr, v_count) == 0) { 5736*7887SLiane.Praza@Sun.COM /* value is within ranges constraint */ 5737*7887SLiane.Praza@Sun.COM scf_count_ranges_destroy(&cr); 5738*7887SLiane.Praza@Sun.COM return (0); 5739*7887SLiane.Praza@Sun.COM } 5740*7887SLiane.Praza@Sun.COM scf_count_ranges_destroy(&cr); 5741*7887SLiane.Praza@Sun.COM } 5742*7887SLiane.Praza@Sun.COM 5743*7887SLiane.Praza@Sun.COM /* 5744*7887SLiane.Praza@Sun.COM * If we get here, we have a possible constraint 5745*7887SLiane.Praza@Sun.COM * violation. 5746*7887SLiane.Praza@Sun.COM */ 5747*7887SLiane.Praza@Sun.COM err_flag |= 0x1; /* RANGE_VIOLATION, count */ 5748*7887SLiane.Praza@Sun.COM break; 5749*7887SLiane.Praza@Sun.COM case SCF_TYPE_INTEGER: 5750*7887SLiane.Praza@Sun.COM if (scf_value_get_integer(value, &v_int) != 0) 5751*7887SLiane.Praza@Sun.COM assert(0); 5752*7887SLiane.Praza@Sun.COM if (scf_tmpl_value_int_range_constraints(pt, &ir) != 0) { 5753*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_NOT_FOUND) 5754*7887SLiane.Praza@Sun.COM break; 5755*7887SLiane.Praza@Sun.COM if (scf_error() != SCF_ERROR_CONSTRAINT_VIOLATED) 5756*7887SLiane.Praza@Sun.COM (void) scf_set_error( 5757*7887SLiane.Praza@Sun.COM SCF_ERROR_TEMPLATE_INVALID); 5758*7887SLiane.Praza@Sun.COM return (-1); 5759*7887SLiane.Praza@Sun.COM } else { 5760*7887SLiane.Praza@Sun.COM if (_check_int_ranges(&ir, v_int) == 0) { 5761*7887SLiane.Praza@Sun.COM /* value is within ranges constraint */ 5762*7887SLiane.Praza@Sun.COM scf_int_ranges_destroy(&ir); 5763*7887SLiane.Praza@Sun.COM return (0); 5764*7887SLiane.Praza@Sun.COM } 5765*7887SLiane.Praza@Sun.COM scf_int_ranges_destroy(&ir); 5766*7887SLiane.Praza@Sun.COM } 5767*7887SLiane.Praza@Sun.COM /* 5768*7887SLiane.Praza@Sun.COM * If we get here, we have a possible constraint 5769*7887SLiane.Praza@Sun.COM * violation. 5770*7887SLiane.Praza@Sun.COM */ 5771*7887SLiane.Praza@Sun.COM err_flag |= 0x2; /* RANGE_VIOLATION, integer */ 5772*7887SLiane.Praza@Sun.COM break; 5773*7887SLiane.Praza@Sun.COM default: 5774*7887SLiane.Praza@Sun.COM break; 5775*7887SLiane.Praza@Sun.COM } 5776*7887SLiane.Praza@Sun.COM 5777*7887SLiane.Praza@Sun.COM vstr = malloc(sz); 5778*7887SLiane.Praza@Sun.COM if (vstr == NULL) { 5779*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 5780*7887SLiane.Praza@Sun.COM return (-1); 5781*7887SLiane.Praza@Sun.COM } 5782*7887SLiane.Praza@Sun.COM 5783*7887SLiane.Praza@Sun.COM /* 5784*7887SLiane.Praza@Sun.COM * If a set of names is provided, confirm value has one of 5785*7887SLiane.Praza@Sun.COM * those names. 5786*7887SLiane.Praza@Sun.COM */ 5787*7887SLiane.Praza@Sun.COM if (scf_tmpl_value_name_constraints(pt, &vals) != 0) { 5788*7887SLiane.Praza@Sun.COM free(vstr); 5789*7887SLiane.Praza@Sun.COM if (scf_error() != SCF_ERROR_NOT_FOUND) { 5790*7887SLiane.Praza@Sun.COM return (-1); 5791*7887SLiane.Praza@Sun.COM } 5792*7887SLiane.Praza@Sun.COM } else { 5793*7887SLiane.Praza@Sun.COM r = scf_value_get_as_string_typed(value, type, vstr, sz); 5794*7887SLiane.Praza@Sun.COM 5795*7887SLiane.Praza@Sun.COM /* 5796*7887SLiane.Praza@Sun.COM * All errors (INVALID_ARGUMENT, NOT_SET, TYPE_MISMATCH) 5797*7887SLiane.Praza@Sun.COM * should be impossible or already caught above. 5798*7887SLiane.Praza@Sun.COM */ 5799*7887SLiane.Praza@Sun.COM assert(r > 0); 5800*7887SLiane.Praza@Sun.COM 5801*7887SLiane.Praza@Sun.COM constraints = vals.values.v_astring; 5802*7887SLiane.Praza@Sun.COM for (n = 0; constraints[n] != NULL; ++n) { 5803*7887SLiane.Praza@Sun.COM if (strcmp(constraints[n], vstr) == 0) { 5804*7887SLiane.Praza@Sun.COM /* value is within constraint */ 5805*7887SLiane.Praza@Sun.COM scf_values_destroy(&vals); 5806*7887SLiane.Praza@Sun.COM free(vstr); 5807*7887SLiane.Praza@Sun.COM return (0); 5808*7887SLiane.Praza@Sun.COM } 5809*7887SLiane.Praza@Sun.COM } 5810*7887SLiane.Praza@Sun.COM /* if we get here, we have a constraint violation */ 5811*7887SLiane.Praza@Sun.COM err_flag |= 0x4; /* CONSTRAINT_VIOLATED */ 5812*7887SLiane.Praza@Sun.COM scf_values_destroy(&vals); 5813*7887SLiane.Praza@Sun.COM free(vstr); 5814*7887SLiane.Praza@Sun.COM } 5815*7887SLiane.Praza@Sun.COM if (err_flag != 0) 5816*7887SLiane.Praza@Sun.COM ret = 1; 5817*7887SLiane.Praza@Sun.COM /* register the errors found */ 5818*7887SLiane.Praza@Sun.COM if (ret == 1 && errs != NULL) { 5819*7887SLiane.Praza@Sun.COM if ((err_flag & 0x1) == 0x1) { 5820*7887SLiane.Praza@Sun.COM /* 5821*7887SLiane.Praza@Sun.COM * Help make the error more human-friendly. If 5822*7887SLiane.Praza@Sun.COM * pg and prop are provided, we know we're 5823*7887SLiane.Praza@Sun.COM * validating repository data. If they're not, 5824*7887SLiane.Praza@Sun.COM * we're validating a potentially hypothetical 5825*7887SLiane.Praza@Sun.COM * value. 5826*7887SLiane.Praza@Sun.COM */ 5827*7887SLiane.Praza@Sun.COM if (pg == NULL && prop == NULL) 5828*7887SLiane.Praza@Sun.COM terr_type = SCF_TERR_VALUE_OUT_OF_RANGE; 5829*7887SLiane.Praza@Sun.COM else 5830*7887SLiane.Praza@Sun.COM terr_type = SCF_TERR_RANGE_VIOLATION; 5831*7887SLiane.Praza@Sun.COM if (_add_tmpl_count_error(errs, terr_type, pg, pt, 5832*7887SLiane.Praza@Sun.COM prop, v_count, 0, 0) == -1) 5833*7887SLiane.Praza@Sun.COM ret = -1; 5834*7887SLiane.Praza@Sun.COM } 5835*7887SLiane.Praza@Sun.COM if ((err_flag & 0x2) == 0x2) { 5836*7887SLiane.Praza@Sun.COM if (pg == NULL && prop == NULL) 5837*7887SLiane.Praza@Sun.COM terr_type = SCF_TERR_VALUE_OUT_OF_RANGE; 5838*7887SLiane.Praza@Sun.COM else 5839*7887SLiane.Praza@Sun.COM terr_type = SCF_TERR_RANGE_VIOLATION; 5840*7887SLiane.Praza@Sun.COM if (_add_tmpl_int_error(errs, terr_type, pg, pt, prop, 5841*7887SLiane.Praza@Sun.COM v_int, 0, 0) == -1) 5842*7887SLiane.Praza@Sun.COM ret = -1; 5843*7887SLiane.Praza@Sun.COM } 5844*7887SLiane.Praza@Sun.COM if ((err_flag & 0x4) == 0x4) { 5845*7887SLiane.Praza@Sun.COM if (pg == NULL && prop == NULL) 5846*7887SLiane.Praza@Sun.COM terr_type = SCF_TERR_INVALID_VALUE; 5847*7887SLiane.Praza@Sun.COM else 5848*7887SLiane.Praza@Sun.COM terr_type = SCF_TERR_VALUE_CONSTRAINT_VIOLATED; 5849*7887SLiane.Praza@Sun.COM if (_add_tmpl_constraint_error(errs, terr_type, pg, 5850*7887SLiane.Praza@Sun.COM pt, prop, value) == -1) 5851*7887SLiane.Praza@Sun.COM ret = -1; 5852*7887SLiane.Praza@Sun.COM } 5853*7887SLiane.Praza@Sun.COM } 5854*7887SLiane.Praza@Sun.COM return (ret); 5855*7887SLiane.Praza@Sun.COM } 5856*7887SLiane.Praza@Sun.COM 5857*7887SLiane.Praza@Sun.COM /* 5858*7887SLiane.Praza@Sun.COM * Returns -1 on failure. Sets scf_error(): 5859*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5860*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5861*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5862*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5863*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5864*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 5865*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5866*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5867*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5868*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5869*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5870*7887SLiane.Praza@Sun.COM */ 5871*7887SLiane.Praza@Sun.COM int 5872*7887SLiane.Praza@Sun.COM scf_tmpl_value_in_constraint(const scf_prop_tmpl_t *pt, scf_value_t *value, 5873*7887SLiane.Praza@Sun.COM scf_tmpl_errors_t **errs) 5874*7887SLiane.Praza@Sun.COM { 5875*7887SLiane.Praza@Sun.COM scf_tmpl_errors_t *e = NULL; 5876*7887SLiane.Praza@Sun.COM 5877*7887SLiane.Praza@Sun.COM if (errs != NULL) { 5878*7887SLiane.Praza@Sun.COM char *fmri; 5879*7887SLiane.Praza@Sun.COM 5880*7887SLiane.Praza@Sun.COM if ((fmri = _scf_tmpl_get_fmri(pt->prt_t)) == NULL) 5881*7887SLiane.Praza@Sun.COM return (-1); 5882*7887SLiane.Praza@Sun.COM *errs = _scf_create_errors(fmri, 1); 5883*7887SLiane.Praza@Sun.COM free(fmri); 5884*7887SLiane.Praza@Sun.COM if (*errs == NULL) 5885*7887SLiane.Praza@Sun.COM return (-1); 5886*7887SLiane.Praza@Sun.COM e = *errs; 5887*7887SLiane.Praza@Sun.COM } 5888*7887SLiane.Praza@Sun.COM 5889*7887SLiane.Praza@Sun.COM return (_value_in_constraint(NULL, NULL, pt, value, e)); 5890*7887SLiane.Praza@Sun.COM } 5891*7887SLiane.Praza@Sun.COM 5892*7887SLiane.Praza@Sun.COM scf_tmpl_error_t * 5893*7887SLiane.Praza@Sun.COM scf_tmpl_next_error(scf_tmpl_errors_t *errs) 5894*7887SLiane.Praza@Sun.COM { 5895*7887SLiane.Praza@Sun.COM if (errs->tes_index < errs->tes_num_errs) { 5896*7887SLiane.Praza@Sun.COM assert(errs->tes_errs[errs->tes_index] != NULL); 5897*7887SLiane.Praza@Sun.COM return (errs->tes_errs[errs->tes_index++]); 5898*7887SLiane.Praza@Sun.COM } else { 5899*7887SLiane.Praza@Sun.COM return (NULL); 5900*7887SLiane.Praza@Sun.COM } 5901*7887SLiane.Praza@Sun.COM } 5902*7887SLiane.Praza@Sun.COM 5903*7887SLiane.Praza@Sun.COM void 5904*7887SLiane.Praza@Sun.COM scf_tmpl_reset_errors(scf_tmpl_errors_t *errs) 5905*7887SLiane.Praza@Sun.COM { 5906*7887SLiane.Praza@Sun.COM errs->tes_index = 0; 5907*7887SLiane.Praza@Sun.COM } 5908*7887SLiane.Praza@Sun.COM 5909*7887SLiane.Praza@Sun.COM int 5910*7887SLiane.Praza@Sun.COM scf_tmpl_strerror(scf_tmpl_error_t *err, char *s, size_t n, int flag) 5911*7887SLiane.Praza@Sun.COM { 5912*7887SLiane.Praza@Sun.COM const char *str; 5913*7887SLiane.Praza@Sun.COM int i; 5914*7887SLiane.Praza@Sun.COM int ret = -1; 5915*7887SLiane.Praza@Sun.COM int nsz = 0; /* err msg length */ 5916*7887SLiane.Praza@Sun.COM int sz = n; /* available buffer size */ 5917*7887SLiane.Praza@Sun.COM char *buf = s; /* where to append in buffer */ 5918*7887SLiane.Praza@Sun.COM char *s0 = (flag == SCF_TMPL_STRERROR_HUMAN) ? ":\n\t" : ": "; 5919*7887SLiane.Praza@Sun.COM char *s1 = (flag == SCF_TMPL_STRERROR_HUMAN) ? "\n\t" : "; "; 5920*7887SLiane.Praza@Sun.COM char *sep = s0; 5921*7887SLiane.Praza@Sun.COM const char *val; 5922*7887SLiane.Praza@Sun.COM 5923*7887SLiane.Praza@Sun.COM /* prefix */ 5924*7887SLiane.Praza@Sun.COM if (err->te_errs->tes_prefix != NULL) { 5925*7887SLiane.Praza@Sun.COM ret = snprintf(buf, sz, "%s", dgettext(TEXT_DOMAIN, 5926*7887SLiane.Praza@Sun.COM err->te_errs->tes_prefix)); 5927*7887SLiane.Praza@Sun.COM nsz += ret; 5928*7887SLiane.Praza@Sun.COM sz = (sz - ret) > 0 ? sz - ret : 0; 5929*7887SLiane.Praza@Sun.COM buf = (sz > 0) ? s + nsz : NULL; 5930*7887SLiane.Praza@Sun.COM } 5931*7887SLiane.Praza@Sun.COM /* error message */ 5932*7887SLiane.Praza@Sun.COM ret = snprintf(buf, sz, "%s", dgettext(TEXT_DOMAIN, 5933*7887SLiane.Praza@Sun.COM em_desc[err->te_type].em_msg)); 5934*7887SLiane.Praza@Sun.COM nsz += ret; 5935*7887SLiane.Praza@Sun.COM sz = (sz - ret) > 0 ? sz - ret : 0; 5936*7887SLiane.Praza@Sun.COM buf = (sz > 0) ? s + nsz : NULL; 5937*7887SLiane.Praza@Sun.COM 5938*7887SLiane.Praza@Sun.COM for (i = 0; _tmpl_error_items[i].get_desc != NULL; ++i) { 5939*7887SLiane.Praza@Sun.COM if ((str = _tmpl_error_items[i].get_desc(err)) == NULL) 5940*7887SLiane.Praza@Sun.COM /* no item to print */ 5941*7887SLiane.Praza@Sun.COM continue; 5942*7887SLiane.Praza@Sun.COM val = _tmpl_error_items[i].get_val(err); 5943*7887SLiane.Praza@Sun.COM ret = snprintf(buf, sz, "%s%s=\"%s\"", sep, str, 5944*7887SLiane.Praza@Sun.COM (val == NULL) ? "" : val); 5945*7887SLiane.Praza@Sun.COM nsz += ret; 5946*7887SLiane.Praza@Sun.COM sz = (sz - ret) > 0 ? sz - ret : 0; 5947*7887SLiane.Praza@Sun.COM buf = (sz > 0) ? s + nsz : NULL; 5948*7887SLiane.Praza@Sun.COM sep = s1; 5949*7887SLiane.Praza@Sun.COM } 5950*7887SLiane.Praza@Sun.COM return (nsz); 5951*7887SLiane.Praza@Sun.COM } 5952*7887SLiane.Praza@Sun.COM 5953*7887SLiane.Praza@Sun.COM /* 5954*7887SLiane.Praza@Sun.COM * return 0 on success, -1 on failure. 5955*7887SLiane.Praza@Sun.COM * set scf_error() to: 5956*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 5957*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 5958*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 5959*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 5960*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 5961*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 5962*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 5963*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 5964*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 5965*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 5966*7887SLiane.Praza@Sun.COM */ 5967*7887SLiane.Praza@Sun.COM static int 5968*7887SLiane.Praza@Sun.COM _validate_cardinality(scf_propertygroup_t *pg, scf_prop_tmpl_t *pt, 5969*7887SLiane.Praza@Sun.COM scf_property_t *prop, scf_tmpl_errors_t *errs) 5970*7887SLiane.Praza@Sun.COM { 5971*7887SLiane.Praza@Sun.COM uint64_t min, max; 5972*7887SLiane.Praza@Sun.COM scf_handle_t *h; 5973*7887SLiane.Praza@Sun.COM scf_iter_t *iter = NULL; 5974*7887SLiane.Praza@Sun.COM scf_value_t *val = NULL; 5975*7887SLiane.Praza@Sun.COM int count = 0; 5976*7887SLiane.Praza@Sun.COM int ret = -1; 5977*7887SLiane.Praza@Sun.COM int r; 5978*7887SLiane.Praza@Sun.COM 5979*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_cardinality(pt, &min, &max) != 0) { 5980*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_NOT_FOUND) 5981*7887SLiane.Praza@Sun.COM return (0); 5982*7887SLiane.Praza@Sun.COM else 5983*7887SLiane.Praza@Sun.COM return (-1); 5984*7887SLiane.Praza@Sun.COM } 5985*7887SLiane.Praza@Sun.COM 5986*7887SLiane.Praza@Sun.COM /* Any number of values permitted. Just return success. */ 5987*7887SLiane.Praza@Sun.COM if (min == 0 && max == UINT64_MAX) { 5988*7887SLiane.Praza@Sun.COM return (0); 5989*7887SLiane.Praza@Sun.COM } 5990*7887SLiane.Praza@Sun.COM 5991*7887SLiane.Praza@Sun.COM h = scf_property_handle(prop); 5992*7887SLiane.Praza@Sun.COM if (h == NULL) { 5993*7887SLiane.Praza@Sun.COM assert(scf_error() == SCF_ERROR_HANDLE_DESTROYED); 5994*7887SLiane.Praza@Sun.COM goto cleanup; 5995*7887SLiane.Praza@Sun.COM } 5996*7887SLiane.Praza@Sun.COM 5997*7887SLiane.Praza@Sun.COM iter = scf_iter_create(h); 5998*7887SLiane.Praza@Sun.COM val = scf_value_create(h); 5999*7887SLiane.Praza@Sun.COM if (iter == NULL || val == NULL) { 6000*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6001*7887SLiane.Praza@Sun.COM goto cleanup; 6002*7887SLiane.Praza@Sun.COM } else { 6003*7887SLiane.Praza@Sun.COM assert(0); 6004*7887SLiane.Praza@Sun.COM abort(); 6005*7887SLiane.Praza@Sun.COM } 6006*7887SLiane.Praza@Sun.COM } 6007*7887SLiane.Praza@Sun.COM 6008*7887SLiane.Praza@Sun.COM if (scf_iter_property_values(iter, prop) != 0) { 6009*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6010*7887SLiane.Praza@Sun.COM goto cleanup; 6011*7887SLiane.Praza@Sun.COM } else { 6012*7887SLiane.Praza@Sun.COM assert(0); 6013*7887SLiane.Praza@Sun.COM abort(); 6014*7887SLiane.Praza@Sun.COM } 6015*7887SLiane.Praza@Sun.COM } 6016*7887SLiane.Praza@Sun.COM 6017*7887SLiane.Praza@Sun.COM while ((r = scf_iter_next_value(iter, val)) == 1) 6018*7887SLiane.Praza@Sun.COM count++; 6019*7887SLiane.Praza@Sun.COM 6020*7887SLiane.Praza@Sun.COM if (r < 0) { 6021*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6022*7887SLiane.Praza@Sun.COM goto cleanup; 6023*7887SLiane.Praza@Sun.COM } else { 6024*7887SLiane.Praza@Sun.COM assert(0); 6025*7887SLiane.Praza@Sun.COM abort(); 6026*7887SLiane.Praza@Sun.COM } 6027*7887SLiane.Praza@Sun.COM } 6028*7887SLiane.Praza@Sun.COM 6029*7887SLiane.Praza@Sun.COM if (count < min || count > max) 6030*7887SLiane.Praza@Sun.COM if (_add_tmpl_count_error(errs, SCF_TERR_CARDINALITY_VIOLATION, 6031*7887SLiane.Praza@Sun.COM pg, pt, prop, (uint64_t)count, &min, &max) == -1) 6032*7887SLiane.Praza@Sun.COM goto cleanup; 6033*7887SLiane.Praza@Sun.COM 6034*7887SLiane.Praza@Sun.COM ret = 0; 6035*7887SLiane.Praza@Sun.COM 6036*7887SLiane.Praza@Sun.COM cleanup: 6037*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 6038*7887SLiane.Praza@Sun.COM scf_value_destroy(val); 6039*7887SLiane.Praza@Sun.COM return (ret); 6040*7887SLiane.Praza@Sun.COM } 6041*7887SLiane.Praza@Sun.COM 6042*7887SLiane.Praza@Sun.COM /* 6043*7887SLiane.Praza@Sun.COM * Returns -1 on error. Sets scf_error(): 6044*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 6045*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 6046*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 6047*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 6048*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 6049*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 6050*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 6051*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 6052*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 6053*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 6054*7887SLiane.Praza@Sun.COM */ 6055*7887SLiane.Praza@Sun.COM static int 6056*7887SLiane.Praza@Sun.COM _check_property(scf_prop_tmpl_t *pt, scf_propertygroup_t *pg, 6057*7887SLiane.Praza@Sun.COM scf_property_t *prop, scf_tmpl_errors_t *errs) 6058*7887SLiane.Praza@Sun.COM { 6059*7887SLiane.Praza@Sun.COM scf_type_t tmpl_type; 6060*7887SLiane.Praza@Sun.COM uint8_t required; 6061*7887SLiane.Praza@Sun.COM scf_handle_t *h; 6062*7887SLiane.Praza@Sun.COM scf_iter_t *iter = NULL; 6063*7887SLiane.Praza@Sun.COM scf_value_t *val = NULL; 6064*7887SLiane.Praza@Sun.COM int r; 6065*7887SLiane.Praza@Sun.COM int ret = -1; 6066*7887SLiane.Praza@Sun.COM 6067*7887SLiane.Praza@Sun.COM h = scf_pg_handle(pg); 6068*7887SLiane.Praza@Sun.COM if (h == NULL) { 6069*7887SLiane.Praza@Sun.COM assert(scf_error() == SCF_ERROR_HANDLE_DESTROYED); 6070*7887SLiane.Praza@Sun.COM return (-1); 6071*7887SLiane.Praza@Sun.COM } 6072*7887SLiane.Praza@Sun.COM 6073*7887SLiane.Praza@Sun.COM iter = scf_iter_create(h); 6074*7887SLiane.Praza@Sun.COM val = scf_value_create(h); 6075*7887SLiane.Praza@Sun.COM if (iter == NULL || val == NULL) { 6076*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6077*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 6078*7887SLiane.Praza@Sun.COM scf_value_destroy(val); 6079*7887SLiane.Praza@Sun.COM return (-1); 6080*7887SLiane.Praza@Sun.COM } else { 6081*7887SLiane.Praza@Sun.COM assert(0); 6082*7887SLiane.Praza@Sun.COM abort(); 6083*7887SLiane.Praza@Sun.COM } 6084*7887SLiane.Praza@Sun.COM } 6085*7887SLiane.Praza@Sun.COM 6086*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_required(pt, &required) != 0) 6087*7887SLiane.Praza@Sun.COM goto cleanup; 6088*7887SLiane.Praza@Sun.COM 6089*7887SLiane.Praza@Sun.COM /* Check type */ 6090*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_type(pt, &tmpl_type) == -1) { 6091*7887SLiane.Praza@Sun.COM if (scf_error() != SCF_ERROR_NOT_FOUND) { 6092*7887SLiane.Praza@Sun.COM goto cleanup; 6093*7887SLiane.Praza@Sun.COM } else if (required) { 6094*7887SLiane.Praza@Sun.COM /* If required, type must be specified. */ 6095*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 6096*7887SLiane.Praza@Sun.COM goto cleanup; 6097*7887SLiane.Praza@Sun.COM } 6098*7887SLiane.Praza@Sun.COM } else if (scf_property_is_type(prop, tmpl_type) != 0) { 6099*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6100*7887SLiane.Praza@Sun.COM goto cleanup; 6101*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6102*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 6103*7887SLiane.Praza@Sun.COM if (_add_tmpl_wrong_prop_type_error(errs, pg, pt, 6104*7887SLiane.Praza@Sun.COM prop) == -1) 6105*7887SLiane.Praza@Sun.COM goto cleanup; 6106*7887SLiane.Praza@Sun.COM break; 6107*7887SLiane.Praza@Sun.COM 6108*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6109*7887SLiane.Praza@Sun.COM /* 6110*7887SLiane.Praza@Sun.COM * tmpl_prop_type shouldn't have handed back 6111*7887SLiane.Praza@Sun.COM * an invalid property type. 6112*7887SLiane.Praza@Sun.COM */ 6113*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 6114*7887SLiane.Praza@Sun.COM default: 6115*7887SLiane.Praza@Sun.COM assert(0); 6116*7887SLiane.Praza@Sun.COM abort(); 6117*7887SLiane.Praza@Sun.COM } 6118*7887SLiane.Praza@Sun.COM } 6119*7887SLiane.Praza@Sun.COM 6120*7887SLiane.Praza@Sun.COM 6121*7887SLiane.Praza@Sun.COM /* Cardinality */ 6122*7887SLiane.Praza@Sun.COM if (_validate_cardinality(pg, pt, prop, errs) == -1) 6123*7887SLiane.Praza@Sun.COM goto cleanup; 6124*7887SLiane.Praza@Sun.COM 6125*7887SLiane.Praza@Sun.COM /* Value constraints */ 6126*7887SLiane.Praza@Sun.COM /* 6127*7887SLiane.Praza@Sun.COM * Iterate through each value, and confirm it is defined as 6128*7887SLiane.Praza@Sun.COM * constrained. 6129*7887SLiane.Praza@Sun.COM */ 6130*7887SLiane.Praza@Sun.COM if (scf_iter_property_values(iter, prop) != 0) { 6131*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET && 6132*7887SLiane.Praza@Sun.COM scf_error() != SCF_ERROR_HANDLE_MISMATCH); 6133*7887SLiane.Praza@Sun.COM goto cleanup; 6134*7887SLiane.Praza@Sun.COM } 6135*7887SLiane.Praza@Sun.COM 6136*7887SLiane.Praza@Sun.COM while ((r = scf_iter_next_value(iter, val)) == 1) { 6137*7887SLiane.Praza@Sun.COM if (_value_in_constraint(pg, prop, pt, val, errs) == -1) { 6138*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6139*7887SLiane.Praza@Sun.COM goto cleanup; 6140*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6141*7887SLiane.Praza@Sun.COM case SCF_ERROR_TEMPLATE_INVALID: 6142*7887SLiane.Praza@Sun.COM goto cleanup; 6143*7887SLiane.Praza@Sun.COM 6144*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6145*7887SLiane.Praza@Sun.COM default: 6146*7887SLiane.Praza@Sun.COM assert(0); 6147*7887SLiane.Praza@Sun.COM abort(); 6148*7887SLiane.Praza@Sun.COM } 6149*7887SLiane.Praza@Sun.COM } 6150*7887SLiane.Praza@Sun.COM } 6151*7887SLiane.Praza@Sun.COM 6152*7887SLiane.Praza@Sun.COM if (r < 0) { 6153*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6154*7887SLiane.Praza@Sun.COM goto cleanup; 6155*7887SLiane.Praza@Sun.COM } else { 6156*7887SLiane.Praza@Sun.COM assert(0); 6157*7887SLiane.Praza@Sun.COM abort(); 6158*7887SLiane.Praza@Sun.COM } 6159*7887SLiane.Praza@Sun.COM } 6160*7887SLiane.Praza@Sun.COM 6161*7887SLiane.Praza@Sun.COM ret = 0; 6162*7887SLiane.Praza@Sun.COM 6163*7887SLiane.Praza@Sun.COM cleanup: 6164*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 6165*7887SLiane.Praza@Sun.COM scf_value_destroy(val); 6166*7887SLiane.Praza@Sun.COM return (ret); 6167*7887SLiane.Praza@Sun.COM } 6168*7887SLiane.Praza@Sun.COM 6169*7887SLiane.Praza@Sun.COM /* 6170*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 6171*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 6172*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 6173*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 6174*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 6175*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 6176*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 6177*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 6178*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 6179*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 6180*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 6181*7887SLiane.Praza@Sun.COM */ 6182*7887SLiane.Praza@Sun.COM static int 6183*7887SLiane.Praza@Sun.COM _check_pg(scf_pg_tmpl_t *t, scf_propertygroup_t *pg, char *pg_name, 6184*7887SLiane.Praza@Sun.COM char *type, scf_tmpl_errors_t *errs) 6185*7887SLiane.Praza@Sun.COM { 6186*7887SLiane.Praza@Sun.COM scf_prop_tmpl_t *pt = NULL; 6187*7887SLiane.Praza@Sun.COM char *pg_type = NULL; 6188*7887SLiane.Praza@Sun.COM scf_iter_t *iter = NULL; 6189*7887SLiane.Praza@Sun.COM uint8_t pg_required; 6190*7887SLiane.Praza@Sun.COM scf_property_t *prop = NULL; 6191*7887SLiane.Praza@Sun.COM scf_handle_t *h; 6192*7887SLiane.Praza@Sun.COM int r; 6193*7887SLiane.Praza@Sun.COM char *prop_name = NULL; 6194*7887SLiane.Praza@Sun.COM ssize_t nsize = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 6195*7887SLiane.Praza@Sun.COM int ret = -1; 6196*7887SLiane.Praza@Sun.COM 6197*7887SLiane.Praza@Sun.COM assert(pg_name != NULL); 6198*7887SLiane.Praza@Sun.COM assert(t != NULL); 6199*7887SLiane.Praza@Sun.COM assert(pg != NULL); 6200*7887SLiane.Praza@Sun.COM assert(type != NULL); 6201*7887SLiane.Praza@Sun.COM assert(nsize != 0); 6202*7887SLiane.Praza@Sun.COM 6203*7887SLiane.Praza@Sun.COM if ((h = scf_pg_handle(pg)) == NULL) { 6204*7887SLiane.Praza@Sun.COM assert(scf_error() == SCF_ERROR_HANDLE_DESTROYED); 6205*7887SLiane.Praza@Sun.COM return (-1); 6206*7887SLiane.Praza@Sun.COM } 6207*7887SLiane.Praza@Sun.COM if ((pt = scf_tmpl_prop_create(h)) == NULL) { 6208*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 6209*7887SLiane.Praza@Sun.COM return (-1); 6210*7887SLiane.Praza@Sun.COM } 6211*7887SLiane.Praza@Sun.COM 6212*7887SLiane.Praza@Sun.COM if ((prop = scf_property_create(h)) == NULL) { 6213*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 6214*7887SLiane.Praza@Sun.COM goto cleanup; 6215*7887SLiane.Praza@Sun.COM } 6216*7887SLiane.Praza@Sun.COM 6217*7887SLiane.Praza@Sun.COM if ((iter = scf_iter_create(h)) == NULL) { 6218*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_INVALID_ARGUMENT); 6219*7887SLiane.Praza@Sun.COM goto cleanup; 6220*7887SLiane.Praza@Sun.COM } 6221*7887SLiane.Praza@Sun.COM if ((prop_name = malloc(nsize)) == NULL) { 6222*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 6223*7887SLiane.Praza@Sun.COM goto cleanup; 6224*7887SLiane.Praza@Sun.COM } 6225*7887SLiane.Praza@Sun.COM 6226*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_required(t, &pg_required) != 0) 6227*7887SLiane.Praza@Sun.COM goto cleanup; 6228*7887SLiane.Praza@Sun.COM 6229*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(t, &pg_type) == -1) { 6230*7887SLiane.Praza@Sun.COM goto cleanup; 6231*7887SLiane.Praza@Sun.COM } else if (pg_required != 0 && 6232*7887SLiane.Praza@Sun.COM strcmp(SCF_TMPL_WILDCARD, pg_type) == 0) { 6233*7887SLiane.Praza@Sun.COM /* Type must be specified for required pgs. */ 6234*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 6235*7887SLiane.Praza@Sun.COM goto cleanup; 6236*7887SLiane.Praza@Sun.COM } 6237*7887SLiane.Praza@Sun.COM 6238*7887SLiane.Praza@Sun.COM if (pg_type != NULL) { 6239*7887SLiane.Praza@Sun.COM if (strcmp(pg_type, type) != 0 && 6240*7887SLiane.Praza@Sun.COM strcmp(pg_type, SCF_TMPL_WILDCARD) != 0) { 6241*7887SLiane.Praza@Sun.COM if (_add_tmpl_wrong_pg_type_error(errs, t, pg) == -1) 6242*7887SLiane.Praza@Sun.COM goto cleanup; 6243*7887SLiane.Praza@Sun.COM } 6244*7887SLiane.Praza@Sun.COM } 6245*7887SLiane.Praza@Sun.COM 6246*7887SLiane.Praza@Sun.COM 6247*7887SLiane.Praza@Sun.COM /* Iterate through properties in the repository and check them. */ 6248*7887SLiane.Praza@Sun.COM if (scf_iter_pg_properties(iter, pg) != 0) { 6249*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6250*7887SLiane.Praza@Sun.COM goto cleanup; 6251*7887SLiane.Praza@Sun.COM } else { 6252*7887SLiane.Praza@Sun.COM assert(0); 6253*7887SLiane.Praza@Sun.COM abort(); 6254*7887SLiane.Praza@Sun.COM } 6255*7887SLiane.Praza@Sun.COM } 6256*7887SLiane.Praza@Sun.COM 6257*7887SLiane.Praza@Sun.COM while ((r = scf_iter_next_property(iter, prop)) == 1) { 6258*7887SLiane.Praza@Sun.COM if (scf_property_get_name(prop, prop_name, nsize) == -1) { 6259*7887SLiane.Praza@Sun.COM assert(scf_error() != SCF_ERROR_NOT_SET); 6260*7887SLiane.Praza@Sun.COM goto cleanup; 6261*7887SLiane.Praza@Sun.COM } 6262*7887SLiane.Praza@Sun.COM if (scf_tmpl_get_by_prop(t, prop_name, pt, 0) != 0) { 6263*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6264*7887SLiane.Praza@Sun.COM goto cleanup; 6265*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6266*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 6267*7887SLiane.Praza@Sun.COM /* No template. Continue. */ 6268*7887SLiane.Praza@Sun.COM continue; 6269*7887SLiane.Praza@Sun.COM 6270*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6271*7887SLiane.Praza@Sun.COM default: 6272*7887SLiane.Praza@Sun.COM assert(0); 6273*7887SLiane.Praza@Sun.COM abort(); 6274*7887SLiane.Praza@Sun.COM } 6275*7887SLiane.Praza@Sun.COM } 6276*7887SLiane.Praza@Sun.COM 6277*7887SLiane.Praza@Sun.COM if (_check_property(pt, pg, prop, errs) != 0) 6278*7887SLiane.Praza@Sun.COM goto cleanup; 6279*7887SLiane.Praza@Sun.COM } 6280*7887SLiane.Praza@Sun.COM 6281*7887SLiane.Praza@Sun.COM if (r < 0) { 6282*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6283*7887SLiane.Praza@Sun.COM goto cleanup; 6284*7887SLiane.Praza@Sun.COM } else { 6285*7887SLiane.Praza@Sun.COM assert(0); 6286*7887SLiane.Praza@Sun.COM abort(); 6287*7887SLiane.Praza@Sun.COM } 6288*7887SLiane.Praza@Sun.COM } 6289*7887SLiane.Praza@Sun.COM 6290*7887SLiane.Praza@Sun.COM scf_tmpl_prop_reset(pt); 6291*7887SLiane.Praza@Sun.COM free(prop_name); 6292*7887SLiane.Praza@Sun.COM prop_name = NULL; 6293*7887SLiane.Praza@Sun.COM /* 6294*7887SLiane.Praza@Sun.COM * Confirm required properties are present. 6295*7887SLiane.Praza@Sun.COM */ 6296*7887SLiane.Praza@Sun.COM while ((r = scf_tmpl_iter_props(t, pt, 6297*7887SLiane.Praza@Sun.COM SCF_PROP_TMPL_FLAG_REQUIRED)) == 0) { 6298*7887SLiane.Praza@Sun.COM scf_type_t prop_type; 6299*7887SLiane.Praza@Sun.COM 6300*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_name(pt, &prop_name) == -1) 6301*7887SLiane.Praza@Sun.COM goto cleanup; 6302*7887SLiane.Praza@Sun.COM 6303*7887SLiane.Praza@Sun.COM /* required properties cannot have type wildcarded */ 6304*7887SLiane.Praza@Sun.COM if (scf_tmpl_prop_type(pt, &prop_type) == -1) { 6305*7887SLiane.Praza@Sun.COM if (scf_error() == SCF_ERROR_NOT_FOUND) 6306*7887SLiane.Praza@Sun.COM (void) scf_set_error( 6307*7887SLiane.Praza@Sun.COM SCF_ERROR_TEMPLATE_INVALID); 6308*7887SLiane.Praza@Sun.COM goto cleanup; 6309*7887SLiane.Praza@Sun.COM } 6310*7887SLiane.Praza@Sun.COM 6311*7887SLiane.Praza@Sun.COM if (scf_pg_get_property(pg, prop_name, prop) != 0) { 6312*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6313*7887SLiane.Praza@Sun.COM goto cleanup; 6314*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6315*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 6316*7887SLiane.Praza@Sun.COM if (_add_tmpl_missing_prop_error(errs, t, pg, 6317*7887SLiane.Praza@Sun.COM pt) == -1) 6318*7887SLiane.Praza@Sun.COM goto cleanup; 6319*7887SLiane.Praza@Sun.COM break; 6320*7887SLiane.Praza@Sun.COM 6321*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6322*7887SLiane.Praza@Sun.COM (void) scf_set_error( 6323*7887SLiane.Praza@Sun.COM SCF_ERROR_TEMPLATE_INVALID); 6324*7887SLiane.Praza@Sun.COM goto cleanup; 6325*7887SLiane.Praza@Sun.COM 6326*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 6327*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 6328*7887SLiane.Praza@Sun.COM default: 6329*7887SLiane.Praza@Sun.COM assert(0); 6330*7887SLiane.Praza@Sun.COM abort(); 6331*7887SLiane.Praza@Sun.COM } 6332*7887SLiane.Praza@Sun.COM } 6333*7887SLiane.Praza@Sun.COM free(prop_name); 6334*7887SLiane.Praza@Sun.COM prop_name = NULL; 6335*7887SLiane.Praza@Sun.COM } 6336*7887SLiane.Praza@Sun.COM if (r < 0) { 6337*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6338*7887SLiane.Praza@Sun.COM goto cleanup; 6339*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6340*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 6341*7887SLiane.Praza@Sun.COM break; 6342*7887SLiane.Praza@Sun.COM 6343*7887SLiane.Praza@Sun.COM case SCF_ERROR_TEMPLATE_INVALID: 6344*7887SLiane.Praza@Sun.COM goto cleanup; 6345*7887SLiane.Praza@Sun.COM 6346*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6347*7887SLiane.Praza@Sun.COM default: 6348*7887SLiane.Praza@Sun.COM assert(0); 6349*7887SLiane.Praza@Sun.COM abort(); 6350*7887SLiane.Praza@Sun.COM } 6351*7887SLiane.Praza@Sun.COM } 6352*7887SLiane.Praza@Sun.COM 6353*7887SLiane.Praza@Sun.COM ret = 0; 6354*7887SLiane.Praza@Sun.COM cleanup: 6355*7887SLiane.Praza@Sun.COM scf_tmpl_prop_destroy(pt); 6356*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 6357*7887SLiane.Praza@Sun.COM scf_property_destroy(prop); 6358*7887SLiane.Praza@Sun.COM free(prop_name); 6359*7887SLiane.Praza@Sun.COM free(pg_type); 6360*7887SLiane.Praza@Sun.COM return (ret); 6361*7887SLiane.Praza@Sun.COM } 6362*7887SLiane.Praza@Sun.COM 6363*7887SLiane.Praza@Sun.COM /* 6364*7887SLiane.Praza@Sun.COM * Checks if instance fmri redefines any pgs defined in restarter or global 6365*7887SLiane.Praza@Sun.COM * Return -1 on failure, sets scf_error() to: 6366*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 6367*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 6368*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 6369*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 6370*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 6371*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 6372*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 6373*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 6374*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 6375*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 6376*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 6377*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 6378*7887SLiane.Praza@Sun.COM */ 6379*7887SLiane.Praza@Sun.COM static int 6380*7887SLiane.Praza@Sun.COM _scf_tmpl_check_pg_redef(scf_handle_t *h, const char *fmri, 6381*7887SLiane.Praza@Sun.COM const char *snapname, scf_tmpl_errors_t *errs) 6382*7887SLiane.Praza@Sun.COM { 6383*7887SLiane.Praza@Sun.COM scf_pg_tmpl_t *t = NULL; 6384*7887SLiane.Praza@Sun.COM scf_pg_tmpl_t *r = NULL; 6385*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 6386*7887SLiane.Praza@Sun.COM char *pg_name_r = NULL; 6387*7887SLiane.Praza@Sun.COM char *pg_type = NULL; 6388*7887SLiane.Praza@Sun.COM char *pg_type_r = NULL; 6389*7887SLiane.Praza@Sun.COM char *target = NULL; 6390*7887SLiane.Praza@Sun.COM int ret_val = -1; 6391*7887SLiane.Praza@Sun.COM int ret; 6392*7887SLiane.Praza@Sun.COM 6393*7887SLiane.Praza@Sun.COM t = scf_tmpl_pg_create(h); 6394*7887SLiane.Praza@Sun.COM r = scf_tmpl_pg_create(h); 6395*7887SLiane.Praza@Sun.COM if (t == NULL || r == NULL) 6396*7887SLiane.Praza@Sun.COM goto cleanup; 6397*7887SLiane.Praza@Sun.COM 6398*7887SLiane.Praza@Sun.COM while ((ret = scf_tmpl_iter_pgs(t, fmri, snapname, NULL, 6399*7887SLiane.Praza@Sun.COM SCF_PG_TMPL_FLAG_EXACT)) == 1) { 6400*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(t, &pg_name) == -1) { 6401*7887SLiane.Praza@Sun.COM goto cleanup; 6402*7887SLiane.Praza@Sun.COM } 6403*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(t, &pg_type) == -1) { 6404*7887SLiane.Praza@Sun.COM goto cleanup; 6405*7887SLiane.Praza@Sun.COM } 6406*7887SLiane.Praza@Sun.COM /* look for a redefinition of a global/restarter pg_pattern */ 6407*7887SLiane.Praza@Sun.COM while ((ret = scf_tmpl_iter_pgs(r, fmri, snapname, pg_type, 6408*7887SLiane.Praza@Sun.COM 0)) == 1) { 6409*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(r, &pg_name_r) == -1) { 6410*7887SLiane.Praza@Sun.COM goto cleanup; 6411*7887SLiane.Praza@Sun.COM } else if (strcmp(pg_name_r, SCF_TMPL_WILDCARD) != 0 && 6412*7887SLiane.Praza@Sun.COM strcmp(pg_name, SCF_TMPL_WILDCARD) != 0 && 6413*7887SLiane.Praza@Sun.COM strcmp(pg_name, pg_name_r) != 0) { 6414*7887SLiane.Praza@Sun.COM /* not a match */ 6415*7887SLiane.Praza@Sun.COM free(pg_name_r); 6416*7887SLiane.Praza@Sun.COM pg_name_r = NULL; 6417*7887SLiane.Praza@Sun.COM continue; 6418*7887SLiane.Praza@Sun.COM } 6419*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(r, &pg_type_r) == -1) { 6420*7887SLiane.Praza@Sun.COM goto cleanup; 6421*7887SLiane.Praza@Sun.COM } else if (strcmp(pg_type_r, SCF_TMPL_WILDCARD) != 0 && 6422*7887SLiane.Praza@Sun.COM strcmp(pg_type, SCF_TMPL_WILDCARD) != 0 && 6423*7887SLiane.Praza@Sun.COM strcmp(pg_type, pg_type_r) != 0) { 6424*7887SLiane.Praza@Sun.COM /* not a match */ 6425*7887SLiane.Praza@Sun.COM free(pg_name_r); 6426*7887SLiane.Praza@Sun.COM pg_name_r = NULL; 6427*7887SLiane.Praza@Sun.COM free(pg_type_r); 6428*7887SLiane.Praza@Sun.COM pg_type_r = NULL; 6429*7887SLiane.Praza@Sun.COM continue; 6430*7887SLiane.Praza@Sun.COM } 6431*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_target(r, &target) == -1) { 6432*7887SLiane.Praza@Sun.COM target = NULL; 6433*7887SLiane.Praza@Sun.COM goto cleanup; 6434*7887SLiane.Praza@Sun.COM } 6435*7887SLiane.Praza@Sun.COM if (strcmp(target, SCF_TM_TARGET_ALL) == 0 || 6436*7887SLiane.Praza@Sun.COM strcmp(target, SCF_TM_TARGET_DELEGATE) == 0) { 6437*7887SLiane.Praza@Sun.COM /* found a pg_pattern redefinition */ 6438*7887SLiane.Praza@Sun.COM if (_add_tmpl_pg_redefine_error(errs, t, 6439*7887SLiane.Praza@Sun.COM r) == -1) 6440*7887SLiane.Praza@Sun.COM goto cleanup; 6441*7887SLiane.Praza@Sun.COM free(pg_name_r); 6442*7887SLiane.Praza@Sun.COM pg_name_r = NULL; 6443*7887SLiane.Praza@Sun.COM free(target); 6444*7887SLiane.Praza@Sun.COM target = NULL; 6445*7887SLiane.Praza@Sun.COM break; 6446*7887SLiane.Praza@Sun.COM } 6447*7887SLiane.Praza@Sun.COM free(pg_name_r); 6448*7887SLiane.Praza@Sun.COM pg_name_r = NULL; 6449*7887SLiane.Praza@Sun.COM free(target); 6450*7887SLiane.Praza@Sun.COM target = NULL; 6451*7887SLiane.Praza@Sun.COM } 6452*7887SLiane.Praza@Sun.COM if (ret == -1) 6453*7887SLiane.Praza@Sun.COM goto cleanup; 6454*7887SLiane.Praza@Sun.COM scf_tmpl_pg_reset(r); 6455*7887SLiane.Praza@Sun.COM 6456*7887SLiane.Praza@Sun.COM free(pg_name); 6457*7887SLiane.Praza@Sun.COM free(pg_type); 6458*7887SLiane.Praza@Sun.COM pg_name = NULL; 6459*7887SLiane.Praza@Sun.COM pg_type = NULL; 6460*7887SLiane.Praza@Sun.COM } 6461*7887SLiane.Praza@Sun.COM if (ret == -1) 6462*7887SLiane.Praza@Sun.COM goto cleanup; 6463*7887SLiane.Praza@Sun.COM 6464*7887SLiane.Praza@Sun.COM ret_val = 0; 6465*7887SLiane.Praza@Sun.COM 6466*7887SLiane.Praza@Sun.COM cleanup: 6467*7887SLiane.Praza@Sun.COM scf_tmpl_pg_destroy(t); 6468*7887SLiane.Praza@Sun.COM scf_tmpl_pg_destroy(r); 6469*7887SLiane.Praza@Sun.COM free(pg_name); 6470*7887SLiane.Praza@Sun.COM free(pg_type); 6471*7887SLiane.Praza@Sun.COM free(pg_name_r); 6472*7887SLiane.Praza@Sun.COM free(pg_type_r); 6473*7887SLiane.Praza@Sun.COM free(target); 6474*7887SLiane.Praza@Sun.COM 6475*7887SLiane.Praza@Sun.COM if (ret_val == -1) { 6476*7887SLiane.Praza@Sun.COM if (!ismember(scf_error(), errors_server)) { 6477*7887SLiane.Praza@Sun.COM switch (scf_error()) { 6478*7887SLiane.Praza@Sun.COM case SCF_ERROR_TYPE_MISMATCH: 6479*7887SLiane.Praza@Sun.COM (void) scf_set_error( 6480*7887SLiane.Praza@Sun.COM SCF_ERROR_TEMPLATE_INVALID); 6481*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 6482*7887SLiane.Praza@Sun.COM 6483*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 6484*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6485*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 6486*7887SLiane.Praza@Sun.COM case SCF_ERROR_TEMPLATE_INVALID: 6487*7887SLiane.Praza@Sun.COM break; 6488*7887SLiane.Praza@Sun.COM 6489*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 6490*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 6491*7887SLiane.Praza@Sun.COM default: 6492*7887SLiane.Praza@Sun.COM assert(0); 6493*7887SLiane.Praza@Sun.COM abort(); 6494*7887SLiane.Praza@Sun.COM } 6495*7887SLiane.Praza@Sun.COM } 6496*7887SLiane.Praza@Sun.COM } 6497*7887SLiane.Praza@Sun.COM return (ret_val); 6498*7887SLiane.Praza@Sun.COM } 6499*7887SLiane.Praza@Sun.COM 6500*7887SLiane.Praza@Sun.COM /* 6501*7887SLiane.Praza@Sun.COM * Returns -1 on failure, sets scf_error() to: 6502*7887SLiane.Praza@Sun.COM * SCF_ERROR_BACKEND_ACCESS 6503*7887SLiane.Praza@Sun.COM * SCF_ERROR_CONNECTION_BROKEN 6504*7887SLiane.Praza@Sun.COM * SCF_ERROR_DELETED 6505*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED 6506*7887SLiane.Praza@Sun.COM * SCF_ERROR_INTERNAL 6507*7887SLiane.Praza@Sun.COM * SCF_ERROR_INVALID_ARGUMENT 6508*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_MEMORY 6509*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES 6510*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_BOUND 6511*7887SLiane.Praza@Sun.COM * SCF_ERROR_NOT_FOUND 6512*7887SLiane.Praza@Sun.COM * SCF_ERROR_PERMISSION_DENIED 6513*7887SLiane.Praza@Sun.COM * SCF_ERROR_TEMPLATE_INVALID 6514*7887SLiane.Praza@Sun.COM */ 6515*7887SLiane.Praza@Sun.COM int 6516*7887SLiane.Praza@Sun.COM scf_tmpl_validate_fmri(scf_handle_t *h, const char *fmri, const char *snapshot, 6517*7887SLiane.Praza@Sun.COM scf_tmpl_errors_t **errs, int flags) 6518*7887SLiane.Praza@Sun.COM { 6519*7887SLiane.Praza@Sun.COM scf_pg_tmpl_t *t = NULL; 6520*7887SLiane.Praza@Sun.COM scf_iter_t *iter = NULL; 6521*7887SLiane.Praza@Sun.COM scf_propertygroup_t *pg = NULL; 6522*7887SLiane.Praza@Sun.COM scf_instance_t *inst = NULL; 6523*7887SLiane.Praza@Sun.COM scf_snapshot_t *snap = NULL; 6524*7887SLiane.Praza@Sun.COM char *type = NULL; 6525*7887SLiane.Praza@Sun.COM char *pg_name = NULL; 6526*7887SLiane.Praza@Sun.COM ssize_t rsize = scf_limit(SCF_LIMIT_MAX_PG_TYPE_LENGTH) + 1; 6527*7887SLiane.Praza@Sun.COM ssize_t nsize = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; 6528*7887SLiane.Praza@Sun.COM int ret = -1; 6529*7887SLiane.Praza@Sun.COM int r; 6530*7887SLiane.Praza@Sun.COM 6531*7887SLiane.Praza@Sun.COM assert(errs != NULL); 6532*7887SLiane.Praza@Sun.COM 6533*7887SLiane.Praza@Sun.COM if ((*errs = _scf_create_errors(fmri, 1)) == NULL) 6534*7887SLiane.Praza@Sun.COM return (-1); 6535*7887SLiane.Praza@Sun.COM 6536*7887SLiane.Praza@Sun.COM if ((pg = scf_pg_create(h)) == NULL || 6537*7887SLiane.Praza@Sun.COM (iter = scf_iter_create(h)) == NULL || 6538*7887SLiane.Praza@Sun.COM (inst = scf_instance_create(h)) == NULL || 6539*7887SLiane.Praza@Sun.COM (t = scf_tmpl_pg_create(h)) == NULL) { 6540*7887SLiane.Praza@Sun.COM /* 6541*7887SLiane.Praza@Sun.COM * Sets SCF_ERROR_INVALID_ARGUMENT, SCF_ERROR_NO_MEMORY, 6542*7887SLiane.Praza@Sun.COM * SCF_ERROR_NO_RESOURCES, SCF_ERROR_INTERNAL or 6543*7887SLiane.Praza@Sun.COM * SCF_ERROR_HANDLE_DESTROYED. 6544*7887SLiane.Praza@Sun.COM */ 6545*7887SLiane.Praza@Sun.COM goto cleanup; 6546*7887SLiane.Praza@Sun.COM } 6547*7887SLiane.Praza@Sun.COM 6548*7887SLiane.Praza@Sun.COM if ((type = malloc(rsize)) == NULL || 6549*7887SLiane.Praza@Sun.COM (pg_name = malloc(nsize)) == NULL) { 6550*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NO_MEMORY); 6551*7887SLiane.Praza@Sun.COM goto cleanup; 6552*7887SLiane.Praza@Sun.COM } 6553*7887SLiane.Praza@Sun.COM 6554*7887SLiane.Praza@Sun.COM if (scf_handle_decode_fmri(h, fmri, NULL, NULL, inst, NULL, NULL, 6555*7887SLiane.Praza@Sun.COM SCF_DECODE_FMRI_EXACT|SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { 6556*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6557*7887SLiane.Praza@Sun.COM goto cleanup; 6558*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6559*7887SLiane.Praza@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED: 6560*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 6561*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 6562*7887SLiane.Praza@Sun.COM 6563*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6564*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 6565*7887SLiane.Praza@Sun.COM goto cleanup; 6566*7887SLiane.Praza@Sun.COM 6567*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 6568*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 6569*7887SLiane.Praza@Sun.COM default: 6570*7887SLiane.Praza@Sun.COM assert(0); 6571*7887SLiane.Praza@Sun.COM abort(); 6572*7887SLiane.Praza@Sun.COM } 6573*7887SLiane.Praza@Sun.COM } 6574*7887SLiane.Praza@Sun.COM 6575*7887SLiane.Praza@Sun.COM if (snapshot == NULL || strcmp(snapshot, "running") == 0 || 6576*7887SLiane.Praza@Sun.COM (flags & SCF_TMPL_VALIDATE_FLAG_CURRENT)) { 6577*7887SLiane.Praza@Sun.COM if (_get_snapshot(inst, NULL, &snap) == -1) 6578*7887SLiane.Praza@Sun.COM goto cleanup; 6579*7887SLiane.Praza@Sun.COM } else { 6580*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NONE); 6581*7887SLiane.Praza@Sun.COM if (_get_snapshot(inst, snapshot, &snap) == -1) { 6582*7887SLiane.Praza@Sun.COM goto cleanup; 6583*7887SLiane.Praza@Sun.COM } else if (scf_error() == SCF_ERROR_NOT_FOUND) { 6584*7887SLiane.Praza@Sun.COM goto cleanup; 6585*7887SLiane.Praza@Sun.COM } 6586*7887SLiane.Praza@Sun.COM } 6587*7887SLiane.Praza@Sun.COM if (_scf_tmpl_check_pg_redef(h, fmri, snapshot, *errs) != 0) { 6588*7887SLiane.Praza@Sun.COM goto cleanup; 6589*7887SLiane.Praza@Sun.COM } 6590*7887SLiane.Praza@Sun.COM 6591*7887SLiane.Praza@Sun.COM /* 6592*7887SLiane.Praza@Sun.COM * Check that property groups on this instance conform to the template. 6593*7887SLiane.Praza@Sun.COM */ 6594*7887SLiane.Praza@Sun.COM if (scf_iter_instance_pgs_composed(iter, inst, snap) != 0) { 6595*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6596*7887SLiane.Praza@Sun.COM goto cleanup; 6597*7887SLiane.Praza@Sun.COM } else { 6598*7887SLiane.Praza@Sun.COM assert(0); 6599*7887SLiane.Praza@Sun.COM abort(); 6600*7887SLiane.Praza@Sun.COM } 6601*7887SLiane.Praza@Sun.COM } 6602*7887SLiane.Praza@Sun.COM 6603*7887SLiane.Praza@Sun.COM while ((r = scf_iter_next_pg(iter, pg)) == 1) { 6604*7887SLiane.Praza@Sun.COM if (scf_pg_get_name(pg, pg_name, nsize) == -1) { 6605*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6606*7887SLiane.Praza@Sun.COM goto cleanup; 6607*7887SLiane.Praza@Sun.COM } else { 6608*7887SLiane.Praza@Sun.COM assert(0); 6609*7887SLiane.Praza@Sun.COM abort(); 6610*7887SLiane.Praza@Sun.COM } 6611*7887SLiane.Praza@Sun.COM } 6612*7887SLiane.Praza@Sun.COM 6613*7887SLiane.Praza@Sun.COM if (scf_pg_get_type(pg, type, rsize) == -1) { 6614*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6615*7887SLiane.Praza@Sun.COM goto cleanup; 6616*7887SLiane.Praza@Sun.COM } else { 6617*7887SLiane.Praza@Sun.COM assert(0); 6618*7887SLiane.Praza@Sun.COM abort(); 6619*7887SLiane.Praza@Sun.COM } 6620*7887SLiane.Praza@Sun.COM } 6621*7887SLiane.Praza@Sun.COM 6622*7887SLiane.Praza@Sun.COM if (scf_tmpl_get_by_pg_name(fmri, snapshot, pg_name, type, t, 6623*7887SLiane.Praza@Sun.COM 0) != 0) { 6624*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6625*7887SLiane.Praza@Sun.COM goto cleanup; 6626*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6627*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 6628*7887SLiane.Praza@Sun.COM continue; 6629*7887SLiane.Praza@Sun.COM 6630*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6631*7887SLiane.Praza@Sun.COM goto cleanup; 6632*7887SLiane.Praza@Sun.COM 6633*7887SLiane.Praza@Sun.COM default: 6634*7887SLiane.Praza@Sun.COM assert(0); 6635*7887SLiane.Praza@Sun.COM abort(); 6636*7887SLiane.Praza@Sun.COM } 6637*7887SLiane.Praza@Sun.COM } 6638*7887SLiane.Praza@Sun.COM 6639*7887SLiane.Praza@Sun.COM if (_check_pg(t, pg, pg_name, type, *errs) != 0) 6640*7887SLiane.Praza@Sun.COM goto cleanup; 6641*7887SLiane.Praza@Sun.COM } 6642*7887SLiane.Praza@Sun.COM if (r < 0) { 6643*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6644*7887SLiane.Praza@Sun.COM goto cleanup; 6645*7887SLiane.Praza@Sun.COM } else { 6646*7887SLiane.Praza@Sun.COM assert(0); 6647*7887SLiane.Praza@Sun.COM abort(); 6648*7887SLiane.Praza@Sun.COM } 6649*7887SLiane.Praza@Sun.COM } 6650*7887SLiane.Praza@Sun.COM 6651*7887SLiane.Praza@Sun.COM scf_tmpl_pg_reset(t); 6652*7887SLiane.Praza@Sun.COM 6653*7887SLiane.Praza@Sun.COM /* 6654*7887SLiane.Praza@Sun.COM * Confirm required property groups are present. 6655*7887SLiane.Praza@Sun.COM */ 6656*7887SLiane.Praza@Sun.COM while ((r = scf_tmpl_iter_pgs(t, fmri, snapshot, NULL, 6657*7887SLiane.Praza@Sun.COM SCF_PG_TMPL_FLAG_REQUIRED)) == 1) { 6658*7887SLiane.Praza@Sun.COM free(pg_name); 6659*7887SLiane.Praza@Sun.COM free(type); 6660*7887SLiane.Praza@Sun.COM 6661*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_name(t, &pg_name) == -1) 6662*7887SLiane.Praza@Sun.COM goto cleanup; 6663*7887SLiane.Praza@Sun.COM if (scf_tmpl_pg_type(t, &type) == -1) 6664*7887SLiane.Praza@Sun.COM goto cleanup; 6665*7887SLiane.Praza@Sun.COM /* 6666*7887SLiane.Praza@Sun.COM * required property group templates should not have 6667*7887SLiane.Praza@Sun.COM * wildcarded name or type 6668*7887SLiane.Praza@Sun.COM */ 6669*7887SLiane.Praza@Sun.COM if (strcmp(pg_name, SCF_TMPL_WILDCARD) == 0 || 6670*7887SLiane.Praza@Sun.COM strcmp(type, SCF_TMPL_WILDCARD) == 0) { 6671*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_TEMPLATE_INVALID); 6672*7887SLiane.Praza@Sun.COM goto cleanup; 6673*7887SLiane.Praza@Sun.COM } 6674*7887SLiane.Praza@Sun.COM 6675*7887SLiane.Praza@Sun.COM if (_get_pg(NULL, inst, snap, pg_name, pg) != 0) { 6676*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6677*7887SLiane.Praza@Sun.COM goto cleanup; 6678*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6679*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 6680*7887SLiane.Praza@Sun.COM if (_add_tmpl_missing_pg_error(*errs, t) == -1) 6681*7887SLiane.Praza@Sun.COM goto cleanup; 6682*7887SLiane.Praza@Sun.COM continue; 6683*7887SLiane.Praza@Sun.COM 6684*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6685*7887SLiane.Praza@Sun.COM case SCF_ERROR_HANDLE_MISMATCH: 6686*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_SET: 6687*7887SLiane.Praza@Sun.COM default: 6688*7887SLiane.Praza@Sun.COM assert(0); 6689*7887SLiane.Praza@Sun.COM abort(); 6690*7887SLiane.Praza@Sun.COM } 6691*7887SLiane.Praza@Sun.COM } 6692*7887SLiane.Praza@Sun.COM } 6693*7887SLiane.Praza@Sun.COM if (r < 0) { 6694*7887SLiane.Praza@Sun.COM if (ismember(scf_error(), errors_server)) { 6695*7887SLiane.Praza@Sun.COM goto cleanup; 6696*7887SLiane.Praza@Sun.COM } else switch (scf_error()) { 6697*7887SLiane.Praza@Sun.COM case SCF_ERROR_NOT_FOUND: 6698*7887SLiane.Praza@Sun.COM break; 6699*7887SLiane.Praza@Sun.COM 6700*7887SLiane.Praza@Sun.COM case SCF_ERROR_INVALID_ARGUMENT: 6701*7887SLiane.Praza@Sun.COM goto cleanup; 6702*7887SLiane.Praza@Sun.COM 6703*7887SLiane.Praza@Sun.COM default: 6704*7887SLiane.Praza@Sun.COM assert(0); 6705*7887SLiane.Praza@Sun.COM abort(); 6706*7887SLiane.Praza@Sun.COM } 6707*7887SLiane.Praza@Sun.COM } 6708*7887SLiane.Praza@Sun.COM 6709*7887SLiane.Praza@Sun.COM ret = 0; 6710*7887SLiane.Praza@Sun.COM if ((*errs)->tes_num_errs > 0) 6711*7887SLiane.Praza@Sun.COM ret = 1; 6712*7887SLiane.Praza@Sun.COM cleanup: 6713*7887SLiane.Praza@Sun.COM if (ret != 1) { 6714*7887SLiane.Praza@Sun.COM /* there are no errors to report */ 6715*7887SLiane.Praza@Sun.COM scf_tmpl_errors_destroy(*errs); 6716*7887SLiane.Praza@Sun.COM *errs = NULL; 6717*7887SLiane.Praza@Sun.COM } 6718*7887SLiane.Praza@Sun.COM scf_tmpl_pg_destroy(t); 6719*7887SLiane.Praza@Sun.COM free(type); 6720*7887SLiane.Praza@Sun.COM free(pg_name); 6721*7887SLiane.Praza@Sun.COM 6722*7887SLiane.Praza@Sun.COM scf_iter_destroy(iter); 6723*7887SLiane.Praza@Sun.COM scf_pg_destroy(pg); 6724*7887SLiane.Praza@Sun.COM scf_instance_destroy(inst); 6725*7887SLiane.Praza@Sun.COM scf_snapshot_destroy(snap); 6726*7887SLiane.Praza@Sun.COM 6727*7887SLiane.Praza@Sun.COM return (ret); 6728*7887SLiane.Praza@Sun.COM } 6729*7887SLiane.Praza@Sun.COM 6730*7887SLiane.Praza@Sun.COM void 6731*7887SLiane.Praza@Sun.COM scf_tmpl_errors_destroy(scf_tmpl_errors_t *errs) 6732*7887SLiane.Praza@Sun.COM { 6733*7887SLiane.Praza@Sun.COM int i; 6734*7887SLiane.Praza@Sun.COM scf_tmpl_error_t *e; 6735*7887SLiane.Praza@Sun.COM 6736*7887SLiane.Praza@Sun.COM if (errs == NULL) 6737*7887SLiane.Praza@Sun.COM return; 6738*7887SLiane.Praza@Sun.COM 6739*7887SLiane.Praza@Sun.COM for (i = 0; i < errs->tes_num_errs; ++i) { 6740*7887SLiane.Praza@Sun.COM e = errs->tes_errs[i]; 6741*7887SLiane.Praza@Sun.COM if (errs->tes_flag != 0) { 6742*7887SLiane.Praza@Sun.COM free((char *)e->te_pg_name); 6743*7887SLiane.Praza@Sun.COM free((char *)e->te_prop_name); 6744*7887SLiane.Praza@Sun.COM free((char *)e->te_ev1); 6745*7887SLiane.Praza@Sun.COM free((char *)e->te_ev2); 6746*7887SLiane.Praza@Sun.COM free((char *)e->te_actual); 6747*7887SLiane.Praza@Sun.COM free((char *)e->te_tmpl_fmri); 6748*7887SLiane.Praza@Sun.COM free((char *)e->te_tmpl_pg_name); 6749*7887SLiane.Praza@Sun.COM free((char *)e->te_tmpl_pg_type); 6750*7887SLiane.Praza@Sun.COM free((char *)e->te_tmpl_prop_name); 6751*7887SLiane.Praza@Sun.COM free((char *)e->te_tmpl_prop_type); 6752*7887SLiane.Praza@Sun.COM } 6753*7887SLiane.Praza@Sun.COM free(e); 6754*7887SLiane.Praza@Sun.COM } 6755*7887SLiane.Praza@Sun.COM free((char *)errs->tes_fmri); 6756*7887SLiane.Praza@Sun.COM free((char *)errs->tes_prefix); 6757*7887SLiane.Praza@Sun.COM free(errs->tes_errs); 6758*7887SLiane.Praza@Sun.COM free(errs); 6759*7887SLiane.Praza@Sun.COM } 6760*7887SLiane.Praza@Sun.COM 6761*7887SLiane.Praza@Sun.COM int 6762*7887SLiane.Praza@Sun.COM scf_tmpl_error_source_fmri(const scf_tmpl_error_t *err, char **fmri) 6763*7887SLiane.Praza@Sun.COM { 6764*7887SLiane.Praza@Sun.COM assert(err != NULL); 6765*7887SLiane.Praza@Sun.COM switch (err->te_type) { 6766*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 6767*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 6768*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 6769*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 6770*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 6771*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 6772*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 6773*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 6774*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 6775*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 6776*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 6777*7887SLiane.Praza@Sun.COM *fmri = (char *)err->te_tmpl_fmri; 6778*7887SLiane.Praza@Sun.COM return (0); 6779*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 6780*7887SLiane.Praza@Sun.COM default: 6781*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 6782*7887SLiane.Praza@Sun.COM } 6783*7887SLiane.Praza@Sun.COM return (-1); 6784*7887SLiane.Praza@Sun.COM } 6785*7887SLiane.Praza@Sun.COM 6786*7887SLiane.Praza@Sun.COM int 6787*7887SLiane.Praza@Sun.COM scf_tmpl_error_type(const scf_tmpl_error_t *err, scf_tmpl_error_type_t *type) 6788*7887SLiane.Praza@Sun.COM { 6789*7887SLiane.Praza@Sun.COM assert(err != NULL); 6790*7887SLiane.Praza@Sun.COM switch (err->te_type) { 6791*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 6792*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 6793*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 6794*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 6795*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 6796*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 6797*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 6798*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 6799*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 6800*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 6801*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 6802*7887SLiane.Praza@Sun.COM *type = err->te_type; 6803*7887SLiane.Praza@Sun.COM return (0); 6804*7887SLiane.Praza@Sun.COM /*NOTREACHED*/ 6805*7887SLiane.Praza@Sun.COM default: 6806*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 6807*7887SLiane.Praza@Sun.COM } 6808*7887SLiane.Praza@Sun.COM return (-1); 6809*7887SLiane.Praza@Sun.COM } 6810*7887SLiane.Praza@Sun.COM 6811*7887SLiane.Praza@Sun.COM int 6812*7887SLiane.Praza@Sun.COM scf_tmpl_error_pg_tmpl(const scf_tmpl_error_t *err, char **name, char **type) 6813*7887SLiane.Praza@Sun.COM { 6814*7887SLiane.Praza@Sun.COM assert(err != NULL); 6815*7887SLiane.Praza@Sun.COM switch (err->te_type) { 6816*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 6817*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 6818*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 6819*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 6820*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 6821*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 6822*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 6823*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 6824*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 6825*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 6826*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 6827*7887SLiane.Praza@Sun.COM if (err->te_tmpl_pg_name != NULL && 6828*7887SLiane.Praza@Sun.COM err->te_tmpl_pg_type != NULL) { 6829*7887SLiane.Praza@Sun.COM if (name != NULL) 6830*7887SLiane.Praza@Sun.COM *name = (char *)err->te_tmpl_pg_name; 6831*7887SLiane.Praza@Sun.COM if (type != NULL) 6832*7887SLiane.Praza@Sun.COM *type = (char *)err->te_tmpl_pg_type; 6833*7887SLiane.Praza@Sun.COM return (0); 6834*7887SLiane.Praza@Sun.COM } 6835*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 6836*7887SLiane.Praza@Sun.COM break; 6837*7887SLiane.Praza@Sun.COM default: 6838*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 6839*7887SLiane.Praza@Sun.COM } 6840*7887SLiane.Praza@Sun.COM return (-1); 6841*7887SLiane.Praza@Sun.COM } 6842*7887SLiane.Praza@Sun.COM 6843*7887SLiane.Praza@Sun.COM int 6844*7887SLiane.Praza@Sun.COM scf_tmpl_error_pg(const scf_tmpl_error_t *err, char **name, char **type) 6845*7887SLiane.Praza@Sun.COM { 6846*7887SLiane.Praza@Sun.COM assert(err != NULL); 6847*7887SLiane.Praza@Sun.COM switch (err->te_type) { 6848*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 6849*7887SLiane.Praza@Sun.COM if (err->te_pg_name != NULL && 6850*7887SLiane.Praza@Sun.COM err->te_actual != NULL) { 6851*7887SLiane.Praza@Sun.COM if (name != NULL) 6852*7887SLiane.Praza@Sun.COM *name = (char *)err->te_pg_name; 6853*7887SLiane.Praza@Sun.COM if (type != NULL) 6854*7887SLiane.Praza@Sun.COM *type = (char *)err->te_actual; 6855*7887SLiane.Praza@Sun.COM return (0); 6856*7887SLiane.Praza@Sun.COM } 6857*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 6858*7887SLiane.Praza@Sun.COM break; 6859*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 6860*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 6861*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 6862*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 6863*7887SLiane.Praza@Sun.COM if (err->te_pg_name != NULL && 6864*7887SLiane.Praza@Sun.COM err->te_tmpl_pg_type != NULL) { 6865*7887SLiane.Praza@Sun.COM if (name != NULL) 6866*7887SLiane.Praza@Sun.COM *name = (char *)err->te_pg_name; 6867*7887SLiane.Praza@Sun.COM if (type != NULL) 6868*7887SLiane.Praza@Sun.COM *type = (char *)err->te_tmpl_pg_type; 6869*7887SLiane.Praza@Sun.COM return (0); 6870*7887SLiane.Praza@Sun.COM } 6871*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 6872*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 6873*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 6874*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 6875*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 6876*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 6877*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 6878*7887SLiane.Praza@Sun.COM break; 6879*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 6880*7887SLiane.Praza@Sun.COM if (err->te_ev1 != NULL && err->te_ev2 != NULL) { 6881*7887SLiane.Praza@Sun.COM if (name != NULL) 6882*7887SLiane.Praza@Sun.COM *name = (char *)err->te_ev1; 6883*7887SLiane.Praza@Sun.COM if (type != NULL) 6884*7887SLiane.Praza@Sun.COM *type = (char *)err->te_ev2; 6885*7887SLiane.Praza@Sun.COM return (0); 6886*7887SLiane.Praza@Sun.COM } 6887*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 6888*7887SLiane.Praza@Sun.COM break; 6889*7887SLiane.Praza@Sun.COM default: 6890*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 6891*7887SLiane.Praza@Sun.COM } 6892*7887SLiane.Praza@Sun.COM return (-1); 6893*7887SLiane.Praza@Sun.COM } 6894*7887SLiane.Praza@Sun.COM 6895*7887SLiane.Praza@Sun.COM int 6896*7887SLiane.Praza@Sun.COM scf_tmpl_error_prop_tmpl(const scf_tmpl_error_t *err, char **name, char **type) 6897*7887SLiane.Praza@Sun.COM { 6898*7887SLiane.Praza@Sun.COM assert(err != NULL); 6899*7887SLiane.Praza@Sun.COM switch (err->te_type) { 6900*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 6901*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 6902*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 6903*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 6904*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 6905*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 6906*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 6907*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 6908*7887SLiane.Praza@Sun.COM if (err->te_tmpl_prop_name != NULL && 6909*7887SLiane.Praza@Sun.COM err->te_tmpl_prop_type != NULL) { 6910*7887SLiane.Praza@Sun.COM if (name != NULL) 6911*7887SLiane.Praza@Sun.COM *name = (char *)err->te_tmpl_prop_name; 6912*7887SLiane.Praza@Sun.COM if (type != NULL) 6913*7887SLiane.Praza@Sun.COM *type = (char *)err->te_tmpl_prop_type; 6914*7887SLiane.Praza@Sun.COM return (0); 6915*7887SLiane.Praza@Sun.COM } 6916*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 6917*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 6918*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 6919*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 6920*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 6921*7887SLiane.Praza@Sun.COM break; 6922*7887SLiane.Praza@Sun.COM default: 6923*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 6924*7887SLiane.Praza@Sun.COM } 6925*7887SLiane.Praza@Sun.COM return (-1); 6926*7887SLiane.Praza@Sun.COM } 6927*7887SLiane.Praza@Sun.COM 6928*7887SLiane.Praza@Sun.COM int 6929*7887SLiane.Praza@Sun.COM scf_tmpl_error_prop(const scf_tmpl_error_t *err, char **name, char **type) 6930*7887SLiane.Praza@Sun.COM { 6931*7887SLiane.Praza@Sun.COM assert(err != NULL); 6932*7887SLiane.Praza@Sun.COM switch (err->te_type) { 6933*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 6934*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 6935*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 6936*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 6937*7887SLiane.Praza@Sun.COM if (err->te_prop_name != NULL && 6938*7887SLiane.Praza@Sun.COM err->te_tmpl_prop_type != NULL) { 6939*7887SLiane.Praza@Sun.COM if (name != NULL) 6940*7887SLiane.Praza@Sun.COM *name = (char *)err->te_prop_name; 6941*7887SLiane.Praza@Sun.COM if (type != NULL) 6942*7887SLiane.Praza@Sun.COM *type = (char *)err->te_tmpl_prop_type; 6943*7887SLiane.Praza@Sun.COM return (0); 6944*7887SLiane.Praza@Sun.COM } 6945*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 6946*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 6947*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 6948*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 6949*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 6950*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 6951*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 6952*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 6953*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 6954*7887SLiane.Praza@Sun.COM break; 6955*7887SLiane.Praza@Sun.COM default: 6956*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 6957*7887SLiane.Praza@Sun.COM } 6958*7887SLiane.Praza@Sun.COM return (-1); 6959*7887SLiane.Praza@Sun.COM } 6960*7887SLiane.Praza@Sun.COM 6961*7887SLiane.Praza@Sun.COM int 6962*7887SLiane.Praza@Sun.COM scf_tmpl_error_value(const scf_tmpl_error_t *err, char **val) 6963*7887SLiane.Praza@Sun.COM { 6964*7887SLiane.Praza@Sun.COM assert(err != NULL); 6965*7887SLiane.Praza@Sun.COM switch (err->te_type) { 6966*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_CONSTRAINT_VIOLATED: 6967*7887SLiane.Praza@Sun.COM case SCF_TERR_RANGE_VIOLATION: 6968*7887SLiane.Praza@Sun.COM case SCF_TERR_VALUE_OUT_OF_RANGE: 6969*7887SLiane.Praza@Sun.COM case SCF_TERR_INVALID_VALUE: 6970*7887SLiane.Praza@Sun.COM if (err->te_actual != NULL) { 6971*7887SLiane.Praza@Sun.COM if (val != NULL) 6972*7887SLiane.Praza@Sun.COM *val = (char *)err->te_actual; 6973*7887SLiane.Praza@Sun.COM return (0); 6974*7887SLiane.Praza@Sun.COM } 6975*7887SLiane.Praza@Sun.COM /*FALLTHROUGH*/ 6976*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PG: 6977*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PG_TYPE: 6978*7887SLiane.Praza@Sun.COM case SCF_TERR_MISSING_PROP: 6979*7887SLiane.Praza@Sun.COM case SCF_TERR_WRONG_PROP_TYPE: 6980*7887SLiane.Praza@Sun.COM case SCF_TERR_CARDINALITY_VIOLATION: 6981*7887SLiane.Praza@Sun.COM case SCF_TERR_PROP_TYPE_MISMATCH: 6982*7887SLiane.Praza@Sun.COM case SCF_TERR_PG_REDEFINE: 6983*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_NOT_FOUND); 6984*7887SLiane.Praza@Sun.COM break; 6985*7887SLiane.Praza@Sun.COM default: 6986*7887SLiane.Praza@Sun.COM (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT); 6987*7887SLiane.Praza@Sun.COM } 6988*7887SLiane.Praza@Sun.COM return (-1); 6989*7887SLiane.Praza@Sun.COM } 6990*7887SLiane.Praza@Sun.COM 6991*7887SLiane.Praza@Sun.COM const char * 6992*7887SLiane.Praza@Sun.COM scf_tmpl_visibility_to_string(uint8_t vis) 6993*7887SLiane.Praza@Sun.COM { 6994*7887SLiane.Praza@Sun.COM if (vis == SCF_TMPL_VISIBILITY_READONLY) 6995*7887SLiane.Praza@Sun.COM return (SCF_TM_VISIBILITY_READONLY); 6996*7887SLiane.Praza@Sun.COM else if (vis == SCF_TMPL_VISIBILITY_HIDDEN) 6997*7887SLiane.Praza@Sun.COM return (SCF_TM_VISIBILITY_HIDDEN); 6998*7887SLiane.Praza@Sun.COM else if (vis == SCF_TMPL_VISIBILITY_READWRITE) 6999*7887SLiane.Praza@Sun.COM return (SCF_TM_VISIBILITY_READWRITE); 7000*7887SLiane.Praza@Sun.COM else 7001*7887SLiane.Praza@Sun.COM return ("unknown"); 7002*7887SLiane.Praza@Sun.COM } 7003