1*11767SAnurag.Maskey@Sun.COM /* 2*11767SAnurag.Maskey@Sun.COM * CDDL HEADER START 3*11767SAnurag.Maskey@Sun.COM * 4*11767SAnurag.Maskey@Sun.COM * The contents of this file are subject to the terms of the 5*11767SAnurag.Maskey@Sun.COM * Common Development and Distribution License (the "License"). 6*11767SAnurag.Maskey@Sun.COM * You may not use this file except in compliance with the License. 7*11767SAnurag.Maskey@Sun.COM * 8*11767SAnurag.Maskey@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*11767SAnurag.Maskey@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*11767SAnurag.Maskey@Sun.COM * See the License for the specific language governing permissions 11*11767SAnurag.Maskey@Sun.COM * and limitations under the License. 12*11767SAnurag.Maskey@Sun.COM * 13*11767SAnurag.Maskey@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*11767SAnurag.Maskey@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*11767SAnurag.Maskey@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*11767SAnurag.Maskey@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*11767SAnurag.Maskey@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*11767SAnurag.Maskey@Sun.COM * 19*11767SAnurag.Maskey@Sun.COM * CDDL HEADER END 20*11767SAnurag.Maskey@Sun.COM */ 21*11767SAnurag.Maskey@Sun.COM 22*11767SAnurag.Maskey@Sun.COM /* 23*11767SAnurag.Maskey@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*11767SAnurag.Maskey@Sun.COM * Use is subject to license terms. 25*11767SAnurag.Maskey@Sun.COM */ 26*11767SAnurag.Maskey@Sun.COM 27*11767SAnurag.Maskey@Sun.COM #include <assert.h> 28*11767SAnurag.Maskey@Sun.COM #include <stdlib.h> 29*11767SAnurag.Maskey@Sun.COM #include <strings.h> 30*11767SAnurag.Maskey@Sun.COM #include <string.h> 31*11767SAnurag.Maskey@Sun.COM 32*11767SAnurag.Maskey@Sun.COM #include "libnwam_impl.h" 33*11767SAnurag.Maskey@Sun.COM #include <libintl.h> 34*11767SAnurag.Maskey@Sun.COM #include <libnwam.h> 35*11767SAnurag.Maskey@Sun.COM 36*11767SAnurag.Maskey@Sun.COM /* 37*11767SAnurag.Maskey@Sun.COM * Generic object manipulation functions. Given an object handle and 38*11767SAnurag.Maskey@Sun.COM * other parameters, create/destroy objects, walk them, walk their 39*11767SAnurag.Maskey@Sun.COM * properties, modify/retrieve/delete properties, enable/disable them, 40*11767SAnurag.Maskey@Sun.COM * etc. All object handles are "struct nwam_handle *" objects, sharing 41*11767SAnurag.Maskey@Sun.COM * the same description based on the object type, name, original name 42*11767SAnurag.Maskey@Sun.COM * (used in renaming) and associated data representing properties. 43*11767SAnurag.Maskey@Sun.COM */ 44*11767SAnurag.Maskey@Sun.COM 45*11767SAnurag.Maskey@Sun.COM nwam_error_t 46*11767SAnurag.Maskey@Sun.COM nwam_handle_create(nwam_object_type_t type, const char *name, 47*11767SAnurag.Maskey@Sun.COM struct nwam_handle **hpp) 48*11767SAnurag.Maskey@Sun.COM { 49*11767SAnurag.Maskey@Sun.COM 50*11767SAnurag.Maskey@Sun.COM assert(name != NULL && hpp != NULL); 51*11767SAnurag.Maskey@Sun.COM 52*11767SAnurag.Maskey@Sun.COM if (strnlen(name, NWAM_MAX_NAME_LEN) > NWAM_MAX_NAME_LEN) { 53*11767SAnurag.Maskey@Sun.COM *hpp = NULL; 54*11767SAnurag.Maskey@Sun.COM return (NWAM_INVALID_ARG); 55*11767SAnurag.Maskey@Sun.COM } 56*11767SAnurag.Maskey@Sun.COM 57*11767SAnurag.Maskey@Sun.COM if ((*hpp = calloc(1, sizeof (struct nwam_handle))) == NULL) 58*11767SAnurag.Maskey@Sun.COM return (NWAM_NO_MEMORY); 59*11767SAnurag.Maskey@Sun.COM 60*11767SAnurag.Maskey@Sun.COM (*hpp)->nwh_object_type = type; 61*11767SAnurag.Maskey@Sun.COM (void) strlcpy((*hpp)->nwh_name, name, strlen(name) + 1); 62*11767SAnurag.Maskey@Sun.COM (*hpp)->nwh_committed = B_FALSE; 63*11767SAnurag.Maskey@Sun.COM (*hpp)->nwh_data = NULL; 64*11767SAnurag.Maskey@Sun.COM 65*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 66*11767SAnurag.Maskey@Sun.COM } 67*11767SAnurag.Maskey@Sun.COM 68*11767SAnurag.Maskey@Sun.COM /* 69*11767SAnurag.Maskey@Sun.COM * Read object of specified type from dbname. 70*11767SAnurag.Maskey@Sun.COM */ 71*11767SAnurag.Maskey@Sun.COM nwam_error_t 72*11767SAnurag.Maskey@Sun.COM nwam_read(nwam_object_type_t type, const char *dbname, const char *name, 73*11767SAnurag.Maskey@Sun.COM uint64_t flags, struct nwam_handle **hpp) 74*11767SAnurag.Maskey@Sun.COM { 75*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 76*11767SAnurag.Maskey@Sun.COM char dbname_copy[MAXPATHLEN]; 77*11767SAnurag.Maskey@Sun.COM 78*11767SAnurag.Maskey@Sun.COM assert(name != NULL && hpp != NULL); 79*11767SAnurag.Maskey@Sun.COM 80*11767SAnurag.Maskey@Sun.COM if (dbname != NULL) 81*11767SAnurag.Maskey@Sun.COM (void) strlcpy(dbname_copy, dbname, sizeof (dbname_copy)); 82*11767SAnurag.Maskey@Sun.COM 83*11767SAnurag.Maskey@Sun.COM if ((err = nwam_valid_flags(flags, NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS) 84*11767SAnurag.Maskey@Sun.COM return (err); 85*11767SAnurag.Maskey@Sun.COM if ((err = nwam_handle_create(type, name, hpp)) != NWAM_SUCCESS) 86*11767SAnurag.Maskey@Sun.COM return (err); 87*11767SAnurag.Maskey@Sun.COM 88*11767SAnurag.Maskey@Sun.COM if ((err = nwam_read_object_from_backend 89*11767SAnurag.Maskey@Sun.COM (dbname != NULL ? dbname_copy : NULL, 90*11767SAnurag.Maskey@Sun.COM type == NWAM_OBJECT_TYPE_NCP ? NULL : (*hpp)->nwh_name, flags, 91*11767SAnurag.Maskey@Sun.COM &(*hpp)->nwh_data)) != NWAM_SUCCESS) { 92*11767SAnurag.Maskey@Sun.COM free(*hpp); 93*11767SAnurag.Maskey@Sun.COM *hpp = NULL; 94*11767SAnurag.Maskey@Sun.COM return (err); 95*11767SAnurag.Maskey@Sun.COM } 96*11767SAnurag.Maskey@Sun.COM if (type == NWAM_OBJECT_TYPE_NCP && dbname != NULL) { 97*11767SAnurag.Maskey@Sun.COM char *ncpname; 98*11767SAnurag.Maskey@Sun.COM 99*11767SAnurag.Maskey@Sun.COM /* 100*11767SAnurag.Maskey@Sun.COM * dbname_copy may have been changed due to case-insensitive 101*11767SAnurag.Maskey@Sun.COM * match against the actual NCP configuration file. 102*11767SAnurag.Maskey@Sun.COM */ 103*11767SAnurag.Maskey@Sun.COM if (nwam_ncp_file_to_name(dbname_copy, &ncpname) 104*11767SAnurag.Maskey@Sun.COM == NWAM_SUCCESS) { 105*11767SAnurag.Maskey@Sun.COM (void) strlcpy((*hpp)->nwh_name, ncpname, 106*11767SAnurag.Maskey@Sun.COM sizeof ((*hpp)->nwh_name)); 107*11767SAnurag.Maskey@Sun.COM free(ncpname); 108*11767SAnurag.Maskey@Sun.COM } 109*11767SAnurag.Maskey@Sun.COM } 110*11767SAnurag.Maskey@Sun.COM 111*11767SAnurag.Maskey@Sun.COM (*hpp)->nwh_committed = B_TRUE; 112*11767SAnurag.Maskey@Sun.COM 113*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 114*11767SAnurag.Maskey@Sun.COM } 115*11767SAnurag.Maskey@Sun.COM 116*11767SAnurag.Maskey@Sun.COM /* 117*11767SAnurag.Maskey@Sun.COM * Create simply creates the handle - the object-specific function must 118*11767SAnurag.Maskey@Sun.COM * then fill in property values. 119*11767SAnurag.Maskey@Sun.COM */ 120*11767SAnurag.Maskey@Sun.COM nwam_error_t 121*11767SAnurag.Maskey@Sun.COM nwam_create(nwam_object_type_t type, const char *dbname, const char *name, 122*11767SAnurag.Maskey@Sun.COM struct nwam_handle **hpp) 123*11767SAnurag.Maskey@Sun.COM { 124*11767SAnurag.Maskey@Sun.COM struct nwam_handle *hp; 125*11767SAnurag.Maskey@Sun.COM 126*11767SAnurag.Maskey@Sun.COM assert(hpp != NULL && name != NULL); 127*11767SAnurag.Maskey@Sun.COM 128*11767SAnurag.Maskey@Sun.COM if (nwam_read(type, dbname, name, 0, &hp) == NWAM_SUCCESS) { 129*11767SAnurag.Maskey@Sun.COM nwam_free(hp); 130*11767SAnurag.Maskey@Sun.COM return (NWAM_ENTITY_EXISTS); 131*11767SAnurag.Maskey@Sun.COM } 132*11767SAnurag.Maskey@Sun.COM /* Create handle */ 133*11767SAnurag.Maskey@Sun.COM return (nwam_handle_create(type, name, hpp)); 134*11767SAnurag.Maskey@Sun.COM } 135*11767SAnurag.Maskey@Sun.COM 136*11767SAnurag.Maskey@Sun.COM nwam_error_t 137*11767SAnurag.Maskey@Sun.COM nwam_get_name(struct nwam_handle *hp, char **namep) 138*11767SAnurag.Maskey@Sun.COM { 139*11767SAnurag.Maskey@Sun.COM assert(hp != NULL && namep != NULL); 140*11767SAnurag.Maskey@Sun.COM 141*11767SAnurag.Maskey@Sun.COM if ((*namep = strdup(hp->nwh_name)) == NULL) { 142*11767SAnurag.Maskey@Sun.COM *namep = NULL; 143*11767SAnurag.Maskey@Sun.COM return (NWAM_NO_MEMORY); 144*11767SAnurag.Maskey@Sun.COM } 145*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 146*11767SAnurag.Maskey@Sun.COM } 147*11767SAnurag.Maskey@Sun.COM 148*11767SAnurag.Maskey@Sun.COM nwam_error_t 149*11767SAnurag.Maskey@Sun.COM nwam_set_name(struct nwam_handle *hp, const char *name) 150*11767SAnurag.Maskey@Sun.COM { 151*11767SAnurag.Maskey@Sun.COM assert(hp != NULL && name != NULL); 152*11767SAnurag.Maskey@Sun.COM 153*11767SAnurag.Maskey@Sun.COM if (hp->nwh_committed) 154*11767SAnurag.Maskey@Sun.COM return (NWAM_ENTITY_READ_ONLY); 155*11767SAnurag.Maskey@Sun.COM 156*11767SAnurag.Maskey@Sun.COM if (strlen(name) >= sizeof (hp->nwh_name)) 157*11767SAnurag.Maskey@Sun.COM return (NWAM_INVALID_ARG); 158*11767SAnurag.Maskey@Sun.COM 159*11767SAnurag.Maskey@Sun.COM (void) strcpy(hp->nwh_name, name); 160*11767SAnurag.Maskey@Sun.COM 161*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 162*11767SAnurag.Maskey@Sun.COM } 163*11767SAnurag.Maskey@Sun.COM 164*11767SAnurag.Maskey@Sun.COM /* Compare object names c1 and c2 using strcasecmp() */ 165*11767SAnurag.Maskey@Sun.COM static int 166*11767SAnurag.Maskey@Sun.COM name_cmp(const void *c1, const void *c2) 167*11767SAnurag.Maskey@Sun.COM { 168*11767SAnurag.Maskey@Sun.COM nwam_ncu_type_t t1, t2; 169*11767SAnurag.Maskey@Sun.COM char *n1, *n2; 170*11767SAnurag.Maskey@Sun.COM 171*11767SAnurag.Maskey@Sun.COM /* If c1 and c2 are typed NCU names, compare names without the types */ 172*11767SAnurag.Maskey@Sun.COM if (nwam_ncu_typed_name_to_name(*(const char **)c1, &t1, &n1) 173*11767SAnurag.Maskey@Sun.COM == NWAM_SUCCESS && 174*11767SAnurag.Maskey@Sun.COM nwam_ncu_typed_name_to_name(*(const char **)c2, &t2, &n2) 175*11767SAnurag.Maskey@Sun.COM == NWAM_SUCCESS) { 176*11767SAnurag.Maskey@Sun.COM int ret = strcasecmp(n1, n2); 177*11767SAnurag.Maskey@Sun.COM free(n1); 178*11767SAnurag.Maskey@Sun.COM free(n2); 179*11767SAnurag.Maskey@Sun.COM 180*11767SAnurag.Maskey@Sun.COM /* For NCUs with the same name, compare their types */ 181*11767SAnurag.Maskey@Sun.COM if (ret == 0) { 182*11767SAnurag.Maskey@Sun.COM if (t1 < t2) 183*11767SAnurag.Maskey@Sun.COM ret = -1; 184*11767SAnurag.Maskey@Sun.COM else if (t1 > t2) 185*11767SAnurag.Maskey@Sun.COM ret = 1; 186*11767SAnurag.Maskey@Sun.COM } 187*11767SAnurag.Maskey@Sun.COM return (ret); 188*11767SAnurag.Maskey@Sun.COM } 189*11767SAnurag.Maskey@Sun.COM 190*11767SAnurag.Maskey@Sun.COM return (strcasecmp(*(const char **)c1, *(const char **)c2)); 191*11767SAnurag.Maskey@Sun.COM } 192*11767SAnurag.Maskey@Sun.COM 193*11767SAnurag.Maskey@Sun.COM /* 194*11767SAnurag.Maskey@Sun.COM * Generic walk function takes the standard walk arguments, and in addition 195*11767SAnurag.Maskey@Sun.COM * takes a selection callback that is object-specific. If this returns 196*11767SAnurag.Maskey@Sun.COM * 0, the object is a valid selection for the walk and the callback is called. 197*11767SAnurag.Maskey@Sun.COM * Otherwise, it is skipped. 198*11767SAnurag.Maskey@Sun.COM */ 199*11767SAnurag.Maskey@Sun.COM nwam_error_t 200*11767SAnurag.Maskey@Sun.COM nwam_walk(nwam_object_type_t type, const char *dbname, 201*11767SAnurag.Maskey@Sun.COM int(*cb)(struct nwam_handle *, void *), 202*11767SAnurag.Maskey@Sun.COM void *data, uint64_t flags, int *retp, 203*11767SAnurag.Maskey@Sun.COM int(*selectcb)(struct nwam_handle *, uint64_t, void *)) 204*11767SAnurag.Maskey@Sun.COM { 205*11767SAnurag.Maskey@Sun.COM void *objlist; 206*11767SAnurag.Maskey@Sun.COM nwam_value_t value; 207*11767SAnurag.Maskey@Sun.COM char **object_names; 208*11767SAnurag.Maskey@Sun.COM uint_t i, num_objects = 0; 209*11767SAnurag.Maskey@Sun.COM struct nwam_handle *hp; 210*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 211*11767SAnurag.Maskey@Sun.COM int ret = 0; 212*11767SAnurag.Maskey@Sun.COM 213*11767SAnurag.Maskey@Sun.COM assert(cb != NULL); 214*11767SAnurag.Maskey@Sun.COM 215*11767SAnurag.Maskey@Sun.COM /* 216*11767SAnurag.Maskey@Sun.COM * To walk a set of objects, call nwam_read_object_from_backend() 217*11767SAnurag.Maskey@Sun.COM * with a "dbname" argument set to the container db name and 218*11767SAnurag.Maskey@Sun.COM * the object name set to NULL. This returns an nvlist with one 219*11767SAnurag.Maskey@Sun.COM * member - the NWAM_OBJECT_NAMES_STRING - and the values it contains 220*11767SAnurag.Maskey@Sun.COM * represent the names of the objects. Read each in turn, calling 221*11767SAnurag.Maskey@Sun.COM * the callback function. 222*11767SAnurag.Maskey@Sun.COM */ 223*11767SAnurag.Maskey@Sun.COM if ((err = nwam_read_object_from_backend((char *)dbname, NULL, flags, 224*11767SAnurag.Maskey@Sun.COM &objlist)) != NWAM_SUCCESS) { 225*11767SAnurag.Maskey@Sun.COM if (err == NWAM_ENTITY_NOT_FOUND) { 226*11767SAnurag.Maskey@Sun.COM /* 227*11767SAnurag.Maskey@Sun.COM * This indicates the dbname container is not present. 228*11767SAnurag.Maskey@Sun.COM * Do not pass back an error in this case, since it is 229*11767SAnurag.Maskey@Sun.COM * valid for a container not to exist. 230*11767SAnurag.Maskey@Sun.COM */ 231*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 232*11767SAnurag.Maskey@Sun.COM } 233*11767SAnurag.Maskey@Sun.COM return (err); 234*11767SAnurag.Maskey@Sun.COM } 235*11767SAnurag.Maskey@Sun.COM 236*11767SAnurag.Maskey@Sun.COM if ((err = nwam_get_prop_value(objlist, NWAM_OBJECT_NAMES_STRING, 237*11767SAnurag.Maskey@Sun.COM &value)) != NWAM_SUCCESS) { 238*11767SAnurag.Maskey@Sun.COM nwam_free_object_list(objlist); 239*11767SAnurag.Maskey@Sun.COM return (err); 240*11767SAnurag.Maskey@Sun.COM } 241*11767SAnurag.Maskey@Sun.COM err = nwam_value_get_string_array(value, &object_names, &num_objects); 242*11767SAnurag.Maskey@Sun.COM nwam_free_object_list(objlist); 243*11767SAnurag.Maskey@Sun.COM if (err != NWAM_SUCCESS) { 244*11767SAnurag.Maskey@Sun.COM nwam_value_free(value); 245*11767SAnurag.Maskey@Sun.COM return (err); 246*11767SAnurag.Maskey@Sun.COM } 247*11767SAnurag.Maskey@Sun.COM 248*11767SAnurag.Maskey@Sun.COM /* sort the object names alphabetically */ 249*11767SAnurag.Maskey@Sun.COM qsort(object_names, num_objects, sizeof (char *), name_cmp); 250*11767SAnurag.Maskey@Sun.COM 251*11767SAnurag.Maskey@Sun.COM for (i = 0; i < num_objects; i++) { 252*11767SAnurag.Maskey@Sun.COM err = nwam_read(type, dbname, object_names[i], 253*11767SAnurag.Maskey@Sun.COM flags & NWAM_FLAG_GLOBAL_MASK, &hp); 254*11767SAnurag.Maskey@Sun.COM /* An object may have disappeared. If so, skip it. */ 255*11767SAnurag.Maskey@Sun.COM if (err == NWAM_ENTITY_NOT_FOUND) 256*11767SAnurag.Maskey@Sun.COM continue; 257*11767SAnurag.Maskey@Sun.COM if (err != NWAM_SUCCESS) { 258*11767SAnurag.Maskey@Sun.COM nwam_value_free(value); 259*11767SAnurag.Maskey@Sun.COM return (err); 260*11767SAnurag.Maskey@Sun.COM } 261*11767SAnurag.Maskey@Sun.COM if ((selectcb == NULL) || (selectcb(hp, flags, data) == 0)) { 262*11767SAnurag.Maskey@Sun.COM ret = cb(hp, data); 263*11767SAnurag.Maskey@Sun.COM if (ret != 0) { 264*11767SAnurag.Maskey@Sun.COM nwam_free(hp); 265*11767SAnurag.Maskey@Sun.COM nwam_value_free(value); 266*11767SAnurag.Maskey@Sun.COM if (retp != NULL) 267*11767SAnurag.Maskey@Sun.COM *retp = ret; 268*11767SAnurag.Maskey@Sun.COM return (NWAM_WALK_HALTED); 269*11767SAnurag.Maskey@Sun.COM } 270*11767SAnurag.Maskey@Sun.COM } 271*11767SAnurag.Maskey@Sun.COM nwam_free(hp); 272*11767SAnurag.Maskey@Sun.COM } 273*11767SAnurag.Maskey@Sun.COM nwam_value_free(value); 274*11767SAnurag.Maskey@Sun.COM 275*11767SAnurag.Maskey@Sun.COM if (retp != NULL) 276*11767SAnurag.Maskey@Sun.COM *retp = ret; 277*11767SAnurag.Maskey@Sun.COM return (err); 278*11767SAnurag.Maskey@Sun.COM } 279*11767SAnurag.Maskey@Sun.COM 280*11767SAnurag.Maskey@Sun.COM void 281*11767SAnurag.Maskey@Sun.COM nwam_free(struct nwam_handle *hp) 282*11767SAnurag.Maskey@Sun.COM { 283*11767SAnurag.Maskey@Sun.COM if (hp != NULL) { 284*11767SAnurag.Maskey@Sun.COM if (hp->nwh_data != NULL) 285*11767SAnurag.Maskey@Sun.COM nwam_free_object_list(hp->nwh_data); 286*11767SAnurag.Maskey@Sun.COM free(hp); 287*11767SAnurag.Maskey@Sun.COM } 288*11767SAnurag.Maskey@Sun.COM } 289*11767SAnurag.Maskey@Sun.COM 290*11767SAnurag.Maskey@Sun.COM /* 291*11767SAnurag.Maskey@Sun.COM * Copy object represented by oldhp to an object newname, all in container 292*11767SAnurag.Maskey@Sun.COM * dbname. 293*11767SAnurag.Maskey@Sun.COM */ 294*11767SAnurag.Maskey@Sun.COM nwam_error_t 295*11767SAnurag.Maskey@Sun.COM nwam_copy(const char *dbname, struct nwam_handle *oldhp, const char *newname, 296*11767SAnurag.Maskey@Sun.COM struct nwam_handle **newhpp) 297*11767SAnurag.Maskey@Sun.COM { 298*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 299*11767SAnurag.Maskey@Sun.COM struct nwam_handle *hp; 300*11767SAnurag.Maskey@Sun.COM 301*11767SAnurag.Maskey@Sun.COM assert(oldhp != NULL && newname != NULL && newhpp != NULL); 302*11767SAnurag.Maskey@Sun.COM 303*11767SAnurag.Maskey@Sun.COM if (nwam_read(oldhp->nwh_object_type, dbname, newname, 0, &hp) 304*11767SAnurag.Maskey@Sun.COM == NWAM_SUCCESS) { 305*11767SAnurag.Maskey@Sun.COM nwam_free(hp); 306*11767SAnurag.Maskey@Sun.COM return (NWAM_ENTITY_EXISTS); 307*11767SAnurag.Maskey@Sun.COM } 308*11767SAnurag.Maskey@Sun.COM 309*11767SAnurag.Maskey@Sun.COM if ((err = nwam_handle_create(oldhp->nwh_object_type, newname, newhpp)) 310*11767SAnurag.Maskey@Sun.COM != NWAM_SUCCESS) 311*11767SAnurag.Maskey@Sun.COM return (err); 312*11767SAnurag.Maskey@Sun.COM if ((err = nwam_dup_object_list(oldhp->nwh_data, 313*11767SAnurag.Maskey@Sun.COM &((*newhpp)->nwh_data))) != NWAM_SUCCESS) { 314*11767SAnurag.Maskey@Sun.COM nwam_free(*newhpp); 315*11767SAnurag.Maskey@Sun.COM *newhpp = NULL; 316*11767SAnurag.Maskey@Sun.COM return (err); 317*11767SAnurag.Maskey@Sun.COM } 318*11767SAnurag.Maskey@Sun.COM 319*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 320*11767SAnurag.Maskey@Sun.COM } 321*11767SAnurag.Maskey@Sun.COM 322*11767SAnurag.Maskey@Sun.COM /* ARGSUSED3 */ 323*11767SAnurag.Maskey@Sun.COM nwam_error_t 324*11767SAnurag.Maskey@Sun.COM nwam_walk_props(struct nwam_handle *hp, 325*11767SAnurag.Maskey@Sun.COM int (*cb)(const char *, nwam_value_t, void *), 326*11767SAnurag.Maskey@Sun.COM void *data, uint64_t flags, int *retp) 327*11767SAnurag.Maskey@Sun.COM { 328*11767SAnurag.Maskey@Sun.COM char *lastpropname = NULL, *propname; 329*11767SAnurag.Maskey@Sun.COM nwam_value_t value; 330*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 331*11767SAnurag.Maskey@Sun.COM int ret = 0; 332*11767SAnurag.Maskey@Sun.COM 333*11767SAnurag.Maskey@Sun.COM assert(hp != NULL && hp->nwh_data != NULL && cb != NULL); 334*11767SAnurag.Maskey@Sun.COM 335*11767SAnurag.Maskey@Sun.COM if ((err = nwam_valid_flags(flags, 0)) != NWAM_SUCCESS) 336*11767SAnurag.Maskey@Sun.COM return (err); 337*11767SAnurag.Maskey@Sun.COM while ((err = nwam_next_object_prop(hp->nwh_data, lastpropname, 338*11767SAnurag.Maskey@Sun.COM &propname, &value)) == NWAM_SUCCESS) { 339*11767SAnurag.Maskey@Sun.COM 340*11767SAnurag.Maskey@Sun.COM ret = cb(propname, value, data); 341*11767SAnurag.Maskey@Sun.COM if (ret != 0) 342*11767SAnurag.Maskey@Sun.COM err = NWAM_WALK_HALTED; 343*11767SAnurag.Maskey@Sun.COM 344*11767SAnurag.Maskey@Sun.COM /* Free value */ 345*11767SAnurag.Maskey@Sun.COM nwam_value_free(value); 346*11767SAnurag.Maskey@Sun.COM 347*11767SAnurag.Maskey@Sun.COM if (err != NWAM_SUCCESS) 348*11767SAnurag.Maskey@Sun.COM break; 349*11767SAnurag.Maskey@Sun.COM 350*11767SAnurag.Maskey@Sun.COM lastpropname = propname; 351*11767SAnurag.Maskey@Sun.COM } 352*11767SAnurag.Maskey@Sun.COM 353*11767SAnurag.Maskey@Sun.COM if (retp != NULL) 354*11767SAnurag.Maskey@Sun.COM *retp = ret; 355*11767SAnurag.Maskey@Sun.COM if (err == NWAM_SUCCESS || err == NWAM_LIST_END) 356*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 357*11767SAnurag.Maskey@Sun.COM return (err); 358*11767SAnurag.Maskey@Sun.COM } 359*11767SAnurag.Maskey@Sun.COM 360*11767SAnurag.Maskey@Sun.COM /* 361*11767SAnurag.Maskey@Sun.COM * Note that prior to calling the generic commit function, object-specific 362*11767SAnurag.Maskey@Sun.COM * validation should be carried out. 363*11767SAnurag.Maskey@Sun.COM */ 364*11767SAnurag.Maskey@Sun.COM nwam_error_t 365*11767SAnurag.Maskey@Sun.COM nwam_commit(const char *dbname, struct nwam_handle *hp, uint64_t flags) 366*11767SAnurag.Maskey@Sun.COM { 367*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 368*11767SAnurag.Maskey@Sun.COM uint64_t iflags = flags; 369*11767SAnurag.Maskey@Sun.COM boolean_t is_ncu; 370*11767SAnurag.Maskey@Sun.COM struct nwam_handle *testhp; 371*11767SAnurag.Maskey@Sun.COM nwam_action_t action; 372*11767SAnurag.Maskey@Sun.COM 373*11767SAnurag.Maskey@Sun.COM assert(hp != NULL); 374*11767SAnurag.Maskey@Sun.COM 375*11767SAnurag.Maskey@Sun.COM /* 376*11767SAnurag.Maskey@Sun.COM * NWAM_FLAG_ENTITY_KNOWN_WLAN is only used for Known WLANs and 377*11767SAnurag.Maskey@Sun.COM * NWAM_FLAG_ENTITY_ENABLE is used for other objects (during enable 378*11767SAnurag.Maskey@Sun.COM * and disable). 379*11767SAnurag.Maskey@Sun.COM */ 380*11767SAnurag.Maskey@Sun.COM if ((err = nwam_valid_flags(flags, 381*11767SAnurag.Maskey@Sun.COM NWAM_FLAG_BLOCKING | NWAM_FLAG_CREATE | 382*11767SAnurag.Maskey@Sun.COM (hp->nwh_object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN ? 383*11767SAnurag.Maskey@Sun.COM NWAM_FLAG_ENTITY_KNOWN_WLAN : NWAM_FLAG_ENTITY_ENABLE))) 384*11767SAnurag.Maskey@Sun.COM != NWAM_SUCCESS) 385*11767SAnurag.Maskey@Sun.COM return (err); 386*11767SAnurag.Maskey@Sun.COM 387*11767SAnurag.Maskey@Sun.COM is_ncu = (hp->nwh_object_type == NWAM_OBJECT_TYPE_NCU); 388*11767SAnurag.Maskey@Sun.COM 389*11767SAnurag.Maskey@Sun.COM /* 390*11767SAnurag.Maskey@Sun.COM * Does object already exist? If not, action is ADD, otherwise REFRESH. 391*11767SAnurag.Maskey@Sun.COM */ 392*11767SAnurag.Maskey@Sun.COM switch (nwam_read(hp->nwh_object_type, (char *)dbname, hp->nwh_name, 0, 393*11767SAnurag.Maskey@Sun.COM &testhp)) { 394*11767SAnurag.Maskey@Sun.COM case NWAM_ENTITY_NOT_FOUND: 395*11767SAnurag.Maskey@Sun.COM action = NWAM_ACTION_ADD; 396*11767SAnurag.Maskey@Sun.COM break; 397*11767SAnurag.Maskey@Sun.COM case NWAM_SUCCESS: 398*11767SAnurag.Maskey@Sun.COM nwam_free(testhp); 399*11767SAnurag.Maskey@Sun.COM if (hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP) 400*11767SAnurag.Maskey@Sun.COM return (NWAM_ENTITY_EXISTS); 401*11767SAnurag.Maskey@Sun.COM /* FALLTHRU */ 402*11767SAnurag.Maskey@Sun.COM default: 403*11767SAnurag.Maskey@Sun.COM action = NWAM_ACTION_REFRESH; 404*11767SAnurag.Maskey@Sun.COM break; 405*11767SAnurag.Maskey@Sun.COM } 406*11767SAnurag.Maskey@Sun.COM 407*11767SAnurag.Maskey@Sun.COM err = nwam_update_object_in_backend((char *)dbname, 408*11767SAnurag.Maskey@Sun.COM hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP ? NULL : hp->nwh_name, 409*11767SAnurag.Maskey@Sun.COM iflags, hp->nwh_data); 410*11767SAnurag.Maskey@Sun.COM if (err != NWAM_SUCCESS) 411*11767SAnurag.Maskey@Sun.COM return (err); 412*11767SAnurag.Maskey@Sun.COM 413*11767SAnurag.Maskey@Sun.COM hp->nwh_committed = B_TRUE; 414*11767SAnurag.Maskey@Sun.COM 415*11767SAnurag.Maskey@Sun.COM /* 416*11767SAnurag.Maskey@Sun.COM * Tell nwamd to reread this object. For NCUs, we need to convert 417*11767SAnurag.Maskey@Sun.COM * the dbname to the NCP name in order to pass it to nwamd. 418*11767SAnurag.Maskey@Sun.COM */ 419*11767SAnurag.Maskey@Sun.COM if (is_ncu) { 420*11767SAnurag.Maskey@Sun.COM char *ncpname; 421*11767SAnurag.Maskey@Sun.COM 422*11767SAnurag.Maskey@Sun.COM if (nwam_ncp_file_to_name(dbname, &ncpname) == NWAM_SUCCESS) { 423*11767SAnurag.Maskey@Sun.COM (void) nwam_request_action(hp->nwh_object_type, 424*11767SAnurag.Maskey@Sun.COM hp->nwh_name, ncpname, action); 425*11767SAnurag.Maskey@Sun.COM free(ncpname); 426*11767SAnurag.Maskey@Sun.COM } 427*11767SAnurag.Maskey@Sun.COM } else { 428*11767SAnurag.Maskey@Sun.COM (void) nwam_request_action(hp->nwh_object_type, hp->nwh_name, 429*11767SAnurag.Maskey@Sun.COM NULL, action); 430*11767SAnurag.Maskey@Sun.COM } 431*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 432*11767SAnurag.Maskey@Sun.COM } 433*11767SAnurag.Maskey@Sun.COM 434*11767SAnurag.Maskey@Sun.COM static boolean_t 435*11767SAnurag.Maskey@Sun.COM nwam_is_active(struct nwam_handle *hp) 436*11767SAnurag.Maskey@Sun.COM { 437*11767SAnurag.Maskey@Sun.COM nwam_state_t state; 438*11767SAnurag.Maskey@Sun.COM nwam_aux_state_t aux; 439*11767SAnurag.Maskey@Sun.COM 440*11767SAnurag.Maskey@Sun.COM return ((nwam_get_state(NULL, hp, &state, &aux) == NWAM_SUCCESS && 441*11767SAnurag.Maskey@Sun.COM state == NWAM_STATE_ONLINE)); 442*11767SAnurag.Maskey@Sun.COM } 443*11767SAnurag.Maskey@Sun.COM 444*11767SAnurag.Maskey@Sun.COM nwam_error_t 445*11767SAnurag.Maskey@Sun.COM nwam_destroy(const char *dbname, struct nwam_handle *hp, uint64_t flags) 446*11767SAnurag.Maskey@Sun.COM { 447*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 448*11767SAnurag.Maskey@Sun.COM char *name; 449*11767SAnurag.Maskey@Sun.COM boolean_t is_ncp, is_ncu; 450*11767SAnurag.Maskey@Sun.COM 451*11767SAnurag.Maskey@Sun.COM assert(hp != NULL); 452*11767SAnurag.Maskey@Sun.COM 453*11767SAnurag.Maskey@Sun.COM /* NWAM_FLAG_ENTITY_KNOWN_WLAN is only used for Known WLANs */ 454*11767SAnurag.Maskey@Sun.COM if ((err = nwam_valid_flags(flags, 455*11767SAnurag.Maskey@Sun.COM NWAM_FLAG_BLOCKING | NWAM_FLAG_DO_NOT_FREE | 456*11767SAnurag.Maskey@Sun.COM (hp->nwh_object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN ? 457*11767SAnurag.Maskey@Sun.COM NWAM_FLAG_ENTITY_KNOWN_WLAN : 0))) != NWAM_SUCCESS) 458*11767SAnurag.Maskey@Sun.COM return (err); 459*11767SAnurag.Maskey@Sun.COM 460*11767SAnurag.Maskey@Sun.COM is_ncp = hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP; 461*11767SAnurag.Maskey@Sun.COM is_ncu = hp->nwh_object_type == NWAM_OBJECT_TYPE_NCU; 462*11767SAnurag.Maskey@Sun.COM name = hp->nwh_name; 463*11767SAnurag.Maskey@Sun.COM 464*11767SAnurag.Maskey@Sun.COM /* Check if object is active */ 465*11767SAnurag.Maskey@Sun.COM if (!is_ncp && !is_ncu && nwam_is_active(hp)) 466*11767SAnurag.Maskey@Sun.COM return (NWAM_ENTITY_IN_USE); 467*11767SAnurag.Maskey@Sun.COM 468*11767SAnurag.Maskey@Sun.COM /* For NCPs, just remove the dbname file, otherwise remove the object */ 469*11767SAnurag.Maskey@Sun.COM err = nwam_remove_object_from_backend((char *)dbname, 470*11767SAnurag.Maskey@Sun.COM is_ncp ? NULL : name, flags); 471*11767SAnurag.Maskey@Sun.COM 472*11767SAnurag.Maskey@Sun.COM /* 473*11767SAnurag.Maskey@Sun.COM * Tell nwamd to remove this object. For NCUs, we need to convert the 474*11767SAnurag.Maskey@Sun.COM * dbname filename to the NCP name to pass it to nwamd. 475*11767SAnurag.Maskey@Sun.COM */ 476*11767SAnurag.Maskey@Sun.COM if (is_ncu) { 477*11767SAnurag.Maskey@Sun.COM char *ncpname; 478*11767SAnurag.Maskey@Sun.COM 479*11767SAnurag.Maskey@Sun.COM if (nwam_ncp_file_to_name(dbname, &ncpname) == NWAM_SUCCESS) { 480*11767SAnurag.Maskey@Sun.COM (void) nwam_request_action(hp->nwh_object_type, name, 481*11767SAnurag.Maskey@Sun.COM ncpname, NWAM_ACTION_DESTROY); 482*11767SAnurag.Maskey@Sun.COM free(ncpname); 483*11767SAnurag.Maskey@Sun.COM } 484*11767SAnurag.Maskey@Sun.COM } else { 485*11767SAnurag.Maskey@Sun.COM (void) nwam_request_action(hp->nwh_object_type, name, NULL, 486*11767SAnurag.Maskey@Sun.COM NWAM_ACTION_DESTROY); 487*11767SAnurag.Maskey@Sun.COM } 488*11767SAnurag.Maskey@Sun.COM 489*11767SAnurag.Maskey@Sun.COM if ((err == NWAM_SUCCESS) && !(flags & NWAM_FLAG_DO_NOT_FREE)) 490*11767SAnurag.Maskey@Sun.COM nwam_free(hp); 491*11767SAnurag.Maskey@Sun.COM 492*11767SAnurag.Maskey@Sun.COM return (err); 493*11767SAnurag.Maskey@Sun.COM } 494*11767SAnurag.Maskey@Sun.COM 495*11767SAnurag.Maskey@Sun.COM /* 496*11767SAnurag.Maskey@Sun.COM * Enable/disable functions assume prior checking of activation mode 497*11767SAnurag.Maskey@Sun.COM * to ensure an enable/disable action is valid for the object. "parent" in these 498*11767SAnurag.Maskey@Sun.COM * functions specifies the NCP for NCUs. 499*11767SAnurag.Maskey@Sun.COM */ 500*11767SAnurag.Maskey@Sun.COM nwam_error_t 501*11767SAnurag.Maskey@Sun.COM nwam_enable(const char *parent, struct nwam_handle *hp) 502*11767SAnurag.Maskey@Sun.COM { 503*11767SAnurag.Maskey@Sun.COM return (nwam_request_action(hp->nwh_object_type, hp->nwh_name, 504*11767SAnurag.Maskey@Sun.COM parent, NWAM_ACTION_ENABLE)); 505*11767SAnurag.Maskey@Sun.COM } 506*11767SAnurag.Maskey@Sun.COM 507*11767SAnurag.Maskey@Sun.COM nwam_error_t 508*11767SAnurag.Maskey@Sun.COM nwam_disable(const char *parent, struct nwam_handle *hp) 509*11767SAnurag.Maskey@Sun.COM { 510*11767SAnurag.Maskey@Sun.COM return (nwam_request_action(hp->nwh_object_type, hp->nwh_name, 511*11767SAnurag.Maskey@Sun.COM parent, NWAM_ACTION_DISABLE)); 512*11767SAnurag.Maskey@Sun.COM } 513*11767SAnurag.Maskey@Sun.COM 514*11767SAnurag.Maskey@Sun.COM nwam_error_t 515*11767SAnurag.Maskey@Sun.COM nwam_get_state(const char *parent, struct nwam_handle *hp, nwam_state_t *statep, 516*11767SAnurag.Maskey@Sun.COM nwam_aux_state_t *auxp) 517*11767SAnurag.Maskey@Sun.COM { 518*11767SAnurag.Maskey@Sun.COM return (nwam_request_state(hp->nwh_object_type, hp->nwh_name, parent, 519*11767SAnurag.Maskey@Sun.COM statep, auxp)); 520*11767SAnurag.Maskey@Sun.COM } 521*11767SAnurag.Maskey@Sun.COM 522*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry * 523*11767SAnurag.Maskey@Sun.COM nwam_get_prop_table_entry(struct nwam_prop_table table, const char *propname) 524*11767SAnurag.Maskey@Sun.COM { 525*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *cur = table.entries; 526*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *end = cur + table.num_entries; 527*11767SAnurag.Maskey@Sun.COM 528*11767SAnurag.Maskey@Sun.COM assert(propname != NULL); 529*11767SAnurag.Maskey@Sun.COM 530*11767SAnurag.Maskey@Sun.COM for (; cur < end; cur++) { 531*11767SAnurag.Maskey@Sun.COM if (strcmp(propname, cur->prop_name) == 0) 532*11767SAnurag.Maskey@Sun.COM return (cur); 533*11767SAnurag.Maskey@Sun.COM } 534*11767SAnurag.Maskey@Sun.COM return (NULL); 535*11767SAnurag.Maskey@Sun.COM } 536*11767SAnurag.Maskey@Sun.COM 537*11767SAnurag.Maskey@Sun.COM nwam_error_t 538*11767SAnurag.Maskey@Sun.COM nwam_get_prop_description(struct nwam_prop_table table, const char *propname, 539*11767SAnurag.Maskey@Sun.COM const char **descriptionp) 540*11767SAnurag.Maskey@Sun.COM { 541*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *pte; 542*11767SAnurag.Maskey@Sun.COM 543*11767SAnurag.Maskey@Sun.COM assert(propname != NULL && descriptionp != NULL); 544*11767SAnurag.Maskey@Sun.COM 545*11767SAnurag.Maskey@Sun.COM if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL) { 546*11767SAnurag.Maskey@Sun.COM *descriptionp = NULL; 547*11767SAnurag.Maskey@Sun.COM return (NWAM_INVALID_ARG); 548*11767SAnurag.Maskey@Sun.COM } 549*11767SAnurag.Maskey@Sun.COM 550*11767SAnurag.Maskey@Sun.COM *descriptionp = dgettext(TEXT_DOMAIN, pte->prop_description); 551*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 552*11767SAnurag.Maskey@Sun.COM } 553*11767SAnurag.Maskey@Sun.COM 554*11767SAnurag.Maskey@Sun.COM nwam_error_t 555*11767SAnurag.Maskey@Sun.COM nwam_get_prop_type(struct nwam_prop_table table, const char *propname, 556*11767SAnurag.Maskey@Sun.COM nwam_value_type_t *typep) 557*11767SAnurag.Maskey@Sun.COM { 558*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *pte; 559*11767SAnurag.Maskey@Sun.COM 560*11767SAnurag.Maskey@Sun.COM assert(propname != NULL && typep != NULL); 561*11767SAnurag.Maskey@Sun.COM 562*11767SAnurag.Maskey@Sun.COM if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL) 563*11767SAnurag.Maskey@Sun.COM return (NWAM_INVALID_ARG); 564*11767SAnurag.Maskey@Sun.COM 565*11767SAnurag.Maskey@Sun.COM *typep = pte->prop_type; 566*11767SAnurag.Maskey@Sun.COM 567*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 568*11767SAnurag.Maskey@Sun.COM } 569*11767SAnurag.Maskey@Sun.COM 570*11767SAnurag.Maskey@Sun.COM nwam_error_t 571*11767SAnurag.Maskey@Sun.COM nwam_prop_multivalued(struct nwam_prop_table table, const char *propname, 572*11767SAnurag.Maskey@Sun.COM boolean_t *multip) 573*11767SAnurag.Maskey@Sun.COM { 574*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *pte; 575*11767SAnurag.Maskey@Sun.COM 576*11767SAnurag.Maskey@Sun.COM assert(propname != NULL && multip != NULL); 577*11767SAnurag.Maskey@Sun.COM 578*11767SAnurag.Maskey@Sun.COM if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL) 579*11767SAnurag.Maskey@Sun.COM return (NWAM_INVALID_ARG); 580*11767SAnurag.Maskey@Sun.COM 581*11767SAnurag.Maskey@Sun.COM if (pte->prop_max_numvalues > 1) 582*11767SAnurag.Maskey@Sun.COM *multip = B_TRUE; 583*11767SAnurag.Maskey@Sun.COM else 584*11767SAnurag.Maskey@Sun.COM *multip = B_FALSE; 585*11767SAnurag.Maskey@Sun.COM 586*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 587*11767SAnurag.Maskey@Sun.COM } 588*11767SAnurag.Maskey@Sun.COM 589*11767SAnurag.Maskey@Sun.COM nwam_error_t 590*11767SAnurag.Maskey@Sun.COM nwam_prop_read_only(struct nwam_prop_table table, const char *propname, 591*11767SAnurag.Maskey@Sun.COM boolean_t *readp) 592*11767SAnurag.Maskey@Sun.COM { 593*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *pte; 594*11767SAnurag.Maskey@Sun.COM 595*11767SAnurag.Maskey@Sun.COM assert(propname != NULL && readp != NULL); 596*11767SAnurag.Maskey@Sun.COM 597*11767SAnurag.Maskey@Sun.COM if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL) 598*11767SAnurag.Maskey@Sun.COM return (NWAM_INVALID_ARG); 599*11767SAnurag.Maskey@Sun.COM 600*11767SAnurag.Maskey@Sun.COM *readp = (pte->prop_is_readonly && !nwam_uid_is_netadm()); 601*11767SAnurag.Maskey@Sun.COM 602*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 603*11767SAnurag.Maskey@Sun.COM } 604*11767SAnurag.Maskey@Sun.COM 605*11767SAnurag.Maskey@Sun.COM /* 606*11767SAnurag.Maskey@Sun.COM * Structure used to pass in prop table and errprop string pointer to internal 607*11767SAnurag.Maskey@Sun.COM * validate function. 608*11767SAnurag.Maskey@Sun.COM */ 609*11767SAnurag.Maskey@Sun.COM struct validate_internal_arg { 610*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table table; 611*11767SAnurag.Maskey@Sun.COM const char **errpropp; 612*11767SAnurag.Maskey@Sun.COM }; 613*11767SAnurag.Maskey@Sun.COM 614*11767SAnurag.Maskey@Sun.COM /* 615*11767SAnurag.Maskey@Sun.COM * Callback used by nwam_walk_props() in nwam_validate(), and 616*11767SAnurag.Maskey@Sun.COM * by nwam_validate_prop() to determine that the number, type and 617*11767SAnurag.Maskey@Sun.COM * range of values are correct, and that validation function (if present) 618*11767SAnurag.Maskey@Sun.COM * succeeds. 619*11767SAnurag.Maskey@Sun.COM */ 620*11767SAnurag.Maskey@Sun.COM static int 621*11767SAnurag.Maskey@Sun.COM nwam_validate_prop_internal(const char *propname, nwam_value_t value, 622*11767SAnurag.Maskey@Sun.COM void *arg) 623*11767SAnurag.Maskey@Sun.COM { 624*11767SAnurag.Maskey@Sun.COM struct validate_internal_arg *via = arg; 625*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table table = via->table; 626*11767SAnurag.Maskey@Sun.COM const char **errpropp = via->errpropp; 627*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *pte; 628*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 629*11767SAnurag.Maskey@Sun.COM nwam_value_type_t type; 630*11767SAnurag.Maskey@Sun.COM uint_t numvalues; 631*11767SAnurag.Maskey@Sun.COM int i; 632*11767SAnurag.Maskey@Sun.COM 633*11767SAnurag.Maskey@Sun.COM if ((err = nwam_value_get_numvalues(value, &numvalues)) 634*11767SAnurag.Maskey@Sun.COM != NWAM_SUCCESS || 635*11767SAnurag.Maskey@Sun.COM (err = nwam_value_get_type(value, &type)) != NWAM_SUCCESS) { 636*11767SAnurag.Maskey@Sun.COM if (errpropp != NULL) 637*11767SAnurag.Maskey@Sun.COM *errpropp = propname; 638*11767SAnurag.Maskey@Sun.COM return (err); 639*11767SAnurag.Maskey@Sun.COM } 640*11767SAnurag.Maskey@Sun.COM if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL) 641*11767SAnurag.Maskey@Sun.COM return (NWAM_INVALID_ARG); 642*11767SAnurag.Maskey@Sun.COM 643*11767SAnurag.Maskey@Sun.COM /* have we get expected number of values? */ 644*11767SAnurag.Maskey@Sun.COM if (numvalues < pte->prop_min_numvalues || 645*11767SAnurag.Maskey@Sun.COM numvalues > pte->prop_max_numvalues) { 646*11767SAnurag.Maskey@Sun.COM if (errpropp != NULL) 647*11767SAnurag.Maskey@Sun.COM *errpropp = propname; 648*11767SAnurag.Maskey@Sun.COM if (numvalues < 1) 649*11767SAnurag.Maskey@Sun.COM return (NWAM_ENTITY_NO_VALUE); 650*11767SAnurag.Maskey@Sun.COM else 651*11767SAnurag.Maskey@Sun.COM return (NWAM_ENTITY_INVALID_VALUE); 652*11767SAnurag.Maskey@Sun.COM } 653*11767SAnurag.Maskey@Sun.COM /* Ensure type matches */ 654*11767SAnurag.Maskey@Sun.COM if (numvalues > 0) { 655*11767SAnurag.Maskey@Sun.COM for (i = 0; i < numvalues; i++) { 656*11767SAnurag.Maskey@Sun.COM if (pte->prop_type != type) { 657*11767SAnurag.Maskey@Sun.COM if (errpropp != NULL) 658*11767SAnurag.Maskey@Sun.COM *errpropp = propname; 659*11767SAnurag.Maskey@Sun.COM return (NWAM_ENTITY_TYPE_MISMATCH); 660*11767SAnurag.Maskey@Sun.COM 661*11767SAnurag.Maskey@Sun.COM } 662*11767SAnurag.Maskey@Sun.COM } 663*11767SAnurag.Maskey@Sun.COM } 664*11767SAnurag.Maskey@Sun.COM /* Call property-specific validation function */ 665*11767SAnurag.Maskey@Sun.COM if (pte->prop_validate != NULL) { 666*11767SAnurag.Maskey@Sun.COM err = pte->prop_validate(value); 667*11767SAnurag.Maskey@Sun.COM if (err != NWAM_SUCCESS && errpropp != NULL) 668*11767SAnurag.Maskey@Sun.COM *errpropp = propname; 669*11767SAnurag.Maskey@Sun.COM return (err); 670*11767SAnurag.Maskey@Sun.COM } 671*11767SAnurag.Maskey@Sun.COM 672*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 673*11767SAnurag.Maskey@Sun.COM } 674*11767SAnurag.Maskey@Sun.COM 675*11767SAnurag.Maskey@Sun.COM nwam_error_t 676*11767SAnurag.Maskey@Sun.COM nwam_validate_prop(struct nwam_prop_table table, struct nwam_handle *hp, 677*11767SAnurag.Maskey@Sun.COM const char *propname, nwam_value_t value) 678*11767SAnurag.Maskey@Sun.COM { 679*11767SAnurag.Maskey@Sun.COM struct validate_internal_arg via; 680*11767SAnurag.Maskey@Sun.COM 681*11767SAnurag.Maskey@Sun.COM assert(hp != NULL && propname != NULL); 682*11767SAnurag.Maskey@Sun.COM 683*11767SAnurag.Maskey@Sun.COM via.table = table; 684*11767SAnurag.Maskey@Sun.COM via.errpropp = NULL; 685*11767SAnurag.Maskey@Sun.COM 686*11767SAnurag.Maskey@Sun.COM return ((nwam_error_t)nwam_validate_prop_internal(propname, 687*11767SAnurag.Maskey@Sun.COM value, &via)); 688*11767SAnurag.Maskey@Sun.COM } 689*11767SAnurag.Maskey@Sun.COM 690*11767SAnurag.Maskey@Sun.COM nwam_error_t 691*11767SAnurag.Maskey@Sun.COM nwam_validate(struct nwam_prop_table table, struct nwam_handle *hp, 692*11767SAnurag.Maskey@Sun.COM const char **errpropp) 693*11767SAnurag.Maskey@Sun.COM { 694*11767SAnurag.Maskey@Sun.COM struct validate_internal_arg via; 695*11767SAnurag.Maskey@Sun.COM nwam_error_t err1, err2; 696*11767SAnurag.Maskey@Sun.COM 697*11767SAnurag.Maskey@Sun.COM assert(hp != NULL); 698*11767SAnurag.Maskey@Sun.COM 699*11767SAnurag.Maskey@Sun.COM via.table = table; 700*11767SAnurag.Maskey@Sun.COM via.errpropp = errpropp; 701*11767SAnurag.Maskey@Sun.COM 702*11767SAnurag.Maskey@Sun.COM err1 = nwam_walk_props(hp, nwam_validate_prop_internal, &via, 703*11767SAnurag.Maskey@Sun.COM 0, (int *)&err2); 704*11767SAnurag.Maskey@Sun.COM if (err1 != NWAM_SUCCESS) 705*11767SAnurag.Maskey@Sun.COM return (err2); 706*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 707*11767SAnurag.Maskey@Sun.COM } 708*11767SAnurag.Maskey@Sun.COM 709*11767SAnurag.Maskey@Sun.COM /* 710*11767SAnurag.Maskey@Sun.COM * Given the type and class flag representations, return the list of properties 711*11767SAnurag.Maskey@Sun.COM * that can be set for that type/class combination. Note this list is a complete 712*11767SAnurag.Maskey@Sun.COM * property list that includes both the required and the optional properties. 713*11767SAnurag.Maskey@Sun.COM * The type and class flags are only used for NCU objects at present. 714*11767SAnurag.Maskey@Sun.COM * 715*11767SAnurag.Maskey@Sun.COM * Caller needs to free prop_list. 716*11767SAnurag.Maskey@Sun.COM */ 717*11767SAnurag.Maskey@Sun.COM nwam_error_t 718*11767SAnurag.Maskey@Sun.COM nwam_get_default_proplist(struct nwam_prop_table table, 719*11767SAnurag.Maskey@Sun.COM uint64_t type, uint64_t class, const char ***prop_list, uint_t *numvalues) 720*11767SAnurag.Maskey@Sun.COM { 721*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *cur = table.entries; 722*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *end = cur + table.num_entries; 723*11767SAnurag.Maskey@Sun.COM int i = 0; 724*11767SAnurag.Maskey@Sun.COM const char **list = NULL; 725*11767SAnurag.Maskey@Sun.COM 726*11767SAnurag.Maskey@Sun.COM assert(prop_list != NULL && numvalues != NULL); 727*11767SAnurag.Maskey@Sun.COM 728*11767SAnurag.Maskey@Sun.COM /* Construct a list of all properties for required type/class */ 729*11767SAnurag.Maskey@Sun.COM list = calloc(table.num_entries, sizeof (char *)); 730*11767SAnurag.Maskey@Sun.COM if (list == NULL) { 731*11767SAnurag.Maskey@Sun.COM *prop_list = NULL; 732*11767SAnurag.Maskey@Sun.COM *numvalues = 0; 733*11767SAnurag.Maskey@Sun.COM return (NWAM_NO_MEMORY); 734*11767SAnurag.Maskey@Sun.COM } 735*11767SAnurag.Maskey@Sun.COM for (; cur < end; cur++) { 736*11767SAnurag.Maskey@Sun.COM if (((type & cur->prop_type_membership) == 0) || 737*11767SAnurag.Maskey@Sun.COM ((class & cur->prop_class_membership) == 0)) 738*11767SAnurag.Maskey@Sun.COM continue; 739*11767SAnurag.Maskey@Sun.COM list[i++] = cur->prop_name; 740*11767SAnurag.Maskey@Sun.COM } 741*11767SAnurag.Maskey@Sun.COM *numvalues = i; 742*11767SAnurag.Maskey@Sun.COM *prop_list = list; 743*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 744*11767SAnurag.Maskey@Sun.COM } 745