16ba597c5SAnurag S. Maskey /*
26ba597c5SAnurag S. Maskey  * CDDL HEADER START
36ba597c5SAnurag S. Maskey  *
46ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
56ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
66ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
76ba597c5SAnurag S. Maskey  *
86ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
106ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
116ba597c5SAnurag S. Maskey  * and limitations under the License.
126ba597c5SAnurag S. Maskey  *
136ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
146ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
166ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
176ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597c5SAnurag S. Maskey  *
196ba597c5SAnurag S. Maskey  * CDDL HEADER END
206ba597c5SAnurag S. Maskey  */
216ba597c5SAnurag S. Maskey 
226ba597c5SAnurag S. Maskey /*
236ba597c5SAnurag S. Maskey  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
246ba597c5SAnurag S. Maskey  * Use is subject to license terms.
256ba597c5SAnurag S. Maskey  */
266ba597c5SAnurag S. Maskey 
276ba597c5SAnurag S. Maskey #include <assert.h>
286ba597c5SAnurag S. Maskey #include <stdlib.h>
296ba597c5SAnurag S. Maskey #include <strings.h>
306ba597c5SAnurag S. Maskey #include <string.h>
316ba597c5SAnurag S. Maskey 
326ba597c5SAnurag S. Maskey #include "libnwam_impl.h"
336ba597c5SAnurag S. Maskey #include <libintl.h>
346ba597c5SAnurag S. Maskey #include <libnwam.h>
356ba597c5SAnurag S. Maskey 
366ba597c5SAnurag S. Maskey /*
376ba597c5SAnurag S. Maskey  * Generic object manipulation functions. Given an object handle and
386ba597c5SAnurag S. Maskey  * other parameters, create/destroy objects, walk them, walk their
396ba597c5SAnurag S. Maskey  * properties, modify/retrieve/delete properties, enable/disable them,
406ba597c5SAnurag S. Maskey  * etc. All object handles are "struct nwam_handle *" objects, sharing
416ba597c5SAnurag S. Maskey  * the same description based on the object type, name, original name
426ba597c5SAnurag S. Maskey  * (used in renaming) and associated data representing properties.
436ba597c5SAnurag S. Maskey  */
446ba597c5SAnurag S. Maskey 
456ba597c5SAnurag S. Maskey nwam_error_t
nwam_handle_create(nwam_object_type_t type,const char * name,struct nwam_handle ** hpp)466ba597c5SAnurag S. Maskey nwam_handle_create(nwam_object_type_t type, const char *name,
476ba597c5SAnurag S. Maskey     struct nwam_handle **hpp)
486ba597c5SAnurag S. Maskey {
496ba597c5SAnurag S. Maskey 
506ba597c5SAnurag S. Maskey 	assert(name != NULL && hpp != NULL);
516ba597c5SAnurag S. Maskey 
526ba597c5SAnurag S. Maskey 	if (strnlen(name, NWAM_MAX_NAME_LEN) > NWAM_MAX_NAME_LEN) {
536ba597c5SAnurag S. Maskey 		*hpp = NULL;
546ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
556ba597c5SAnurag S. Maskey 	}
566ba597c5SAnurag S. Maskey 
576ba597c5SAnurag S. Maskey 	if ((*hpp = calloc(1, sizeof (struct nwam_handle))) == NULL)
586ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
596ba597c5SAnurag S. Maskey 
606ba597c5SAnurag S. Maskey 	(*hpp)->nwh_object_type = type;
616ba597c5SAnurag S. Maskey 	(void) strlcpy((*hpp)->nwh_name, name, strlen(name) + 1);
626ba597c5SAnurag S. Maskey 	(*hpp)->nwh_committed = B_FALSE;
636ba597c5SAnurag S. Maskey 	(*hpp)->nwh_data = NULL;
646ba597c5SAnurag S. Maskey 
656ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
666ba597c5SAnurag S. Maskey }
676ba597c5SAnurag S. Maskey 
686ba597c5SAnurag S. Maskey /*
696ba597c5SAnurag S. Maskey  * Read object of specified type from dbname.
706ba597c5SAnurag S. Maskey  */
716ba597c5SAnurag S. Maskey nwam_error_t
nwam_read(nwam_object_type_t type,const char * dbname,const char * name,uint64_t flags,struct nwam_handle ** hpp)726ba597c5SAnurag S. Maskey nwam_read(nwam_object_type_t type, const char *dbname, const char *name,
736ba597c5SAnurag S. Maskey     uint64_t flags, struct nwam_handle **hpp)
746ba597c5SAnurag S. Maskey {
756ba597c5SAnurag S. Maskey 	nwam_error_t err;
766ba597c5SAnurag S. Maskey 	char dbname_copy[MAXPATHLEN];
776ba597c5SAnurag S. Maskey 
786ba597c5SAnurag S. Maskey 	assert(name != NULL && hpp != NULL);
796ba597c5SAnurag S. Maskey 
806ba597c5SAnurag S. Maskey 	if (dbname != NULL)
816ba597c5SAnurag S. Maskey 		(void) strlcpy(dbname_copy, dbname, sizeof (dbname_copy));
826ba597c5SAnurag S. Maskey 
836ba597c5SAnurag S. Maskey 	if ((err = nwam_valid_flags(flags, NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
846ba597c5SAnurag S. Maskey 		return (err);
856ba597c5SAnurag S. Maskey 	if ((err = nwam_handle_create(type, name, hpp)) != NWAM_SUCCESS)
866ba597c5SAnurag S. Maskey 		return (err);
876ba597c5SAnurag S. Maskey 
886ba597c5SAnurag S. Maskey 	if ((err = nwam_read_object_from_backend
896ba597c5SAnurag S. Maskey 	    (dbname != NULL ? dbname_copy : NULL,
906ba597c5SAnurag S. Maskey 	    type == NWAM_OBJECT_TYPE_NCP ? NULL : (*hpp)->nwh_name, flags,
916ba597c5SAnurag S. Maskey 	    &(*hpp)->nwh_data)) != NWAM_SUCCESS) {
926ba597c5SAnurag S. Maskey 		free(*hpp);
936ba597c5SAnurag S. Maskey 		*hpp = NULL;
946ba597c5SAnurag S. Maskey 		return (err);
956ba597c5SAnurag S. Maskey 	}
966ba597c5SAnurag S. Maskey 	if (type == NWAM_OBJECT_TYPE_NCP && dbname != NULL) {
976ba597c5SAnurag S. Maskey 		char *ncpname;
986ba597c5SAnurag S. Maskey 
996ba597c5SAnurag S. Maskey 		/*
1006ba597c5SAnurag S. Maskey 		 * dbname_copy may have been changed due to case-insensitive
1016ba597c5SAnurag S. Maskey 		 * match against the actual NCP configuration file.
1026ba597c5SAnurag S. Maskey 		 */
1036ba597c5SAnurag S. Maskey 		if (nwam_ncp_file_to_name(dbname_copy, &ncpname)
1046ba597c5SAnurag S. Maskey 		    == NWAM_SUCCESS) {
1056ba597c5SAnurag S. Maskey 			(void) strlcpy((*hpp)->nwh_name, ncpname,
1066ba597c5SAnurag S. Maskey 			    sizeof ((*hpp)->nwh_name));
1076ba597c5SAnurag S. Maskey 			free(ncpname);
1086ba597c5SAnurag S. Maskey 		}
1096ba597c5SAnurag S. Maskey 	}
1106ba597c5SAnurag S. Maskey 
1116ba597c5SAnurag S. Maskey 	(*hpp)->nwh_committed = B_TRUE;
1126ba597c5SAnurag S. Maskey 
1136ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1146ba597c5SAnurag S. Maskey }
1156ba597c5SAnurag S. Maskey 
1166ba597c5SAnurag S. Maskey /*
1176ba597c5SAnurag S. Maskey  * Create simply creates the handle - the object-specific function must
1186ba597c5SAnurag S. Maskey  * then fill in property values.
1196ba597c5SAnurag S. Maskey  */
1206ba597c5SAnurag S. Maskey nwam_error_t
nwam_create(nwam_object_type_t type,const char * dbname,const char * name,struct nwam_handle ** hpp)1216ba597c5SAnurag S. Maskey nwam_create(nwam_object_type_t type, const char *dbname, const char *name,
1226ba597c5SAnurag S. Maskey     struct nwam_handle **hpp)
1236ba597c5SAnurag S. Maskey {
1246ba597c5SAnurag S. Maskey 	struct nwam_handle *hp;
1256ba597c5SAnurag S. Maskey 
1266ba597c5SAnurag S. Maskey 	assert(hpp != NULL && name != NULL);
1276ba597c5SAnurag S. Maskey 
1286ba597c5SAnurag S. Maskey 	if (nwam_read(type, dbname, name, 0, &hp) == NWAM_SUCCESS) {
1296ba597c5SAnurag S. Maskey 		nwam_free(hp);
1306ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_EXISTS);
1316ba597c5SAnurag S. Maskey 	}
1326ba597c5SAnurag S. Maskey 	/* Create handle */
1336ba597c5SAnurag S. Maskey 	return (nwam_handle_create(type, name, hpp));
1346ba597c5SAnurag S. Maskey }
1356ba597c5SAnurag S. Maskey 
1366ba597c5SAnurag S. Maskey nwam_error_t
nwam_get_name(struct nwam_handle * hp,char ** namep)1376ba597c5SAnurag S. Maskey nwam_get_name(struct nwam_handle *hp, char **namep)
1386ba597c5SAnurag S. Maskey {
1396ba597c5SAnurag S. Maskey 	assert(hp != NULL && namep != NULL);
1406ba597c5SAnurag S. Maskey 
1416ba597c5SAnurag S. Maskey 	if ((*namep = strdup(hp->nwh_name)) == NULL) {
1426ba597c5SAnurag S. Maskey 		*namep = NULL;
1436ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
1446ba597c5SAnurag S. Maskey 	}
1456ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1466ba597c5SAnurag S. Maskey }
1476ba597c5SAnurag S. Maskey 
1486ba597c5SAnurag S. Maskey nwam_error_t
nwam_set_name(struct nwam_handle * hp,const char * name)1496ba597c5SAnurag S. Maskey nwam_set_name(struct nwam_handle *hp, const char *name)
1506ba597c5SAnurag S. Maskey {
1516ba597c5SAnurag S. Maskey 	assert(hp != NULL && name != NULL);
1526ba597c5SAnurag S. Maskey 
1536ba597c5SAnurag S. Maskey 	if (hp->nwh_committed)
1546ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_READ_ONLY);
1556ba597c5SAnurag S. Maskey 
1566ba597c5SAnurag S. Maskey 	if (strlen(name) >= sizeof (hp->nwh_name))
1576ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
1586ba597c5SAnurag S. Maskey 
1596ba597c5SAnurag S. Maskey 	(void) strcpy(hp->nwh_name, name);
1606ba597c5SAnurag S. Maskey 
1616ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1626ba597c5SAnurag S. Maskey }
1636ba597c5SAnurag S. Maskey 
1646ba597c5SAnurag S. Maskey /* Compare object names c1 and c2 using strcasecmp() */
1656ba597c5SAnurag S. Maskey static int
name_cmp(const void * c1,const void * c2)1666ba597c5SAnurag S. Maskey name_cmp(const void *c1, const void *c2)
1676ba597c5SAnurag S. Maskey {
1686ba597c5SAnurag S. Maskey 	nwam_ncu_type_t t1, t2;
1696ba597c5SAnurag S. Maskey 	char		*n1, *n2;
1706ba597c5SAnurag S. Maskey 
1716ba597c5SAnurag S. Maskey 	/* If c1 and c2 are typed NCU names, compare names without the types */
1726ba597c5SAnurag S. Maskey 	if (nwam_ncu_typed_name_to_name(*(const char **)c1, &t1, &n1)
1736ba597c5SAnurag S. Maskey 	    == NWAM_SUCCESS &&
1746ba597c5SAnurag S. Maskey 	    nwam_ncu_typed_name_to_name(*(const char **)c2, &t2, &n2)
1756ba597c5SAnurag S. Maskey 	    == NWAM_SUCCESS) {
1766ba597c5SAnurag S. Maskey 		int ret = strcasecmp(n1, n2);
1776ba597c5SAnurag S. Maskey 		free(n1);
1786ba597c5SAnurag S. Maskey 		free(n2);
1796ba597c5SAnurag S. Maskey 
1806ba597c5SAnurag S. Maskey 		/* For NCUs with the same name, compare their types */
1816ba597c5SAnurag S. Maskey 		if (ret == 0) {
1826ba597c5SAnurag S. Maskey 			if (t1 < t2)
1836ba597c5SAnurag S. Maskey 				ret = -1;
1846ba597c5SAnurag S. Maskey 			else if (t1 > t2)
1856ba597c5SAnurag S. Maskey 				ret = 1;
1866ba597c5SAnurag S. Maskey 		}
1876ba597c5SAnurag S. Maskey 		return (ret);
1886ba597c5SAnurag S. Maskey 	}
1896ba597c5SAnurag S. Maskey 
1906ba597c5SAnurag S. Maskey 	return (strcasecmp(*(const char **)c1, *(const char **)c2));
1916ba597c5SAnurag S. Maskey }
1926ba597c5SAnurag S. Maskey 
1936ba597c5SAnurag S. Maskey /*
1946ba597c5SAnurag S. Maskey  * Generic walk function takes the standard walk arguments, and in addition
1956ba597c5SAnurag S. Maskey  * takes a selection callback that is object-specific. If this returns
1966ba597c5SAnurag S. Maskey  * 0, the object is a valid selection for the walk and the callback is called.
1976ba597c5SAnurag S. Maskey  * Otherwise, it is skipped.
1986ba597c5SAnurag S. Maskey  */
1996ba597c5SAnurag S. Maskey nwam_error_t
nwam_walk(nwam_object_type_t type,const char * dbname,int (* cb)(struct nwam_handle *,void *),void * data,uint64_t flags,int * retp,int (* selectcb)(struct nwam_handle *,uint64_t,void *))2006ba597c5SAnurag S. Maskey nwam_walk(nwam_object_type_t type, const char *dbname,
2016ba597c5SAnurag S. Maskey     int(*cb)(struct nwam_handle *, void *),
2026ba597c5SAnurag S. Maskey     void *data, uint64_t flags, int *retp,
2036ba597c5SAnurag S. Maskey     int(*selectcb)(struct nwam_handle *, uint64_t, void *))
2046ba597c5SAnurag S. Maskey {
2056ba597c5SAnurag S. Maskey 	void *objlist;
2066ba597c5SAnurag S. Maskey 	nwam_value_t value;
2076ba597c5SAnurag S. Maskey 	char **object_names;
2086ba597c5SAnurag S. Maskey 	uint_t i, num_objects = 0;
2096ba597c5SAnurag S. Maskey 	struct nwam_handle *hp;
2106ba597c5SAnurag S. Maskey 	nwam_error_t err;
2116ba597c5SAnurag S. Maskey 	int ret = 0;
2126ba597c5SAnurag S. Maskey 
2136ba597c5SAnurag S. Maskey 	assert(cb != NULL);
2146ba597c5SAnurag S. Maskey 
2156ba597c5SAnurag S. Maskey 	/*
2166ba597c5SAnurag S. Maskey 	 * To walk a set of objects, call nwam_read_object_from_backend()
2176ba597c5SAnurag S. Maskey 	 * with a "dbname" argument set to the container db name and
2186ba597c5SAnurag S. Maskey 	 * the object name set to NULL. This returns an nvlist with one
2196ba597c5SAnurag S. Maskey 	 * member - the NWAM_OBJECT_NAMES_STRING - and the values it contains
2206ba597c5SAnurag S. Maskey 	 * represent the names of the objects.  Read each in turn, calling
2216ba597c5SAnurag S. Maskey 	 * the callback function.
2226ba597c5SAnurag S. Maskey 	 */
2236ba597c5SAnurag S. Maskey 	if ((err = nwam_read_object_from_backend((char *)dbname, NULL, flags,
2246ba597c5SAnurag S. Maskey 	    &objlist)) != NWAM_SUCCESS) {
2256ba597c5SAnurag S. Maskey 		if (err == NWAM_ENTITY_NOT_FOUND) {
2266ba597c5SAnurag S. Maskey 			/*
2276ba597c5SAnurag S. Maskey 			 * This indicates the dbname container is not present.
2286ba597c5SAnurag S. Maskey 			 * Do not pass back an error in this case, since it is
2296ba597c5SAnurag S. Maskey 			 * valid for a container not to exist.
2306ba597c5SAnurag S. Maskey 			 */
2316ba597c5SAnurag S. Maskey 			return (NWAM_SUCCESS);
2326ba597c5SAnurag S. Maskey 		}
2336ba597c5SAnurag S. Maskey 		return (err);
2346ba597c5SAnurag S. Maskey 	}
2356ba597c5SAnurag S. Maskey 
2366ba597c5SAnurag S. Maskey 	if ((err = nwam_get_prop_value(objlist, NWAM_OBJECT_NAMES_STRING,
2376ba597c5SAnurag S. Maskey 	    &value)) != NWAM_SUCCESS) {
2386ba597c5SAnurag S. Maskey 		nwam_free_object_list(objlist);
2396ba597c5SAnurag S. Maskey 		return (err);
2406ba597c5SAnurag S. Maskey 	}
2416ba597c5SAnurag S. Maskey 	err = nwam_value_get_string_array(value, &object_names, &num_objects);
2426ba597c5SAnurag S. Maskey 	nwam_free_object_list(objlist);
2436ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
2446ba597c5SAnurag S. Maskey 		nwam_value_free(value);
2456ba597c5SAnurag S. Maskey 		return (err);
2466ba597c5SAnurag S. Maskey 	}
2476ba597c5SAnurag S. Maskey 
2486ba597c5SAnurag S. Maskey 	/* sort the object names alphabetically */
2496ba597c5SAnurag S. Maskey 	qsort(object_names, num_objects, sizeof (char *), name_cmp);
2506ba597c5SAnurag S. Maskey 
2516ba597c5SAnurag S. Maskey 	for (i = 0; i < num_objects; i++) {
2526ba597c5SAnurag S. Maskey 		err = nwam_read(type, dbname, object_names[i],
2536ba597c5SAnurag S. Maskey 		    flags & NWAM_FLAG_GLOBAL_MASK, &hp);
2546ba597c5SAnurag S. Maskey 		/* An object may have disappeared.  If so, skip it. */
2556ba597c5SAnurag S. Maskey 		if (err == NWAM_ENTITY_NOT_FOUND)
2566ba597c5SAnurag S. Maskey 			continue;
2576ba597c5SAnurag S. Maskey 		if (err != NWAM_SUCCESS) {
2586ba597c5SAnurag S. Maskey 			nwam_value_free(value);
2596ba597c5SAnurag S. Maskey 			return (err);
2606ba597c5SAnurag S. Maskey 		}
2616ba597c5SAnurag S. Maskey 		if ((selectcb == NULL) || (selectcb(hp, flags, data) == 0)) {
2626ba597c5SAnurag S. Maskey 			ret = cb(hp, data);
2636ba597c5SAnurag S. Maskey 			if (ret != 0) {
2646ba597c5SAnurag S. Maskey 				nwam_free(hp);
2656ba597c5SAnurag S. Maskey 				nwam_value_free(value);
2666ba597c5SAnurag S. Maskey 				if (retp != NULL)
2676ba597c5SAnurag S. Maskey 					*retp = ret;
2686ba597c5SAnurag S. Maskey 				return (NWAM_WALK_HALTED);
2696ba597c5SAnurag S. Maskey 			}
2706ba597c5SAnurag S. Maskey 		}
2716ba597c5SAnurag S. Maskey 		nwam_free(hp);
2726ba597c5SAnurag S. Maskey 	}
2736ba597c5SAnurag S. Maskey 	nwam_value_free(value);
2746ba597c5SAnurag S. Maskey 
2756ba597c5SAnurag S. Maskey 	if (retp != NULL)
2766ba597c5SAnurag S. Maskey 		*retp = ret;
2776ba597c5SAnurag S. Maskey 	return (err);
2786ba597c5SAnurag S. Maskey }
2796ba597c5SAnurag S. Maskey 
2806ba597c5SAnurag S. Maskey void
nwam_free(struct nwam_handle * hp)2816ba597c5SAnurag S. Maskey nwam_free(struct nwam_handle *hp)
2826ba597c5SAnurag S. Maskey {
2836ba597c5SAnurag S. Maskey 	if (hp != NULL) {
2846ba597c5SAnurag S. Maskey 		if (hp->nwh_data != NULL)
2856ba597c5SAnurag S. Maskey 			nwam_free_object_list(hp->nwh_data);
2866ba597c5SAnurag S. Maskey 		free(hp);
2876ba597c5SAnurag S. Maskey 	}
2886ba597c5SAnurag S. Maskey }
2896ba597c5SAnurag S. Maskey 
2906ba597c5SAnurag S. Maskey /*
2916ba597c5SAnurag S. Maskey  * Copy object represented by oldhp to an object newname, all in container
2926ba597c5SAnurag S. Maskey  * dbname.
2936ba597c5SAnurag S. Maskey  */
2946ba597c5SAnurag S. Maskey nwam_error_t
nwam_copy(const char * dbname,struct nwam_handle * oldhp,const char * newname,struct nwam_handle ** newhpp)2956ba597c5SAnurag S. Maskey nwam_copy(const char *dbname, struct nwam_handle *oldhp, const char *newname,
2966ba597c5SAnurag S. Maskey     struct nwam_handle **newhpp)
2976ba597c5SAnurag S. Maskey {
2986ba597c5SAnurag S. Maskey 	nwam_error_t err;
2996ba597c5SAnurag S. Maskey 	struct nwam_handle *hp;
3006ba597c5SAnurag S. Maskey 
3016ba597c5SAnurag S. Maskey 	assert(oldhp != NULL && newname != NULL && newhpp != NULL);
3026ba597c5SAnurag S. Maskey 
3036ba597c5SAnurag S. Maskey 	if (nwam_read(oldhp->nwh_object_type, dbname, newname, 0, &hp)
3046ba597c5SAnurag S. Maskey 	    == NWAM_SUCCESS) {
3056ba597c5SAnurag S. Maskey 		nwam_free(hp);
3066ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_EXISTS);
3076ba597c5SAnurag S. Maskey 	}
3086ba597c5SAnurag S. Maskey 
3096ba597c5SAnurag S. Maskey 	if ((err = nwam_handle_create(oldhp->nwh_object_type, newname, newhpp))
3106ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
3116ba597c5SAnurag S. Maskey 		return (err);
3126ba597c5SAnurag S. Maskey 	if ((err = nwam_dup_object_list(oldhp->nwh_data,
3136ba597c5SAnurag S. Maskey 	    &((*newhpp)->nwh_data))) != NWAM_SUCCESS) {
3146ba597c5SAnurag S. Maskey 		nwam_free(*newhpp);
3156ba597c5SAnurag S. Maskey 		*newhpp = NULL;
3166ba597c5SAnurag S. Maskey 		return (err);
3176ba597c5SAnurag S. Maskey 	}
3186ba597c5SAnurag S. Maskey 
3196ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
3206ba597c5SAnurag S. Maskey }
3216ba597c5SAnurag S. Maskey 
3226ba597c5SAnurag S. Maskey /* ARGSUSED3 */
3236ba597c5SAnurag S. Maskey nwam_error_t
nwam_walk_props(struct nwam_handle * hp,int (* cb)(const char *,nwam_value_t,void *),void * data,uint64_t flags,int * retp)3246ba597c5SAnurag S. Maskey nwam_walk_props(struct nwam_handle *hp,
3256ba597c5SAnurag S. Maskey     int (*cb)(const char *, nwam_value_t, void *),
3266ba597c5SAnurag S. Maskey     void *data, uint64_t flags, int *retp)
3276ba597c5SAnurag S. Maskey {
3286ba597c5SAnurag S. Maskey 	char *lastpropname = NULL, *propname;
3296ba597c5SAnurag S. Maskey 	nwam_value_t value;
3306ba597c5SAnurag S. Maskey 	nwam_error_t err;
3316ba597c5SAnurag S. Maskey 	int ret = 0;
3326ba597c5SAnurag S. Maskey 
3336ba597c5SAnurag S. Maskey 	assert(hp != NULL && hp->nwh_data != NULL && cb != NULL);
3346ba597c5SAnurag S. Maskey 
3356ba597c5SAnurag S. Maskey 	if ((err = nwam_valid_flags(flags, 0)) != NWAM_SUCCESS)
3366ba597c5SAnurag S. Maskey 		return (err);
3376ba597c5SAnurag S. Maskey 	while ((err = nwam_next_object_prop(hp->nwh_data, lastpropname,
3386ba597c5SAnurag S. Maskey 	    &propname, &value)) == NWAM_SUCCESS) {
3396ba597c5SAnurag S. Maskey 
3406ba597c5SAnurag S. Maskey 		ret = cb(propname, value, data);
3416ba597c5SAnurag S. Maskey 		if (ret != 0)
3426ba597c5SAnurag S. Maskey 			err = NWAM_WALK_HALTED;
3436ba597c5SAnurag S. Maskey 
3446ba597c5SAnurag S. Maskey 		/* Free value */
3456ba597c5SAnurag S. Maskey 		nwam_value_free(value);
3466ba597c5SAnurag S. Maskey 
3476ba597c5SAnurag S. Maskey 		if (err != NWAM_SUCCESS)
3486ba597c5SAnurag S. Maskey 			break;
3496ba597c5SAnurag S. Maskey 
3506ba597c5SAnurag S. Maskey 		lastpropname = propname;
3516ba597c5SAnurag S. Maskey 	}
3526ba597c5SAnurag S. Maskey 
3536ba597c5SAnurag S. Maskey 	if (retp != NULL)
3546ba597c5SAnurag S. Maskey 		*retp = ret;
3556ba597c5SAnurag S. Maskey 	if (err == NWAM_SUCCESS || err == NWAM_LIST_END)
3566ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
3576ba597c5SAnurag S. Maskey 	return (err);
3586ba597c5SAnurag S. Maskey }
3596ba597c5SAnurag S. Maskey 
3606ba597c5SAnurag S. Maskey /*
3616ba597c5SAnurag S. Maskey  * Note that prior to calling the generic commit function, object-specific
3626ba597c5SAnurag S. Maskey  * validation should be carried out.
3636ba597c5SAnurag S. Maskey  */
3646ba597c5SAnurag S. Maskey nwam_error_t
nwam_commit(const char * dbname,struct nwam_handle * hp,uint64_t flags)3656ba597c5SAnurag S. Maskey nwam_commit(const char *dbname, struct nwam_handle *hp, uint64_t flags)
3666ba597c5SAnurag S. Maskey {
3676ba597c5SAnurag S. Maskey 	nwam_error_t err;
3686ba597c5SAnurag S. Maskey 	uint64_t iflags = flags;
3696ba597c5SAnurag S. Maskey 	boolean_t is_ncu;
3706ba597c5SAnurag S. Maskey 	struct nwam_handle *testhp;
3716ba597c5SAnurag S. Maskey 	nwam_action_t action;
3726ba597c5SAnurag S. Maskey 
3736ba597c5SAnurag S. Maskey 	assert(hp != NULL);
3746ba597c5SAnurag S. Maskey 
3756ba597c5SAnurag S. Maskey 	/*
3766ba597c5SAnurag S. Maskey 	 * NWAM_FLAG_ENTITY_KNOWN_WLAN is only used for Known WLANs and
3776ba597c5SAnurag S. Maskey 	 * NWAM_FLAG_ENTITY_ENABLE is used for other objects (during enable
3786ba597c5SAnurag S. Maskey 	 * and disable).
3796ba597c5SAnurag S. Maskey 	 */
3806ba597c5SAnurag S. Maskey 	if ((err = nwam_valid_flags(flags,
3816ba597c5SAnurag S. Maskey 	    NWAM_FLAG_BLOCKING | NWAM_FLAG_CREATE |
3826ba597c5SAnurag S. Maskey 	    (hp->nwh_object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN ?
3836ba597c5SAnurag S. Maskey 	    NWAM_FLAG_ENTITY_KNOWN_WLAN : NWAM_FLAG_ENTITY_ENABLE)))
3846ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
3856ba597c5SAnurag S. Maskey 		return (err);
3866ba597c5SAnurag S. Maskey 
3876ba597c5SAnurag S. Maskey 	is_ncu = (hp->nwh_object_type == NWAM_OBJECT_TYPE_NCU);
3886ba597c5SAnurag S. Maskey 
3896ba597c5SAnurag S. Maskey 	/*
3906ba597c5SAnurag S. Maskey 	 * Does object already exist? If not, action is ADD, otherwise REFRESH.
3916ba597c5SAnurag S. Maskey 	 */
3926ba597c5SAnurag S. Maskey 	switch (nwam_read(hp->nwh_object_type, (char *)dbname, hp->nwh_name, 0,
3936ba597c5SAnurag S. Maskey 	    &testhp)) {
3946ba597c5SAnurag S. Maskey 	case NWAM_ENTITY_NOT_FOUND:
3956ba597c5SAnurag S. Maskey 		action = NWAM_ACTION_ADD;
3966ba597c5SAnurag S. Maskey 		break;
3976ba597c5SAnurag S. Maskey 	case NWAM_SUCCESS:
3986ba597c5SAnurag S. Maskey 		nwam_free(testhp);
3996ba597c5SAnurag S. Maskey 		if (hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP)
4006ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_EXISTS);
4016ba597c5SAnurag S. Maskey 		/* FALLTHRU */
4026ba597c5SAnurag S. Maskey 	default:
4036ba597c5SAnurag S. Maskey 		action = NWAM_ACTION_REFRESH;
4046ba597c5SAnurag S. Maskey 		break;
4056ba597c5SAnurag S. Maskey 	}
4066ba597c5SAnurag S. Maskey 
4076ba597c5SAnurag S. Maskey 	err = nwam_update_object_in_backend((char *)dbname,
4086ba597c5SAnurag S. Maskey 	    hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP ? NULL : hp->nwh_name,
4096ba597c5SAnurag S. Maskey 	    iflags, hp->nwh_data);
4106ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
4116ba597c5SAnurag S. Maskey 		return (err);
4126ba597c5SAnurag S. Maskey 
4136ba597c5SAnurag S. Maskey 	hp->nwh_committed = B_TRUE;
4146ba597c5SAnurag S. Maskey 
4156ba597c5SAnurag S. Maskey 	/*
4166ba597c5SAnurag S. Maskey 	 * Tell nwamd to reread this object.  For NCUs, we need to convert
4176ba597c5SAnurag S. Maskey 	 * the dbname to the NCP name in order to pass it to nwamd.
4186ba597c5SAnurag S. Maskey 	 */
4196ba597c5SAnurag S. Maskey 	if (is_ncu) {
4206ba597c5SAnurag S. Maskey 		char *ncpname;
4216ba597c5SAnurag S. Maskey 
4226ba597c5SAnurag S. Maskey 		if (nwam_ncp_file_to_name(dbname, &ncpname) == NWAM_SUCCESS) {
4236ba597c5SAnurag S. Maskey 			(void) nwam_request_action(hp->nwh_object_type,
4246ba597c5SAnurag S. Maskey 			    hp->nwh_name, ncpname, action);
4256ba597c5SAnurag S. Maskey 			free(ncpname);
4266ba597c5SAnurag S. Maskey 		}
4276ba597c5SAnurag S. Maskey 	} else {
4286ba597c5SAnurag S. Maskey 		(void) nwam_request_action(hp->nwh_object_type, hp->nwh_name,
4296ba597c5SAnurag S. Maskey 		    NULL, action);
4306ba597c5SAnurag S. Maskey 	}
4316ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
4326ba597c5SAnurag S. Maskey }
4336ba597c5SAnurag S. Maskey 
4346ba597c5SAnurag S. Maskey static boolean_t
nwam_is_active(struct nwam_handle * hp)4356ba597c5SAnurag S. Maskey nwam_is_active(struct nwam_handle *hp)
4366ba597c5SAnurag S. Maskey {
4376ba597c5SAnurag S. Maskey 	nwam_state_t state;
4386ba597c5SAnurag S. Maskey 	nwam_aux_state_t aux;
4396ba597c5SAnurag S. Maskey 
4406ba597c5SAnurag S. Maskey 	return ((nwam_get_state(NULL, hp, &state, &aux) == NWAM_SUCCESS &&
4416ba597c5SAnurag S. Maskey 	    state == NWAM_STATE_ONLINE));
4426ba597c5SAnurag S. Maskey }
4436ba597c5SAnurag S. Maskey 
4446ba597c5SAnurag S. Maskey nwam_error_t
nwam_destroy(const char * dbname,struct nwam_handle * hp,uint64_t flags)4456ba597c5SAnurag S. Maskey nwam_destroy(const char *dbname, struct nwam_handle *hp, uint64_t flags)
4466ba597c5SAnurag S. Maskey {
4476ba597c5SAnurag S. Maskey 	nwam_error_t err;
4486ba597c5SAnurag S. Maskey 	char *name;
4496ba597c5SAnurag S. Maskey 	boolean_t is_ncp, is_ncu;
4506ba597c5SAnurag S. Maskey 
4516ba597c5SAnurag S. Maskey 	assert(hp != NULL);
4526ba597c5SAnurag S. Maskey 
4536ba597c5SAnurag S. Maskey 	/* NWAM_FLAG_ENTITY_KNOWN_WLAN is only used for Known WLANs */
4546ba597c5SAnurag S. Maskey 	if ((err = nwam_valid_flags(flags,
4556ba597c5SAnurag S. Maskey 	    NWAM_FLAG_BLOCKING | NWAM_FLAG_DO_NOT_FREE |
4566ba597c5SAnurag S. Maskey 	    (hp->nwh_object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN ?
4576ba597c5SAnurag S. Maskey 	    NWAM_FLAG_ENTITY_KNOWN_WLAN : 0))) != NWAM_SUCCESS)
4586ba597c5SAnurag S. Maskey 		return (err);
4596ba597c5SAnurag S. Maskey 
4606ba597c5SAnurag S. Maskey 	is_ncp = hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP;
4616ba597c5SAnurag S. Maskey 	is_ncu = hp->nwh_object_type == NWAM_OBJECT_TYPE_NCU;
4626ba597c5SAnurag S. Maskey 	name = hp->nwh_name;
4636ba597c5SAnurag S. Maskey 
4646ba597c5SAnurag S. Maskey 	/* Check if object is active */
4656ba597c5SAnurag S. Maskey 	if (!is_ncp && !is_ncu && nwam_is_active(hp))
4666ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_IN_USE);
4676ba597c5SAnurag S. Maskey 
4686ba597c5SAnurag S. Maskey 	/* For NCPs, just remove the dbname file, otherwise remove the object */
4696ba597c5SAnurag S. Maskey 	err = nwam_remove_object_from_backend((char *)dbname,
4706ba597c5SAnurag S. Maskey 	    is_ncp ? NULL : name, flags);
4716ba597c5SAnurag S. Maskey 
4726ba597c5SAnurag S. Maskey 	/*
4736ba597c5SAnurag S. Maskey 	 * Tell nwamd to remove this object.  For NCUs, we need to convert the
4746ba597c5SAnurag S. Maskey 	 * dbname filename to the NCP name to pass it to nwamd.
4756ba597c5SAnurag S. Maskey 	 */
4766ba597c5SAnurag S. Maskey 	if (is_ncu) {
4776ba597c5SAnurag S. Maskey 		char *ncpname;
4786ba597c5SAnurag S. Maskey 
4796ba597c5SAnurag S. Maskey 		if (nwam_ncp_file_to_name(dbname, &ncpname) == NWAM_SUCCESS) {
4806ba597c5SAnurag S. Maskey 			(void) nwam_request_action(hp->nwh_object_type, name,
4816ba597c5SAnurag S. Maskey 			    ncpname, NWAM_ACTION_DESTROY);
4826ba597c5SAnurag S. Maskey 			free(ncpname);
4836ba597c5SAnurag S. Maskey 		}
4846ba597c5SAnurag S. Maskey 	} else {
4856ba597c5SAnurag S. Maskey 		(void) nwam_request_action(hp->nwh_object_type, name, NULL,
4866ba597c5SAnurag S. Maskey 		    NWAM_ACTION_DESTROY);
4876ba597c5SAnurag S. Maskey 	}
4886ba597c5SAnurag S. Maskey 
4896ba597c5SAnurag S. Maskey 	if ((err == NWAM_SUCCESS) && !(flags & NWAM_FLAG_DO_NOT_FREE))
4906ba597c5SAnurag S. Maskey 		nwam_free(hp);
4916ba597c5SAnurag S. Maskey 
4926ba597c5SAnurag S. Maskey 	return (err);
4936ba597c5SAnurag S. Maskey }
4946ba597c5SAnurag S. Maskey 
4956ba597c5SAnurag S. Maskey /*
4966ba597c5SAnurag S. Maskey  * Enable/disable functions assume prior checking of activation mode
4976ba597c5SAnurag S. Maskey  * to ensure an enable/disable action is valid for the object. "parent" in these
4986ba597c5SAnurag S. Maskey  * functions specifies the NCP for NCUs.
4996ba597c5SAnurag S. Maskey  */
5006ba597c5SAnurag S. Maskey nwam_error_t
nwam_enable(const char * parent,struct nwam_handle * hp)5016ba597c5SAnurag S. Maskey nwam_enable(const char *parent, struct nwam_handle *hp)
5026ba597c5SAnurag S. Maskey {
5036ba597c5SAnurag S. Maskey 	return (nwam_request_action(hp->nwh_object_type, hp->nwh_name,
5046ba597c5SAnurag S. Maskey 	    parent, NWAM_ACTION_ENABLE));
5056ba597c5SAnurag S. Maskey }
5066ba597c5SAnurag S. Maskey 
5076ba597c5SAnurag S. Maskey nwam_error_t
nwam_disable(const char * parent,struct nwam_handle * hp)5086ba597c5SAnurag S. Maskey nwam_disable(const char *parent, struct nwam_handle *hp)
5096ba597c5SAnurag S. Maskey {
5106ba597c5SAnurag S. Maskey 	return (nwam_request_action(hp->nwh_object_type, hp->nwh_name,
5116ba597c5SAnurag S. Maskey 	    parent, NWAM_ACTION_DISABLE));
5126ba597c5SAnurag S. Maskey }
5136ba597c5SAnurag S. Maskey 
5146ba597c5SAnurag S. Maskey nwam_error_t
nwam_get_state(const char * parent,struct nwam_handle * hp,nwam_state_t * statep,nwam_aux_state_t * auxp)5156ba597c5SAnurag S. Maskey nwam_get_state(const char *parent, struct nwam_handle *hp, nwam_state_t *statep,
5166ba597c5SAnurag S. Maskey     nwam_aux_state_t *auxp)
5176ba597c5SAnurag S. Maskey {
5186ba597c5SAnurag S. Maskey 	return (nwam_request_state(hp->nwh_object_type, hp->nwh_name, parent,
5196ba597c5SAnurag S. Maskey 	    statep, auxp));
5206ba597c5SAnurag S. Maskey }
5216ba597c5SAnurag S. Maskey 
5226ba597c5SAnurag S. Maskey struct nwam_prop_table_entry *
nwam_get_prop_table_entry(struct nwam_prop_table table,const char * propname)5236ba597c5SAnurag S. Maskey nwam_get_prop_table_entry(struct nwam_prop_table table, const char *propname)
5246ba597c5SAnurag S. Maskey {
5256ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *cur = table.entries;
5266ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *end = cur + table.num_entries;
5276ba597c5SAnurag S. Maskey 
5286ba597c5SAnurag S. Maskey 	assert(propname != NULL);
5296ba597c5SAnurag S. Maskey 
5306ba597c5SAnurag S. Maskey 	for (; cur < end; cur++) {
5316ba597c5SAnurag S. Maskey 		if (strcmp(propname, cur->prop_name) == 0)
5326ba597c5SAnurag S. Maskey 			return (cur);
5336ba597c5SAnurag S. Maskey 	}
5346ba597c5SAnurag S. Maskey 	return (NULL);
5356ba597c5SAnurag S. Maskey }
5366ba597c5SAnurag S. Maskey 
5376ba597c5SAnurag S. Maskey nwam_error_t
nwam_get_prop_description(struct nwam_prop_table table,const char * propname,const char ** descriptionp)5386ba597c5SAnurag S. Maskey nwam_get_prop_description(struct nwam_prop_table table, const char *propname,
5396ba597c5SAnurag S. Maskey     const char **descriptionp)
5406ba597c5SAnurag S. Maskey {
5416ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *pte;
5426ba597c5SAnurag S. Maskey 
5436ba597c5SAnurag S. Maskey 	assert(propname != NULL && descriptionp != NULL);
5446ba597c5SAnurag S. Maskey 
5456ba597c5SAnurag S. Maskey 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL) {
5466ba597c5SAnurag S. Maskey 		*descriptionp = NULL;
5476ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
5486ba597c5SAnurag S. Maskey 	}
5496ba597c5SAnurag S. Maskey 
5506ba597c5SAnurag S. Maskey 	*descriptionp = dgettext(TEXT_DOMAIN, pte->prop_description);
5516ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
5526ba597c5SAnurag S. Maskey }
5536ba597c5SAnurag S. Maskey 
5546ba597c5SAnurag S. Maskey nwam_error_t
nwam_get_prop_type(struct nwam_prop_table table,const char * propname,nwam_value_type_t * typep)5556ba597c5SAnurag S. Maskey nwam_get_prop_type(struct nwam_prop_table table, const char *propname,
5566ba597c5SAnurag S. Maskey     nwam_value_type_t *typep)
5576ba597c5SAnurag S. Maskey {
5586ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *pte;
5596ba597c5SAnurag S. Maskey 
5606ba597c5SAnurag S. Maskey 	assert(propname != NULL && typep != NULL);
5616ba597c5SAnurag S. Maskey 
5626ba597c5SAnurag S. Maskey 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL)
5636ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
5646ba597c5SAnurag S. Maskey 
5656ba597c5SAnurag S. Maskey 	*typep = pte->prop_type;
5666ba597c5SAnurag S. Maskey 
5676ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
5686ba597c5SAnurag S. Maskey }
5696ba597c5SAnurag S. Maskey 
5706ba597c5SAnurag S. Maskey nwam_error_t
nwam_prop_multivalued(struct nwam_prop_table table,const char * propname,boolean_t * multip)5716ba597c5SAnurag S. Maskey nwam_prop_multivalued(struct nwam_prop_table table, const char *propname,
5726ba597c5SAnurag S. Maskey     boolean_t *multip)
5736ba597c5SAnurag S. Maskey {
5746ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *pte;
5756ba597c5SAnurag S. Maskey 
5766ba597c5SAnurag S. Maskey 	assert(propname != NULL && multip != NULL);
5776ba597c5SAnurag S. Maskey 
5786ba597c5SAnurag S. Maskey 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL)
5796ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
5806ba597c5SAnurag S. Maskey 
5816ba597c5SAnurag S. Maskey 	if (pte->prop_max_numvalues > 1)
5826ba597c5SAnurag S. Maskey 		*multip = B_TRUE;
5836ba597c5SAnurag S. Maskey 	else
5846ba597c5SAnurag S. Maskey 		*multip = B_FALSE;
5856ba597c5SAnurag S. Maskey 
5866ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
5876ba597c5SAnurag S. Maskey }
5886ba597c5SAnurag S. Maskey 
5896ba597c5SAnurag S. Maskey nwam_error_t
nwam_prop_read_only(struct nwam_prop_table table,const char * propname,boolean_t * readp)5906ba597c5SAnurag S. Maskey nwam_prop_read_only(struct nwam_prop_table table, const char *propname,
5916ba597c5SAnurag S. Maskey     boolean_t *readp)
5926ba597c5SAnurag S. Maskey {
5936ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *pte;
5946ba597c5SAnurag S. Maskey 
5956ba597c5SAnurag S. Maskey 	assert(propname != NULL && readp != NULL);
5966ba597c5SAnurag S. Maskey 
5976ba597c5SAnurag S. Maskey 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL)
5986ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
5996ba597c5SAnurag S. Maskey 
600*69b43529SMichael Hunter 	*readp = (pte->prop_is_readonly && !nwam_uid_is_special());
6016ba597c5SAnurag S. Maskey 
6026ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
6036ba597c5SAnurag S. Maskey }
6046ba597c5SAnurag S. Maskey 
6056ba597c5SAnurag S. Maskey /*
6066ba597c5SAnurag S. Maskey  * Structure used to pass in prop table and errprop string pointer to internal
6076ba597c5SAnurag S. Maskey  * validate function.
6086ba597c5SAnurag S. Maskey  */
6096ba597c5SAnurag S. Maskey struct validate_internal_arg {
6106ba597c5SAnurag S. Maskey 	struct nwam_prop_table table;
6116ba597c5SAnurag S. Maskey 	const char **errpropp;
6126ba597c5SAnurag S. Maskey };
6136ba597c5SAnurag S. Maskey 
6146ba597c5SAnurag S. Maskey /*
6156ba597c5SAnurag S. Maskey  * Callback used by nwam_walk_props() in nwam_validate(), and
6166ba597c5SAnurag S. Maskey  * by nwam_validate_prop() to determine that the number, type and
6176ba597c5SAnurag S. Maskey  * range of values are correct, and that validation function (if present)
6186ba597c5SAnurag S. Maskey  * succeeds.
6196ba597c5SAnurag S. Maskey  */
6206ba597c5SAnurag S. Maskey static int
nwam_validate_prop_internal(const char * propname,nwam_value_t value,void * arg)6216ba597c5SAnurag S. Maskey nwam_validate_prop_internal(const char *propname, nwam_value_t value,
6226ba597c5SAnurag S. Maskey     void *arg)
6236ba597c5SAnurag S. Maskey {
6246ba597c5SAnurag S. Maskey 	struct validate_internal_arg *via = arg;
6256ba597c5SAnurag S. Maskey 	struct nwam_prop_table table = via->table;
6266ba597c5SAnurag S. Maskey 	const char **errpropp = via->errpropp;
6276ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *pte;
6286ba597c5SAnurag S. Maskey 	nwam_error_t err;
6296ba597c5SAnurag S. Maskey 	nwam_value_type_t type;
6306ba597c5SAnurag S. Maskey 	uint_t numvalues;
6316ba597c5SAnurag S. Maskey 	int i;
6326ba597c5SAnurag S. Maskey 
6336ba597c5SAnurag S. Maskey 	if ((err = nwam_value_get_numvalues(value, &numvalues))
6346ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS ||
6356ba597c5SAnurag S. Maskey 	    (err = nwam_value_get_type(value, &type)) != NWAM_SUCCESS) {
6366ba597c5SAnurag S. Maskey 		if (errpropp != NULL)
6376ba597c5SAnurag S. Maskey 			*errpropp = propname;
6386ba597c5SAnurag S. Maskey 		return (err);
6396ba597c5SAnurag S. Maskey 	}
6406ba597c5SAnurag S. Maskey 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL)
6416ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
6426ba597c5SAnurag S. Maskey 
6436ba597c5SAnurag S. Maskey 	/* have we get expected number of values? */
6446ba597c5SAnurag S. Maskey 	if (numvalues < pte->prop_min_numvalues ||
6456ba597c5SAnurag S. Maskey 	    numvalues > pte->prop_max_numvalues) {
6466ba597c5SAnurag S. Maskey 		if (errpropp != NULL)
6476ba597c5SAnurag S. Maskey 			*errpropp = propname;
6486ba597c5SAnurag S. Maskey 		if (numvalues < 1)
6496ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_NO_VALUE);
6506ba597c5SAnurag S. Maskey 		else
6516ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_INVALID_VALUE);
6526ba597c5SAnurag S. Maskey 	}
6536ba597c5SAnurag S. Maskey 	/* Ensure type matches */
6546ba597c5SAnurag S. Maskey 	if (numvalues > 0) {
6556ba597c5SAnurag S. Maskey 		for (i = 0; i < numvalues; i++) {
6566ba597c5SAnurag S. Maskey 			if (pte->prop_type != type) {
6576ba597c5SAnurag S. Maskey 				if (errpropp != NULL)
6586ba597c5SAnurag S. Maskey 					*errpropp = propname;
6596ba597c5SAnurag S. Maskey 				return (NWAM_ENTITY_TYPE_MISMATCH);
6606ba597c5SAnurag S. Maskey 
6616ba597c5SAnurag S. Maskey 			}
6626ba597c5SAnurag S. Maskey 		}
6636ba597c5SAnurag S. Maskey 	}
6646ba597c5SAnurag S. Maskey 	/* Call property-specific validation function */
6656ba597c5SAnurag S. Maskey 	if (pte->prop_validate != NULL) {
6666ba597c5SAnurag S. Maskey 		err = pte->prop_validate(value);
6676ba597c5SAnurag S. Maskey 		if (err != NWAM_SUCCESS && errpropp != NULL)
6686ba597c5SAnurag S. Maskey 			*errpropp = propname;
6696ba597c5SAnurag S. Maskey 		return (err);
6706ba597c5SAnurag S. Maskey 	}
6716ba597c5SAnurag S. Maskey 
6726ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
6736ba597c5SAnurag S. Maskey }
6746ba597c5SAnurag S. Maskey 
6756ba597c5SAnurag S. Maskey nwam_error_t
nwam_validate_prop(struct nwam_prop_table table,struct nwam_handle * hp,const char * propname,nwam_value_t value)6766ba597c5SAnurag S. Maskey nwam_validate_prop(struct nwam_prop_table table, struct nwam_handle *hp,
6776ba597c5SAnurag S. Maskey     const char *propname, nwam_value_t value)
6786ba597c5SAnurag S. Maskey {
6796ba597c5SAnurag S. Maskey 	struct validate_internal_arg via;
6806ba597c5SAnurag S. Maskey 
6816ba597c5SAnurag S. Maskey 	assert(hp != NULL && propname != NULL);
6826ba597c5SAnurag S. Maskey 
6836ba597c5SAnurag S. Maskey 	via.table = table;
6846ba597c5SAnurag S. Maskey 	via.errpropp = NULL;
6856ba597c5SAnurag S. Maskey 
6866ba597c5SAnurag S. Maskey 	return ((nwam_error_t)nwam_validate_prop_internal(propname,
6876ba597c5SAnurag S. Maskey 	    value, &via));
6886ba597c5SAnurag S. Maskey }
6896ba597c5SAnurag S. Maskey 
6906ba597c5SAnurag S. Maskey nwam_error_t
nwam_validate(struct nwam_prop_table table,struct nwam_handle * hp,const char ** errpropp)6916ba597c5SAnurag S. Maskey nwam_validate(struct nwam_prop_table table, struct nwam_handle *hp,
6926ba597c5SAnurag S. Maskey     const char **errpropp)
6936ba597c5SAnurag S. Maskey {
6946ba597c5SAnurag S. Maskey 	struct validate_internal_arg via;
6956ba597c5SAnurag S. Maskey 	nwam_error_t err1, err2;
6966ba597c5SAnurag S. Maskey 
6976ba597c5SAnurag S. Maskey 	assert(hp != NULL);
6986ba597c5SAnurag S. Maskey 
6996ba597c5SAnurag S. Maskey 	via.table = table;
7006ba597c5SAnurag S. Maskey 	via.errpropp = errpropp;
7016ba597c5SAnurag S. Maskey 
7026ba597c5SAnurag S. Maskey 	err1 = nwam_walk_props(hp, nwam_validate_prop_internal, &via,
7036ba597c5SAnurag S. Maskey 	    0, (int *)&err2);
7046ba597c5SAnurag S. Maskey 	if (err1 != NWAM_SUCCESS)
7056ba597c5SAnurag S. Maskey 		return (err2);
7066ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
7076ba597c5SAnurag S. Maskey }
7086ba597c5SAnurag S. Maskey 
7096ba597c5SAnurag S. Maskey /*
7106ba597c5SAnurag S. Maskey  * Given the type and class flag representations, return the list of properties
7116ba597c5SAnurag S. Maskey  * that can be set for that type/class combination. Note this list is a complete
7126ba597c5SAnurag S. Maskey  * property list that includes both the required and the optional properties.
7136ba597c5SAnurag S. Maskey  * The type and class flags are only used for NCU objects at present.
7146ba597c5SAnurag S. Maskey  *
7156ba597c5SAnurag S. Maskey  * Caller needs to free prop_list.
7166ba597c5SAnurag S. Maskey  */
7176ba597c5SAnurag S. Maskey nwam_error_t
nwam_get_default_proplist(struct nwam_prop_table table,uint64_t type,uint64_t class,const char *** prop_list,uint_t * numvalues)7186ba597c5SAnurag S. Maskey nwam_get_default_proplist(struct nwam_prop_table table,
7196ba597c5SAnurag S. Maskey     uint64_t type, uint64_t class, const char ***prop_list, uint_t *numvalues)
7206ba597c5SAnurag S. Maskey {
7216ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *cur = table.entries;
7226ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *end = cur + table.num_entries;
7236ba597c5SAnurag S. Maskey 	int i = 0;
7246ba597c5SAnurag S. Maskey 	const char **list = NULL;
7256ba597c5SAnurag S. Maskey 
7266ba597c5SAnurag S. Maskey 	assert(prop_list != NULL && numvalues != NULL);
7276ba597c5SAnurag S. Maskey 
7286ba597c5SAnurag S. Maskey 	/* Construct a list of all properties for required type/class */
7296ba597c5SAnurag S. Maskey 	list = calloc(table.num_entries, sizeof (char *));
7306ba597c5SAnurag S. Maskey 	if (list == NULL) {
7316ba597c5SAnurag S. Maskey 		*prop_list = NULL;
7326ba597c5SAnurag S. Maskey 		*numvalues = 0;
7336ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
7346ba597c5SAnurag S. Maskey 	}
7356ba597c5SAnurag S. Maskey 	for (; cur < end; cur++) {
7366ba597c5SAnurag S. Maskey 		if (((type & cur->prop_type_membership) == 0) ||
7376ba597c5SAnurag S. Maskey 		    ((class & cur->prop_class_membership) == 0))
7386ba597c5SAnurag S. Maskey 			continue;
7396ba597c5SAnurag S. Maskey 		list[i++] = cur->prop_name;
7406ba597c5SAnurag S. Maskey 	}
7416ba597c5SAnurag S. Maskey 	*numvalues = i;
7426ba597c5SAnurag S. Maskey 	*prop_list = list;
7436ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
7446ba597c5SAnurag S. Maskey }
745