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