xref: /onnv-gate/usr/src/lib/libnwam/common/libnwam_object.c (revision 12036:aa269fb9cf77)
111767SAnurag.Maskey@Sun.COM /*
211767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
311767SAnurag.Maskey@Sun.COM  *
411767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
511767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
611767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
711767SAnurag.Maskey@Sun.COM  *
811767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
1111767SAnurag.Maskey@Sun.COM  * and limitations under the License.
1211767SAnurag.Maskey@Sun.COM  *
1311767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811767SAnurag.Maskey@Sun.COM  *
1911767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
2011767SAnurag.Maskey@Sun.COM  */
2111767SAnurag.Maskey@Sun.COM 
2211767SAnurag.Maskey@Sun.COM /*
2311767SAnurag.Maskey@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
2411767SAnurag.Maskey@Sun.COM  * Use is subject to license terms.
2511767SAnurag.Maskey@Sun.COM  */
2611767SAnurag.Maskey@Sun.COM 
2711767SAnurag.Maskey@Sun.COM #include <assert.h>
2811767SAnurag.Maskey@Sun.COM #include <stdlib.h>
2911767SAnurag.Maskey@Sun.COM #include <strings.h>
3011767SAnurag.Maskey@Sun.COM #include <string.h>
3111767SAnurag.Maskey@Sun.COM 
3211767SAnurag.Maskey@Sun.COM #include "libnwam_impl.h"
3311767SAnurag.Maskey@Sun.COM #include <libintl.h>
3411767SAnurag.Maskey@Sun.COM #include <libnwam.h>
3511767SAnurag.Maskey@Sun.COM 
3611767SAnurag.Maskey@Sun.COM /*
3711767SAnurag.Maskey@Sun.COM  * Generic object manipulation functions. Given an object handle and
3811767SAnurag.Maskey@Sun.COM  * other parameters, create/destroy objects, walk them, walk their
3911767SAnurag.Maskey@Sun.COM  * properties, modify/retrieve/delete properties, enable/disable them,
4011767SAnurag.Maskey@Sun.COM  * etc. All object handles are "struct nwam_handle *" objects, sharing
4111767SAnurag.Maskey@Sun.COM  * the same description based on the object type, name, original name
4211767SAnurag.Maskey@Sun.COM  * (used in renaming) and associated data representing properties.
4311767SAnurag.Maskey@Sun.COM  */
4411767SAnurag.Maskey@Sun.COM 
4511767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_handle_create(nwam_object_type_t type,const char * name,struct nwam_handle ** hpp)4611767SAnurag.Maskey@Sun.COM nwam_handle_create(nwam_object_type_t type, const char *name,
4711767SAnurag.Maskey@Sun.COM     struct nwam_handle **hpp)
4811767SAnurag.Maskey@Sun.COM {
4911767SAnurag.Maskey@Sun.COM 
5011767SAnurag.Maskey@Sun.COM 	assert(name != NULL && hpp != NULL);
5111767SAnurag.Maskey@Sun.COM 
5211767SAnurag.Maskey@Sun.COM 	if (strnlen(name, NWAM_MAX_NAME_LEN) > NWAM_MAX_NAME_LEN) {
5311767SAnurag.Maskey@Sun.COM 		*hpp = NULL;
5411767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
5511767SAnurag.Maskey@Sun.COM 	}
5611767SAnurag.Maskey@Sun.COM 
5711767SAnurag.Maskey@Sun.COM 	if ((*hpp = calloc(1, sizeof (struct nwam_handle))) == NULL)
5811767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
5911767SAnurag.Maskey@Sun.COM 
6011767SAnurag.Maskey@Sun.COM 	(*hpp)->nwh_object_type = type;
6111767SAnurag.Maskey@Sun.COM 	(void) strlcpy((*hpp)->nwh_name, name, strlen(name) + 1);
6211767SAnurag.Maskey@Sun.COM 	(*hpp)->nwh_committed = B_FALSE;
6311767SAnurag.Maskey@Sun.COM 	(*hpp)->nwh_data = NULL;
6411767SAnurag.Maskey@Sun.COM 
6511767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
6611767SAnurag.Maskey@Sun.COM }
6711767SAnurag.Maskey@Sun.COM 
6811767SAnurag.Maskey@Sun.COM /*
6911767SAnurag.Maskey@Sun.COM  * Read object of specified type from dbname.
7011767SAnurag.Maskey@Sun.COM  */
7111767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_read(nwam_object_type_t type,const char * dbname,const char * name,uint64_t flags,struct nwam_handle ** hpp)7211767SAnurag.Maskey@Sun.COM nwam_read(nwam_object_type_t type, const char *dbname, const char *name,
7311767SAnurag.Maskey@Sun.COM     uint64_t flags, struct nwam_handle **hpp)
7411767SAnurag.Maskey@Sun.COM {
7511767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
7611767SAnurag.Maskey@Sun.COM 	char dbname_copy[MAXPATHLEN];
7711767SAnurag.Maskey@Sun.COM 
7811767SAnurag.Maskey@Sun.COM 	assert(name != NULL && hpp != NULL);
7911767SAnurag.Maskey@Sun.COM 
8011767SAnurag.Maskey@Sun.COM 	if (dbname != NULL)
8111767SAnurag.Maskey@Sun.COM 		(void) strlcpy(dbname_copy, dbname, sizeof (dbname_copy));
8211767SAnurag.Maskey@Sun.COM 
8311767SAnurag.Maskey@Sun.COM 	if ((err = nwam_valid_flags(flags, NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
8411767SAnurag.Maskey@Sun.COM 		return (err);
8511767SAnurag.Maskey@Sun.COM 	if ((err = nwam_handle_create(type, name, hpp)) != NWAM_SUCCESS)
8611767SAnurag.Maskey@Sun.COM 		return (err);
8711767SAnurag.Maskey@Sun.COM 
8811767SAnurag.Maskey@Sun.COM 	if ((err = nwam_read_object_from_backend
8911767SAnurag.Maskey@Sun.COM 	    (dbname != NULL ? dbname_copy : NULL,
9011767SAnurag.Maskey@Sun.COM 	    type == NWAM_OBJECT_TYPE_NCP ? NULL : (*hpp)->nwh_name, flags,
9111767SAnurag.Maskey@Sun.COM 	    &(*hpp)->nwh_data)) != NWAM_SUCCESS) {
9211767SAnurag.Maskey@Sun.COM 		free(*hpp);
9311767SAnurag.Maskey@Sun.COM 		*hpp = NULL;
9411767SAnurag.Maskey@Sun.COM 		return (err);
9511767SAnurag.Maskey@Sun.COM 	}
9611767SAnurag.Maskey@Sun.COM 	if (type == NWAM_OBJECT_TYPE_NCP && dbname != NULL) {
9711767SAnurag.Maskey@Sun.COM 		char *ncpname;
9811767SAnurag.Maskey@Sun.COM 
9911767SAnurag.Maskey@Sun.COM 		/*
10011767SAnurag.Maskey@Sun.COM 		 * dbname_copy may have been changed due to case-insensitive
10111767SAnurag.Maskey@Sun.COM 		 * match against the actual NCP configuration file.
10211767SAnurag.Maskey@Sun.COM 		 */
10311767SAnurag.Maskey@Sun.COM 		if (nwam_ncp_file_to_name(dbname_copy, &ncpname)
10411767SAnurag.Maskey@Sun.COM 		    == NWAM_SUCCESS) {
10511767SAnurag.Maskey@Sun.COM 			(void) strlcpy((*hpp)->nwh_name, ncpname,
10611767SAnurag.Maskey@Sun.COM 			    sizeof ((*hpp)->nwh_name));
10711767SAnurag.Maskey@Sun.COM 			free(ncpname);
10811767SAnurag.Maskey@Sun.COM 		}
10911767SAnurag.Maskey@Sun.COM 	}
11011767SAnurag.Maskey@Sun.COM 
11111767SAnurag.Maskey@Sun.COM 	(*hpp)->nwh_committed = B_TRUE;
11211767SAnurag.Maskey@Sun.COM 
11311767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
11411767SAnurag.Maskey@Sun.COM }
11511767SAnurag.Maskey@Sun.COM 
11611767SAnurag.Maskey@Sun.COM /*
11711767SAnurag.Maskey@Sun.COM  * Create simply creates the handle - the object-specific function must
11811767SAnurag.Maskey@Sun.COM  * then fill in property values.
11911767SAnurag.Maskey@Sun.COM  */
12011767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_create(nwam_object_type_t type,const char * dbname,const char * name,struct nwam_handle ** hpp)12111767SAnurag.Maskey@Sun.COM nwam_create(nwam_object_type_t type, const char *dbname, const char *name,
12211767SAnurag.Maskey@Sun.COM     struct nwam_handle **hpp)
12311767SAnurag.Maskey@Sun.COM {
12411767SAnurag.Maskey@Sun.COM 	struct nwam_handle *hp;
12511767SAnurag.Maskey@Sun.COM 
12611767SAnurag.Maskey@Sun.COM 	assert(hpp != NULL && name != NULL);
12711767SAnurag.Maskey@Sun.COM 
12811767SAnurag.Maskey@Sun.COM 	if (nwam_read(type, dbname, name, 0, &hp) == NWAM_SUCCESS) {
12911767SAnurag.Maskey@Sun.COM 		nwam_free(hp);
13011767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_EXISTS);
13111767SAnurag.Maskey@Sun.COM 	}
13211767SAnurag.Maskey@Sun.COM 	/* Create handle */
13311767SAnurag.Maskey@Sun.COM 	return (nwam_handle_create(type, name, hpp));
13411767SAnurag.Maskey@Sun.COM }
13511767SAnurag.Maskey@Sun.COM 
13611767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_get_name(struct nwam_handle * hp,char ** namep)13711767SAnurag.Maskey@Sun.COM nwam_get_name(struct nwam_handle *hp, char **namep)
13811767SAnurag.Maskey@Sun.COM {
13911767SAnurag.Maskey@Sun.COM 	assert(hp != NULL && namep != NULL);
14011767SAnurag.Maskey@Sun.COM 
14111767SAnurag.Maskey@Sun.COM 	if ((*namep = strdup(hp->nwh_name)) == NULL) {
14211767SAnurag.Maskey@Sun.COM 		*namep = NULL;
14311767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
14411767SAnurag.Maskey@Sun.COM 	}
14511767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
14611767SAnurag.Maskey@Sun.COM }
14711767SAnurag.Maskey@Sun.COM 
14811767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_set_name(struct nwam_handle * hp,const char * name)14911767SAnurag.Maskey@Sun.COM nwam_set_name(struct nwam_handle *hp, const char *name)
15011767SAnurag.Maskey@Sun.COM {
15111767SAnurag.Maskey@Sun.COM 	assert(hp != NULL && name != NULL);
15211767SAnurag.Maskey@Sun.COM 
15311767SAnurag.Maskey@Sun.COM 	if (hp->nwh_committed)
15411767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_READ_ONLY);
15511767SAnurag.Maskey@Sun.COM 
15611767SAnurag.Maskey@Sun.COM 	if (strlen(name) >= sizeof (hp->nwh_name))
15711767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
15811767SAnurag.Maskey@Sun.COM 
15911767SAnurag.Maskey@Sun.COM 	(void) strcpy(hp->nwh_name, name);
16011767SAnurag.Maskey@Sun.COM 
16111767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
16211767SAnurag.Maskey@Sun.COM }
16311767SAnurag.Maskey@Sun.COM 
16411767SAnurag.Maskey@Sun.COM /* Compare object names c1 and c2 using strcasecmp() */
16511767SAnurag.Maskey@Sun.COM static int
name_cmp(const void * c1,const void * c2)16611767SAnurag.Maskey@Sun.COM name_cmp(const void *c1, const void *c2)
16711767SAnurag.Maskey@Sun.COM {
16811767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t t1, t2;
16911767SAnurag.Maskey@Sun.COM 	char		*n1, *n2;
17011767SAnurag.Maskey@Sun.COM 
17111767SAnurag.Maskey@Sun.COM 	/* If c1 and c2 are typed NCU names, compare names without the types */
17211767SAnurag.Maskey@Sun.COM 	if (nwam_ncu_typed_name_to_name(*(const char **)c1, &t1, &n1)
17311767SAnurag.Maskey@Sun.COM 	    == NWAM_SUCCESS &&
17411767SAnurag.Maskey@Sun.COM 	    nwam_ncu_typed_name_to_name(*(const char **)c2, &t2, &n2)
17511767SAnurag.Maskey@Sun.COM 	    == NWAM_SUCCESS) {
17611767SAnurag.Maskey@Sun.COM 		int ret = strcasecmp(n1, n2);
17711767SAnurag.Maskey@Sun.COM 		free(n1);
17811767SAnurag.Maskey@Sun.COM 		free(n2);
17911767SAnurag.Maskey@Sun.COM 
18011767SAnurag.Maskey@Sun.COM 		/* For NCUs with the same name, compare their types */
18111767SAnurag.Maskey@Sun.COM 		if (ret == 0) {
18211767SAnurag.Maskey@Sun.COM 			if (t1 < t2)
18311767SAnurag.Maskey@Sun.COM 				ret = -1;
18411767SAnurag.Maskey@Sun.COM 			else if (t1 > t2)
18511767SAnurag.Maskey@Sun.COM 				ret = 1;
18611767SAnurag.Maskey@Sun.COM 		}
18711767SAnurag.Maskey@Sun.COM 		return (ret);
18811767SAnurag.Maskey@Sun.COM 	}
18911767SAnurag.Maskey@Sun.COM 
19011767SAnurag.Maskey@Sun.COM 	return (strcasecmp(*(const char **)c1, *(const char **)c2));
19111767SAnurag.Maskey@Sun.COM }
19211767SAnurag.Maskey@Sun.COM 
19311767SAnurag.Maskey@Sun.COM /*
19411767SAnurag.Maskey@Sun.COM  * Generic walk function takes the standard walk arguments, and in addition
19511767SAnurag.Maskey@Sun.COM  * takes a selection callback that is object-specific. If this returns
19611767SAnurag.Maskey@Sun.COM  * 0, the object is a valid selection for the walk and the callback is called.
19711767SAnurag.Maskey@Sun.COM  * Otherwise, it is skipped.
19811767SAnurag.Maskey@Sun.COM  */
19911767SAnurag.Maskey@Sun.COM 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 *))20011767SAnurag.Maskey@Sun.COM nwam_walk(nwam_object_type_t type, const char *dbname,
20111767SAnurag.Maskey@Sun.COM     int(*cb)(struct nwam_handle *, void *),
20211767SAnurag.Maskey@Sun.COM     void *data, uint64_t flags, int *retp,
20311767SAnurag.Maskey@Sun.COM     int(*selectcb)(struct nwam_handle *, uint64_t, void *))
20411767SAnurag.Maskey@Sun.COM {
20511767SAnurag.Maskey@Sun.COM 	void *objlist;
20611767SAnurag.Maskey@Sun.COM 	nwam_value_t value;
20711767SAnurag.Maskey@Sun.COM 	char **object_names;
20811767SAnurag.Maskey@Sun.COM 	uint_t i, num_objects = 0;
20911767SAnurag.Maskey@Sun.COM 	struct nwam_handle *hp;
21011767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
21111767SAnurag.Maskey@Sun.COM 	int ret = 0;
21211767SAnurag.Maskey@Sun.COM 
21311767SAnurag.Maskey@Sun.COM 	assert(cb != NULL);
21411767SAnurag.Maskey@Sun.COM 
21511767SAnurag.Maskey@Sun.COM 	/*
21611767SAnurag.Maskey@Sun.COM 	 * To walk a set of objects, call nwam_read_object_from_backend()
21711767SAnurag.Maskey@Sun.COM 	 * with a "dbname" argument set to the container db name and
21811767SAnurag.Maskey@Sun.COM 	 * the object name set to NULL. This returns an nvlist with one
21911767SAnurag.Maskey@Sun.COM 	 * member - the NWAM_OBJECT_NAMES_STRING - and the values it contains
22011767SAnurag.Maskey@Sun.COM 	 * represent the names of the objects.  Read each in turn, calling
22111767SAnurag.Maskey@Sun.COM 	 * the callback function.
22211767SAnurag.Maskey@Sun.COM 	 */
22311767SAnurag.Maskey@Sun.COM 	if ((err = nwam_read_object_from_backend((char *)dbname, NULL, flags,
22411767SAnurag.Maskey@Sun.COM 	    &objlist)) != NWAM_SUCCESS) {
22511767SAnurag.Maskey@Sun.COM 		if (err == NWAM_ENTITY_NOT_FOUND) {
22611767SAnurag.Maskey@Sun.COM 			/*
22711767SAnurag.Maskey@Sun.COM 			 * This indicates the dbname container is not present.
22811767SAnurag.Maskey@Sun.COM 			 * Do not pass back an error in this case, since it is
22911767SAnurag.Maskey@Sun.COM 			 * valid for a container not to exist.
23011767SAnurag.Maskey@Sun.COM 			 */
23111767SAnurag.Maskey@Sun.COM 			return (NWAM_SUCCESS);
23211767SAnurag.Maskey@Sun.COM 		}
23311767SAnurag.Maskey@Sun.COM 		return (err);
23411767SAnurag.Maskey@Sun.COM 	}
23511767SAnurag.Maskey@Sun.COM 
23611767SAnurag.Maskey@Sun.COM 	if ((err = nwam_get_prop_value(objlist, NWAM_OBJECT_NAMES_STRING,
23711767SAnurag.Maskey@Sun.COM 	    &value)) != NWAM_SUCCESS) {
23811767SAnurag.Maskey@Sun.COM 		nwam_free_object_list(objlist);
23911767SAnurag.Maskey@Sun.COM 		return (err);
24011767SAnurag.Maskey@Sun.COM 	}
24111767SAnurag.Maskey@Sun.COM 	err = nwam_value_get_string_array(value, &object_names, &num_objects);
24211767SAnurag.Maskey@Sun.COM 	nwam_free_object_list(objlist);
24311767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS) {
24411767SAnurag.Maskey@Sun.COM 		nwam_value_free(value);
24511767SAnurag.Maskey@Sun.COM 		return (err);
24611767SAnurag.Maskey@Sun.COM 	}
24711767SAnurag.Maskey@Sun.COM 
24811767SAnurag.Maskey@Sun.COM 	/* sort the object names alphabetically */
24911767SAnurag.Maskey@Sun.COM 	qsort(object_names, num_objects, sizeof (char *), name_cmp);
25011767SAnurag.Maskey@Sun.COM 
25111767SAnurag.Maskey@Sun.COM 	for (i = 0; i < num_objects; i++) {
25211767SAnurag.Maskey@Sun.COM 		err = nwam_read(type, dbname, object_names[i],
25311767SAnurag.Maskey@Sun.COM 		    flags & NWAM_FLAG_GLOBAL_MASK, &hp);
25411767SAnurag.Maskey@Sun.COM 		/* An object may have disappeared.  If so, skip it. */
25511767SAnurag.Maskey@Sun.COM 		if (err == NWAM_ENTITY_NOT_FOUND)
25611767SAnurag.Maskey@Sun.COM 			continue;
25711767SAnurag.Maskey@Sun.COM 		if (err != NWAM_SUCCESS) {
25811767SAnurag.Maskey@Sun.COM 			nwam_value_free(value);
25911767SAnurag.Maskey@Sun.COM 			return (err);
26011767SAnurag.Maskey@Sun.COM 		}
26111767SAnurag.Maskey@Sun.COM 		if ((selectcb == NULL) || (selectcb(hp, flags, data) == 0)) {
26211767SAnurag.Maskey@Sun.COM 			ret = cb(hp, data);
26311767SAnurag.Maskey@Sun.COM 			if (ret != 0) {
26411767SAnurag.Maskey@Sun.COM 				nwam_free(hp);
26511767SAnurag.Maskey@Sun.COM 				nwam_value_free(value);
26611767SAnurag.Maskey@Sun.COM 				if (retp != NULL)
26711767SAnurag.Maskey@Sun.COM 					*retp = ret;
26811767SAnurag.Maskey@Sun.COM 				return (NWAM_WALK_HALTED);
26911767SAnurag.Maskey@Sun.COM 			}
27011767SAnurag.Maskey@Sun.COM 		}
27111767SAnurag.Maskey@Sun.COM 		nwam_free(hp);
27211767SAnurag.Maskey@Sun.COM 	}
27311767SAnurag.Maskey@Sun.COM 	nwam_value_free(value);
27411767SAnurag.Maskey@Sun.COM 
27511767SAnurag.Maskey@Sun.COM 	if (retp != NULL)
27611767SAnurag.Maskey@Sun.COM 		*retp = ret;
27711767SAnurag.Maskey@Sun.COM 	return (err);
27811767SAnurag.Maskey@Sun.COM }
27911767SAnurag.Maskey@Sun.COM 
28011767SAnurag.Maskey@Sun.COM void
nwam_free(struct nwam_handle * hp)28111767SAnurag.Maskey@Sun.COM nwam_free(struct nwam_handle *hp)
28211767SAnurag.Maskey@Sun.COM {
28311767SAnurag.Maskey@Sun.COM 	if (hp != NULL) {
28411767SAnurag.Maskey@Sun.COM 		if (hp->nwh_data != NULL)
28511767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(hp->nwh_data);
28611767SAnurag.Maskey@Sun.COM 		free(hp);
28711767SAnurag.Maskey@Sun.COM 	}
28811767SAnurag.Maskey@Sun.COM }
28911767SAnurag.Maskey@Sun.COM 
29011767SAnurag.Maskey@Sun.COM /*
29111767SAnurag.Maskey@Sun.COM  * Copy object represented by oldhp to an object newname, all in container
29211767SAnurag.Maskey@Sun.COM  * dbname.
29311767SAnurag.Maskey@Sun.COM  */
29411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_copy(const char * dbname,struct nwam_handle * oldhp,const char * newname,struct nwam_handle ** newhpp)29511767SAnurag.Maskey@Sun.COM nwam_copy(const char *dbname, struct nwam_handle *oldhp, const char *newname,
29611767SAnurag.Maskey@Sun.COM     struct nwam_handle **newhpp)
29711767SAnurag.Maskey@Sun.COM {
29811767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
29911767SAnurag.Maskey@Sun.COM 	struct nwam_handle *hp;
30011767SAnurag.Maskey@Sun.COM 
30111767SAnurag.Maskey@Sun.COM 	assert(oldhp != NULL && newname != NULL && newhpp != NULL);
30211767SAnurag.Maskey@Sun.COM 
30311767SAnurag.Maskey@Sun.COM 	if (nwam_read(oldhp->nwh_object_type, dbname, newname, 0, &hp)
30411767SAnurag.Maskey@Sun.COM 	    == NWAM_SUCCESS) {
30511767SAnurag.Maskey@Sun.COM 		nwam_free(hp);
30611767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_EXISTS);
30711767SAnurag.Maskey@Sun.COM 	}
30811767SAnurag.Maskey@Sun.COM 
30911767SAnurag.Maskey@Sun.COM 	if ((err = nwam_handle_create(oldhp->nwh_object_type, newname, newhpp))
31011767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
31111767SAnurag.Maskey@Sun.COM 		return (err);
31211767SAnurag.Maskey@Sun.COM 	if ((err = nwam_dup_object_list(oldhp->nwh_data,
31311767SAnurag.Maskey@Sun.COM 	    &((*newhpp)->nwh_data))) != NWAM_SUCCESS) {
31411767SAnurag.Maskey@Sun.COM 		nwam_free(*newhpp);
31511767SAnurag.Maskey@Sun.COM 		*newhpp = NULL;
31611767SAnurag.Maskey@Sun.COM 		return (err);
31711767SAnurag.Maskey@Sun.COM 	}
31811767SAnurag.Maskey@Sun.COM 
31911767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
32011767SAnurag.Maskey@Sun.COM }
32111767SAnurag.Maskey@Sun.COM 
32211767SAnurag.Maskey@Sun.COM /* ARGSUSED3 */
32311767SAnurag.Maskey@Sun.COM 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)32411767SAnurag.Maskey@Sun.COM nwam_walk_props(struct nwam_handle *hp,
32511767SAnurag.Maskey@Sun.COM     int (*cb)(const char *, nwam_value_t, void *),
32611767SAnurag.Maskey@Sun.COM     void *data, uint64_t flags, int *retp)
32711767SAnurag.Maskey@Sun.COM {
32811767SAnurag.Maskey@Sun.COM 	char *lastpropname = NULL, *propname;
32911767SAnurag.Maskey@Sun.COM 	nwam_value_t value;
33011767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
33111767SAnurag.Maskey@Sun.COM 	int ret = 0;
33211767SAnurag.Maskey@Sun.COM 
33311767SAnurag.Maskey@Sun.COM 	assert(hp != NULL && hp->nwh_data != NULL && cb != NULL);
33411767SAnurag.Maskey@Sun.COM 
33511767SAnurag.Maskey@Sun.COM 	if ((err = nwam_valid_flags(flags, 0)) != NWAM_SUCCESS)
33611767SAnurag.Maskey@Sun.COM 		return (err);
33711767SAnurag.Maskey@Sun.COM 	while ((err = nwam_next_object_prop(hp->nwh_data, lastpropname,
33811767SAnurag.Maskey@Sun.COM 	    &propname, &value)) == NWAM_SUCCESS) {
33911767SAnurag.Maskey@Sun.COM 
34011767SAnurag.Maskey@Sun.COM 		ret = cb(propname, value, data);
34111767SAnurag.Maskey@Sun.COM 		if (ret != 0)
34211767SAnurag.Maskey@Sun.COM 			err = NWAM_WALK_HALTED;
34311767SAnurag.Maskey@Sun.COM 
34411767SAnurag.Maskey@Sun.COM 		/* Free value */
34511767SAnurag.Maskey@Sun.COM 		nwam_value_free(value);
34611767SAnurag.Maskey@Sun.COM 
34711767SAnurag.Maskey@Sun.COM 		if (err != NWAM_SUCCESS)
34811767SAnurag.Maskey@Sun.COM 			break;
34911767SAnurag.Maskey@Sun.COM 
35011767SAnurag.Maskey@Sun.COM 		lastpropname = propname;
35111767SAnurag.Maskey@Sun.COM 	}
35211767SAnurag.Maskey@Sun.COM 
35311767SAnurag.Maskey@Sun.COM 	if (retp != NULL)
35411767SAnurag.Maskey@Sun.COM 		*retp = ret;
35511767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS || err == NWAM_LIST_END)
35611767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
35711767SAnurag.Maskey@Sun.COM 	return (err);
35811767SAnurag.Maskey@Sun.COM }
35911767SAnurag.Maskey@Sun.COM 
36011767SAnurag.Maskey@Sun.COM /*
36111767SAnurag.Maskey@Sun.COM  * Note that prior to calling the generic commit function, object-specific
36211767SAnurag.Maskey@Sun.COM  * validation should be carried out.
36311767SAnurag.Maskey@Sun.COM  */
36411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_commit(const char * dbname,struct nwam_handle * hp,uint64_t flags)36511767SAnurag.Maskey@Sun.COM nwam_commit(const char *dbname, struct nwam_handle *hp, uint64_t flags)
36611767SAnurag.Maskey@Sun.COM {
36711767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
36811767SAnurag.Maskey@Sun.COM 	uint64_t iflags = flags;
36911767SAnurag.Maskey@Sun.COM 	boolean_t is_ncu;
37011767SAnurag.Maskey@Sun.COM 	struct nwam_handle *testhp;
37111767SAnurag.Maskey@Sun.COM 	nwam_action_t action;
37211767SAnurag.Maskey@Sun.COM 
37311767SAnurag.Maskey@Sun.COM 	assert(hp != NULL);
37411767SAnurag.Maskey@Sun.COM 
37511767SAnurag.Maskey@Sun.COM 	/*
37611767SAnurag.Maskey@Sun.COM 	 * NWAM_FLAG_ENTITY_KNOWN_WLAN is only used for Known WLANs and
37711767SAnurag.Maskey@Sun.COM 	 * NWAM_FLAG_ENTITY_ENABLE is used for other objects (during enable
37811767SAnurag.Maskey@Sun.COM 	 * and disable).
37911767SAnurag.Maskey@Sun.COM 	 */
38011767SAnurag.Maskey@Sun.COM 	if ((err = nwam_valid_flags(flags,
38111767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_BLOCKING | NWAM_FLAG_CREATE |
38211767SAnurag.Maskey@Sun.COM 	    (hp->nwh_object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN ?
38311767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_ENTITY_KNOWN_WLAN : NWAM_FLAG_ENTITY_ENABLE)))
38411767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
38511767SAnurag.Maskey@Sun.COM 		return (err);
38611767SAnurag.Maskey@Sun.COM 
38711767SAnurag.Maskey@Sun.COM 	is_ncu = (hp->nwh_object_type == NWAM_OBJECT_TYPE_NCU);
38811767SAnurag.Maskey@Sun.COM 
38911767SAnurag.Maskey@Sun.COM 	/*
39011767SAnurag.Maskey@Sun.COM 	 * Does object already exist? If not, action is ADD, otherwise REFRESH.
39111767SAnurag.Maskey@Sun.COM 	 */
39211767SAnurag.Maskey@Sun.COM 	switch (nwam_read(hp->nwh_object_type, (char *)dbname, hp->nwh_name, 0,
39311767SAnurag.Maskey@Sun.COM 	    &testhp)) {
39411767SAnurag.Maskey@Sun.COM 	case NWAM_ENTITY_NOT_FOUND:
39511767SAnurag.Maskey@Sun.COM 		action = NWAM_ACTION_ADD;
39611767SAnurag.Maskey@Sun.COM 		break;
39711767SAnurag.Maskey@Sun.COM 	case NWAM_SUCCESS:
39811767SAnurag.Maskey@Sun.COM 		nwam_free(testhp);
39911767SAnurag.Maskey@Sun.COM 		if (hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP)
40011767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_EXISTS);
40111767SAnurag.Maskey@Sun.COM 		/* FALLTHRU */
40211767SAnurag.Maskey@Sun.COM 	default:
40311767SAnurag.Maskey@Sun.COM 		action = NWAM_ACTION_REFRESH;
40411767SAnurag.Maskey@Sun.COM 		break;
40511767SAnurag.Maskey@Sun.COM 	}
40611767SAnurag.Maskey@Sun.COM 
40711767SAnurag.Maskey@Sun.COM 	err = nwam_update_object_in_backend((char *)dbname,
40811767SAnurag.Maskey@Sun.COM 	    hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP ? NULL : hp->nwh_name,
40911767SAnurag.Maskey@Sun.COM 	    iflags, hp->nwh_data);
41011767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
41111767SAnurag.Maskey@Sun.COM 		return (err);
41211767SAnurag.Maskey@Sun.COM 
41311767SAnurag.Maskey@Sun.COM 	hp->nwh_committed = B_TRUE;
41411767SAnurag.Maskey@Sun.COM 
41511767SAnurag.Maskey@Sun.COM 	/*
41611767SAnurag.Maskey@Sun.COM 	 * Tell nwamd to reread this object.  For NCUs, we need to convert
41711767SAnurag.Maskey@Sun.COM 	 * the dbname to the NCP name in order to pass it to nwamd.
41811767SAnurag.Maskey@Sun.COM 	 */
41911767SAnurag.Maskey@Sun.COM 	if (is_ncu) {
42011767SAnurag.Maskey@Sun.COM 		char *ncpname;
42111767SAnurag.Maskey@Sun.COM 
42211767SAnurag.Maskey@Sun.COM 		if (nwam_ncp_file_to_name(dbname, &ncpname) == NWAM_SUCCESS) {
42311767SAnurag.Maskey@Sun.COM 			(void) nwam_request_action(hp->nwh_object_type,
42411767SAnurag.Maskey@Sun.COM 			    hp->nwh_name, ncpname, action);
42511767SAnurag.Maskey@Sun.COM 			free(ncpname);
42611767SAnurag.Maskey@Sun.COM 		}
42711767SAnurag.Maskey@Sun.COM 	} else {
42811767SAnurag.Maskey@Sun.COM 		(void) nwam_request_action(hp->nwh_object_type, hp->nwh_name,
42911767SAnurag.Maskey@Sun.COM 		    NULL, action);
43011767SAnurag.Maskey@Sun.COM 	}
43111767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
43211767SAnurag.Maskey@Sun.COM }
43311767SAnurag.Maskey@Sun.COM 
43411767SAnurag.Maskey@Sun.COM static boolean_t
nwam_is_active(struct nwam_handle * hp)43511767SAnurag.Maskey@Sun.COM nwam_is_active(struct nwam_handle *hp)
43611767SAnurag.Maskey@Sun.COM {
43711767SAnurag.Maskey@Sun.COM 	nwam_state_t state;
43811767SAnurag.Maskey@Sun.COM 	nwam_aux_state_t aux;
43911767SAnurag.Maskey@Sun.COM 
44011767SAnurag.Maskey@Sun.COM 	return ((nwam_get_state(NULL, hp, &state, &aux) == NWAM_SUCCESS &&
44111767SAnurag.Maskey@Sun.COM 	    state == NWAM_STATE_ONLINE));
44211767SAnurag.Maskey@Sun.COM }
44311767SAnurag.Maskey@Sun.COM 
44411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_destroy(const char * dbname,struct nwam_handle * hp,uint64_t flags)44511767SAnurag.Maskey@Sun.COM nwam_destroy(const char *dbname, struct nwam_handle *hp, uint64_t flags)
44611767SAnurag.Maskey@Sun.COM {
44711767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
44811767SAnurag.Maskey@Sun.COM 	char *name;
44911767SAnurag.Maskey@Sun.COM 	boolean_t is_ncp, is_ncu;
45011767SAnurag.Maskey@Sun.COM 
45111767SAnurag.Maskey@Sun.COM 	assert(hp != NULL);
45211767SAnurag.Maskey@Sun.COM 
45311767SAnurag.Maskey@Sun.COM 	/* NWAM_FLAG_ENTITY_KNOWN_WLAN is only used for Known WLANs */
45411767SAnurag.Maskey@Sun.COM 	if ((err = nwam_valid_flags(flags,
45511767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_BLOCKING | NWAM_FLAG_DO_NOT_FREE |
45611767SAnurag.Maskey@Sun.COM 	    (hp->nwh_object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN ?
45711767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_ENTITY_KNOWN_WLAN : 0))) != NWAM_SUCCESS)
45811767SAnurag.Maskey@Sun.COM 		return (err);
45911767SAnurag.Maskey@Sun.COM 
46011767SAnurag.Maskey@Sun.COM 	is_ncp = hp->nwh_object_type == NWAM_OBJECT_TYPE_NCP;
46111767SAnurag.Maskey@Sun.COM 	is_ncu = hp->nwh_object_type == NWAM_OBJECT_TYPE_NCU;
46211767SAnurag.Maskey@Sun.COM 	name = hp->nwh_name;
46311767SAnurag.Maskey@Sun.COM 
46411767SAnurag.Maskey@Sun.COM 	/* Check if object is active */
46511767SAnurag.Maskey@Sun.COM 	if (!is_ncp && !is_ncu && nwam_is_active(hp))
46611767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_IN_USE);
46711767SAnurag.Maskey@Sun.COM 
46811767SAnurag.Maskey@Sun.COM 	/* For NCPs, just remove the dbname file, otherwise remove the object */
46911767SAnurag.Maskey@Sun.COM 	err = nwam_remove_object_from_backend((char *)dbname,
47011767SAnurag.Maskey@Sun.COM 	    is_ncp ? NULL : name, flags);
47111767SAnurag.Maskey@Sun.COM 
47211767SAnurag.Maskey@Sun.COM 	/*
47311767SAnurag.Maskey@Sun.COM 	 * Tell nwamd to remove this object.  For NCUs, we need to convert the
47411767SAnurag.Maskey@Sun.COM 	 * dbname filename to the NCP name to pass it to nwamd.
47511767SAnurag.Maskey@Sun.COM 	 */
47611767SAnurag.Maskey@Sun.COM 	if (is_ncu) {
47711767SAnurag.Maskey@Sun.COM 		char *ncpname;
47811767SAnurag.Maskey@Sun.COM 
47911767SAnurag.Maskey@Sun.COM 		if (nwam_ncp_file_to_name(dbname, &ncpname) == NWAM_SUCCESS) {
48011767SAnurag.Maskey@Sun.COM 			(void) nwam_request_action(hp->nwh_object_type, name,
48111767SAnurag.Maskey@Sun.COM 			    ncpname, NWAM_ACTION_DESTROY);
48211767SAnurag.Maskey@Sun.COM 			free(ncpname);
48311767SAnurag.Maskey@Sun.COM 		}
48411767SAnurag.Maskey@Sun.COM 	} else {
48511767SAnurag.Maskey@Sun.COM 		(void) nwam_request_action(hp->nwh_object_type, name, NULL,
48611767SAnurag.Maskey@Sun.COM 		    NWAM_ACTION_DESTROY);
48711767SAnurag.Maskey@Sun.COM 	}
48811767SAnurag.Maskey@Sun.COM 
48911767SAnurag.Maskey@Sun.COM 	if ((err == NWAM_SUCCESS) && !(flags & NWAM_FLAG_DO_NOT_FREE))
49011767SAnurag.Maskey@Sun.COM 		nwam_free(hp);
49111767SAnurag.Maskey@Sun.COM 
49211767SAnurag.Maskey@Sun.COM 	return (err);
49311767SAnurag.Maskey@Sun.COM }
49411767SAnurag.Maskey@Sun.COM 
49511767SAnurag.Maskey@Sun.COM /*
49611767SAnurag.Maskey@Sun.COM  * Enable/disable functions assume prior checking of activation mode
49711767SAnurag.Maskey@Sun.COM  * to ensure an enable/disable action is valid for the object. "parent" in these
49811767SAnurag.Maskey@Sun.COM  * functions specifies the NCP for NCUs.
49911767SAnurag.Maskey@Sun.COM  */
50011767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_enable(const char * parent,struct nwam_handle * hp)50111767SAnurag.Maskey@Sun.COM nwam_enable(const char *parent, struct nwam_handle *hp)
50211767SAnurag.Maskey@Sun.COM {
50311767SAnurag.Maskey@Sun.COM 	return (nwam_request_action(hp->nwh_object_type, hp->nwh_name,
50411767SAnurag.Maskey@Sun.COM 	    parent, NWAM_ACTION_ENABLE));
50511767SAnurag.Maskey@Sun.COM }
50611767SAnurag.Maskey@Sun.COM 
50711767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_disable(const char * parent,struct nwam_handle * hp)50811767SAnurag.Maskey@Sun.COM nwam_disable(const char *parent, struct nwam_handle *hp)
50911767SAnurag.Maskey@Sun.COM {
51011767SAnurag.Maskey@Sun.COM 	return (nwam_request_action(hp->nwh_object_type, hp->nwh_name,
51111767SAnurag.Maskey@Sun.COM 	    parent, NWAM_ACTION_DISABLE));
51211767SAnurag.Maskey@Sun.COM }
51311767SAnurag.Maskey@Sun.COM 
51411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_get_state(const char * parent,struct nwam_handle * hp,nwam_state_t * statep,nwam_aux_state_t * auxp)51511767SAnurag.Maskey@Sun.COM nwam_get_state(const char *parent, struct nwam_handle *hp, nwam_state_t *statep,
51611767SAnurag.Maskey@Sun.COM     nwam_aux_state_t *auxp)
51711767SAnurag.Maskey@Sun.COM {
51811767SAnurag.Maskey@Sun.COM 	return (nwam_request_state(hp->nwh_object_type, hp->nwh_name, parent,
51911767SAnurag.Maskey@Sun.COM 	    statep, auxp));
52011767SAnurag.Maskey@Sun.COM }
52111767SAnurag.Maskey@Sun.COM 
52211767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry *
nwam_get_prop_table_entry(struct nwam_prop_table table,const char * propname)52311767SAnurag.Maskey@Sun.COM nwam_get_prop_table_entry(struct nwam_prop_table table, const char *propname)
52411767SAnurag.Maskey@Sun.COM {
52511767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *cur = table.entries;
52611767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *end = cur + table.num_entries;
52711767SAnurag.Maskey@Sun.COM 
52811767SAnurag.Maskey@Sun.COM 	assert(propname != NULL);
52911767SAnurag.Maskey@Sun.COM 
53011767SAnurag.Maskey@Sun.COM 	for (; cur < end; cur++) {
53111767SAnurag.Maskey@Sun.COM 		if (strcmp(propname, cur->prop_name) == 0)
53211767SAnurag.Maskey@Sun.COM 			return (cur);
53311767SAnurag.Maskey@Sun.COM 	}
53411767SAnurag.Maskey@Sun.COM 	return (NULL);
53511767SAnurag.Maskey@Sun.COM }
53611767SAnurag.Maskey@Sun.COM 
53711767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_get_prop_description(struct nwam_prop_table table,const char * propname,const char ** descriptionp)53811767SAnurag.Maskey@Sun.COM nwam_get_prop_description(struct nwam_prop_table table, const char *propname,
53911767SAnurag.Maskey@Sun.COM     const char **descriptionp)
54011767SAnurag.Maskey@Sun.COM {
54111767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *pte;
54211767SAnurag.Maskey@Sun.COM 
54311767SAnurag.Maskey@Sun.COM 	assert(propname != NULL && descriptionp != NULL);
54411767SAnurag.Maskey@Sun.COM 
54511767SAnurag.Maskey@Sun.COM 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL) {
54611767SAnurag.Maskey@Sun.COM 		*descriptionp = NULL;
54711767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
54811767SAnurag.Maskey@Sun.COM 	}
54911767SAnurag.Maskey@Sun.COM 
55011767SAnurag.Maskey@Sun.COM 	*descriptionp = dgettext(TEXT_DOMAIN, pte->prop_description);
55111767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
55211767SAnurag.Maskey@Sun.COM }
55311767SAnurag.Maskey@Sun.COM 
55411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_get_prop_type(struct nwam_prop_table table,const char * propname,nwam_value_type_t * typep)55511767SAnurag.Maskey@Sun.COM nwam_get_prop_type(struct nwam_prop_table table, const char *propname,
55611767SAnurag.Maskey@Sun.COM     nwam_value_type_t *typep)
55711767SAnurag.Maskey@Sun.COM {
55811767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *pte;
55911767SAnurag.Maskey@Sun.COM 
56011767SAnurag.Maskey@Sun.COM 	assert(propname != NULL && typep != NULL);
56111767SAnurag.Maskey@Sun.COM 
56211767SAnurag.Maskey@Sun.COM 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL)
56311767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
56411767SAnurag.Maskey@Sun.COM 
56511767SAnurag.Maskey@Sun.COM 	*typep = pte->prop_type;
56611767SAnurag.Maskey@Sun.COM 
56711767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
56811767SAnurag.Maskey@Sun.COM }
56911767SAnurag.Maskey@Sun.COM 
57011767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_prop_multivalued(struct nwam_prop_table table,const char * propname,boolean_t * multip)57111767SAnurag.Maskey@Sun.COM nwam_prop_multivalued(struct nwam_prop_table table, const char *propname,
57211767SAnurag.Maskey@Sun.COM     boolean_t *multip)
57311767SAnurag.Maskey@Sun.COM {
57411767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *pte;
57511767SAnurag.Maskey@Sun.COM 
57611767SAnurag.Maskey@Sun.COM 	assert(propname != NULL && multip != NULL);
57711767SAnurag.Maskey@Sun.COM 
57811767SAnurag.Maskey@Sun.COM 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL)
57911767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
58011767SAnurag.Maskey@Sun.COM 
58111767SAnurag.Maskey@Sun.COM 	if (pte->prop_max_numvalues > 1)
58211767SAnurag.Maskey@Sun.COM 		*multip = B_TRUE;
58311767SAnurag.Maskey@Sun.COM 	else
58411767SAnurag.Maskey@Sun.COM 		*multip = B_FALSE;
58511767SAnurag.Maskey@Sun.COM 
58611767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
58711767SAnurag.Maskey@Sun.COM }
58811767SAnurag.Maskey@Sun.COM 
58911767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_prop_read_only(struct nwam_prop_table table,const char * propname,boolean_t * readp)59011767SAnurag.Maskey@Sun.COM nwam_prop_read_only(struct nwam_prop_table table, const char *propname,
59111767SAnurag.Maskey@Sun.COM     boolean_t *readp)
59211767SAnurag.Maskey@Sun.COM {
59311767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *pte;
59411767SAnurag.Maskey@Sun.COM 
59511767SAnurag.Maskey@Sun.COM 	assert(propname != NULL && readp != NULL);
59611767SAnurag.Maskey@Sun.COM 
59711767SAnurag.Maskey@Sun.COM 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL)
59811767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
59911767SAnurag.Maskey@Sun.COM 
600*12036SMichael.Hunter@Sun.COM 	*readp = (pte->prop_is_readonly && !nwam_uid_is_special());
60111767SAnurag.Maskey@Sun.COM 
60211767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
60311767SAnurag.Maskey@Sun.COM }
60411767SAnurag.Maskey@Sun.COM 
60511767SAnurag.Maskey@Sun.COM /*
60611767SAnurag.Maskey@Sun.COM  * Structure used to pass in prop table and errprop string pointer to internal
60711767SAnurag.Maskey@Sun.COM  * validate function.
60811767SAnurag.Maskey@Sun.COM  */
60911767SAnurag.Maskey@Sun.COM struct validate_internal_arg {
61011767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table table;
61111767SAnurag.Maskey@Sun.COM 	const char **errpropp;
61211767SAnurag.Maskey@Sun.COM };
61311767SAnurag.Maskey@Sun.COM 
61411767SAnurag.Maskey@Sun.COM /*
61511767SAnurag.Maskey@Sun.COM  * Callback used by nwam_walk_props() in nwam_validate(), and
61611767SAnurag.Maskey@Sun.COM  * by nwam_validate_prop() to determine that the number, type and
61711767SAnurag.Maskey@Sun.COM  * range of values are correct, and that validation function (if present)
61811767SAnurag.Maskey@Sun.COM  * succeeds.
61911767SAnurag.Maskey@Sun.COM  */
62011767SAnurag.Maskey@Sun.COM static int
nwam_validate_prop_internal(const char * propname,nwam_value_t value,void * arg)62111767SAnurag.Maskey@Sun.COM nwam_validate_prop_internal(const char *propname, nwam_value_t value,
62211767SAnurag.Maskey@Sun.COM     void *arg)
62311767SAnurag.Maskey@Sun.COM {
62411767SAnurag.Maskey@Sun.COM 	struct validate_internal_arg *via = arg;
62511767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table table = via->table;
62611767SAnurag.Maskey@Sun.COM 	const char **errpropp = via->errpropp;
62711767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *pte;
62811767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
62911767SAnurag.Maskey@Sun.COM 	nwam_value_type_t type;
63011767SAnurag.Maskey@Sun.COM 	uint_t numvalues;
63111767SAnurag.Maskey@Sun.COM 	int i;
63211767SAnurag.Maskey@Sun.COM 
63311767SAnurag.Maskey@Sun.COM 	if ((err = nwam_value_get_numvalues(value, &numvalues))
63411767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS ||
63511767SAnurag.Maskey@Sun.COM 	    (err = nwam_value_get_type(value, &type)) != NWAM_SUCCESS) {
63611767SAnurag.Maskey@Sun.COM 		if (errpropp != NULL)
63711767SAnurag.Maskey@Sun.COM 			*errpropp = propname;
63811767SAnurag.Maskey@Sun.COM 		return (err);
63911767SAnurag.Maskey@Sun.COM 	}
64011767SAnurag.Maskey@Sun.COM 	if ((pte = nwam_get_prop_table_entry(table, propname)) == NULL)
64111767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
64211767SAnurag.Maskey@Sun.COM 
64311767SAnurag.Maskey@Sun.COM 	/* have we get expected number of values? */
64411767SAnurag.Maskey@Sun.COM 	if (numvalues < pte->prop_min_numvalues ||
64511767SAnurag.Maskey@Sun.COM 	    numvalues > pte->prop_max_numvalues) {
64611767SAnurag.Maskey@Sun.COM 		if (errpropp != NULL)
64711767SAnurag.Maskey@Sun.COM 			*errpropp = propname;
64811767SAnurag.Maskey@Sun.COM 		if (numvalues < 1)
64911767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_NO_VALUE);
65011767SAnurag.Maskey@Sun.COM 		else
65111767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
65211767SAnurag.Maskey@Sun.COM 	}
65311767SAnurag.Maskey@Sun.COM 	/* Ensure type matches */
65411767SAnurag.Maskey@Sun.COM 	if (numvalues > 0) {
65511767SAnurag.Maskey@Sun.COM 		for (i = 0; i < numvalues; i++) {
65611767SAnurag.Maskey@Sun.COM 			if (pte->prop_type != type) {
65711767SAnurag.Maskey@Sun.COM 				if (errpropp != NULL)
65811767SAnurag.Maskey@Sun.COM 					*errpropp = propname;
65911767SAnurag.Maskey@Sun.COM 				return (NWAM_ENTITY_TYPE_MISMATCH);
66011767SAnurag.Maskey@Sun.COM 
66111767SAnurag.Maskey@Sun.COM 			}
66211767SAnurag.Maskey@Sun.COM 		}
66311767SAnurag.Maskey@Sun.COM 	}
66411767SAnurag.Maskey@Sun.COM 	/* Call property-specific validation function */
66511767SAnurag.Maskey@Sun.COM 	if (pte->prop_validate != NULL) {
66611767SAnurag.Maskey@Sun.COM 		err = pte->prop_validate(value);
66711767SAnurag.Maskey@Sun.COM 		if (err != NWAM_SUCCESS && errpropp != NULL)
66811767SAnurag.Maskey@Sun.COM 			*errpropp = propname;
66911767SAnurag.Maskey@Sun.COM 		return (err);
67011767SAnurag.Maskey@Sun.COM 	}
67111767SAnurag.Maskey@Sun.COM 
67211767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
67311767SAnurag.Maskey@Sun.COM }
67411767SAnurag.Maskey@Sun.COM 
67511767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_validate_prop(struct nwam_prop_table table,struct nwam_handle * hp,const char * propname,nwam_value_t value)67611767SAnurag.Maskey@Sun.COM nwam_validate_prop(struct nwam_prop_table table, struct nwam_handle *hp,
67711767SAnurag.Maskey@Sun.COM     const char *propname, nwam_value_t value)
67811767SAnurag.Maskey@Sun.COM {
67911767SAnurag.Maskey@Sun.COM 	struct validate_internal_arg via;
68011767SAnurag.Maskey@Sun.COM 
68111767SAnurag.Maskey@Sun.COM 	assert(hp != NULL && propname != NULL);
68211767SAnurag.Maskey@Sun.COM 
68311767SAnurag.Maskey@Sun.COM 	via.table = table;
68411767SAnurag.Maskey@Sun.COM 	via.errpropp = NULL;
68511767SAnurag.Maskey@Sun.COM 
68611767SAnurag.Maskey@Sun.COM 	return ((nwam_error_t)nwam_validate_prop_internal(propname,
68711767SAnurag.Maskey@Sun.COM 	    value, &via));
68811767SAnurag.Maskey@Sun.COM }
68911767SAnurag.Maskey@Sun.COM 
69011767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_validate(struct nwam_prop_table table,struct nwam_handle * hp,const char ** errpropp)69111767SAnurag.Maskey@Sun.COM nwam_validate(struct nwam_prop_table table, struct nwam_handle *hp,
69211767SAnurag.Maskey@Sun.COM     const char **errpropp)
69311767SAnurag.Maskey@Sun.COM {
69411767SAnurag.Maskey@Sun.COM 	struct validate_internal_arg via;
69511767SAnurag.Maskey@Sun.COM 	nwam_error_t err1, err2;
69611767SAnurag.Maskey@Sun.COM 
69711767SAnurag.Maskey@Sun.COM 	assert(hp != NULL);
69811767SAnurag.Maskey@Sun.COM 
69911767SAnurag.Maskey@Sun.COM 	via.table = table;
70011767SAnurag.Maskey@Sun.COM 	via.errpropp = errpropp;
70111767SAnurag.Maskey@Sun.COM 
70211767SAnurag.Maskey@Sun.COM 	err1 = nwam_walk_props(hp, nwam_validate_prop_internal, &via,
70311767SAnurag.Maskey@Sun.COM 	    0, (int *)&err2);
70411767SAnurag.Maskey@Sun.COM 	if (err1 != NWAM_SUCCESS)
70511767SAnurag.Maskey@Sun.COM 		return (err2);
70611767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
70711767SAnurag.Maskey@Sun.COM }
70811767SAnurag.Maskey@Sun.COM 
70911767SAnurag.Maskey@Sun.COM /*
71011767SAnurag.Maskey@Sun.COM  * Given the type and class flag representations, return the list of properties
71111767SAnurag.Maskey@Sun.COM  * that can be set for that type/class combination. Note this list is a complete
71211767SAnurag.Maskey@Sun.COM  * property list that includes both the required and the optional properties.
71311767SAnurag.Maskey@Sun.COM  * The type and class flags are only used for NCU objects at present.
71411767SAnurag.Maskey@Sun.COM  *
71511767SAnurag.Maskey@Sun.COM  * Caller needs to free prop_list.
71611767SAnurag.Maskey@Sun.COM  */
71711767SAnurag.Maskey@Sun.COM 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)71811767SAnurag.Maskey@Sun.COM nwam_get_default_proplist(struct nwam_prop_table table,
71911767SAnurag.Maskey@Sun.COM     uint64_t type, uint64_t class, const char ***prop_list, uint_t *numvalues)
72011767SAnurag.Maskey@Sun.COM {
72111767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *cur = table.entries;
72211767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *end = cur + table.num_entries;
72311767SAnurag.Maskey@Sun.COM 	int i = 0;
72411767SAnurag.Maskey@Sun.COM 	const char **list = NULL;
72511767SAnurag.Maskey@Sun.COM 
72611767SAnurag.Maskey@Sun.COM 	assert(prop_list != NULL && numvalues != NULL);
72711767SAnurag.Maskey@Sun.COM 
72811767SAnurag.Maskey@Sun.COM 	/* Construct a list of all properties for required type/class */
72911767SAnurag.Maskey@Sun.COM 	list = calloc(table.num_entries, sizeof (char *));
73011767SAnurag.Maskey@Sun.COM 	if (list == NULL) {
73111767SAnurag.Maskey@Sun.COM 		*prop_list = NULL;
73211767SAnurag.Maskey@Sun.COM 		*numvalues = 0;
73311767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
73411767SAnurag.Maskey@Sun.COM 	}
73511767SAnurag.Maskey@Sun.COM 	for (; cur < end; cur++) {
73611767SAnurag.Maskey@Sun.COM 		if (((type & cur->prop_type_membership) == 0) ||
73711767SAnurag.Maskey@Sun.COM 		    ((class & cur->prop_class_membership) == 0))
73811767SAnurag.Maskey@Sun.COM 			continue;
73911767SAnurag.Maskey@Sun.COM 		list[i++] = cur->prop_name;
74011767SAnurag.Maskey@Sun.COM 	}
74111767SAnurag.Maskey@Sun.COM 	*numvalues = i;
74211767SAnurag.Maskey@Sun.COM 	*prop_list = list;
74311767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
74411767SAnurag.Maskey@Sun.COM }
745