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 <dirent.h>
296ba597c5SAnurag S. Maskey #include <ctype.h>
306ba597c5SAnurag S. Maskey #include <libgen.h>
316ba597c5SAnurag S. Maskey #include <errno.h>
326ba597c5SAnurag S. Maskey #include <fcntl.h>
336ba597c5SAnurag S. Maskey #include <sys/param.h>
346ba597c5SAnurag S. Maskey #include <sys/types.h>
356ba597c5SAnurag S. Maskey #include <sys/stat.h>
366ba597c5SAnurag S. Maskey #include <stdio.h>
376ba597c5SAnurag S. Maskey #include <stdlib.h>
386ba597c5SAnurag S. Maskey #include <strings.h>
396ba597c5SAnurag S. Maskey #include <unistd.h>
406ba597c5SAnurag S. Maskey 
416ba597c5SAnurag S. Maskey #include "libnwam_impl.h"
426ba597c5SAnurag S. Maskey #include <libnwam_priv.h>
436ba597c5SAnurag S. Maskey #include <libnwam.h>
446ba597c5SAnurag S. Maskey 
456ba597c5SAnurag S. Maskey /*
466ba597c5SAnurag S. Maskey  * Implementation of files backend for libnwam configuration objects.
476ba597c5SAnurag S. Maskey  * /etc/dladm/datalink.conf-like format is used.
486ba597c5SAnurag S. Maskey  */
496ba597c5SAnurag S. Maskey #define	NWAM_FILE_LINE_MAX		2048
506ba597c5SAnurag S. Maskey #define	NWAM_FILE_PROP_ESCAPE		'\\'
516ba597c5SAnurag S. Maskey #define	NWAM_FILE_PROP_DELIMITER	';'
526ba597c5SAnurag S. Maskey #define	NWAM_FILE_PROP_ASSIGN		'='
536ba597c5SAnurag S. Maskey #define	NWAM_FILE_VALUE_DELIMITER	','
546ba597c5SAnurag S. Maskey #define	NWAM_FILE_BOOLEAN_TRUE		"true"
556ba597c5SAnurag S. Maskey #define	NWAM_FILE_BOOLEAN_FALSE		"false"
566ba597c5SAnurag S. Maskey 
576ba597c5SAnurag S. Maskey /*
586ba597c5SAnurag S. Maskey  * strtok_r-like function that takes a string, finds the next unescaped
596ba597c5SAnurag S. Maskey  * delimiter char after in, nullifies it and sets nextp to point to the
606ba597c5SAnurag S. Maskey  * remaining string (if any). Returns in, setting nextp to NULL if no such
616ba597c5SAnurag S. Maskey  * delimiter is found.
626ba597c5SAnurag S. Maskey  */
636ba597c5SAnurag S. Maskey char *
nwam_tokenize_by_unescaped_delim(char * in,char delim,char ** nextp)646ba597c5SAnurag S. Maskey nwam_tokenize_by_unescaped_delim(char *in, char delim, char **nextp)
656ba597c5SAnurag S. Maskey {
666ba597c5SAnurag S. Maskey 	boolean_t escaped = B_FALSE;
676ba597c5SAnurag S. Maskey 	size_t totlen;
686ba597c5SAnurag S. Maskey 
696ba597c5SAnurag S. Maskey 	if (in == NULL)
706ba597c5SAnurag S. Maskey 		return (NULL);
716ba597c5SAnurag S. Maskey 
726ba597c5SAnurag S. Maskey 	totlen = strlen(in);
736ba597c5SAnurag S. Maskey 
746ba597c5SAnurag S. Maskey 	for (*nextp = in; (*nextp - in) < strlen(in); (*nextp)++) {
756ba597c5SAnurag S. Maskey 		if ((*nextp)[0] == NWAM_FILE_PROP_ESCAPE) {
766ba597c5SAnurag S. Maskey 			escaped = !escaped;
776ba597c5SAnurag S. Maskey 		} else if (!escaped && (*nextp)[0] == delim) {
786ba597c5SAnurag S. Maskey 			/* Nullify delimiter */
796ba597c5SAnurag S. Maskey 			(*nextp)[0] = '\0';
806ba597c5SAnurag S. Maskey 			/*
816ba597c5SAnurag S. Maskey 			 * If more string left to go, nextp points to string
826ba597c5SAnurag S. Maskey 			 * after delimiter, otherwise NULL.
836ba597c5SAnurag S. Maskey 			 */
846ba597c5SAnurag S. Maskey 			(*nextp)++;
856ba597c5SAnurag S. Maskey 			*nextp = ((*nextp - in) < totlen) ? (*nextp) : NULL;
866ba597c5SAnurag S. Maskey 			return (in);
876ba597c5SAnurag S. Maskey 		} else {
886ba597c5SAnurag S. Maskey 			escaped = B_FALSE;
896ba597c5SAnurag S. Maskey 		}
906ba597c5SAnurag S. Maskey 	}
916ba597c5SAnurag S. Maskey 	*nextp = NULL;
926ba597c5SAnurag S. Maskey 	return (in);
936ba597c5SAnurag S. Maskey }
946ba597c5SAnurag S. Maskey 
956ba597c5SAnurag S. Maskey /* Add escape chars to value string */
966ba597c5SAnurag S. Maskey static void
value_add_escapes(char * in,char * out)976ba597c5SAnurag S. Maskey value_add_escapes(char *in, char *out)
986ba597c5SAnurag S. Maskey {
996ba597c5SAnurag S. Maskey 	int i, j = 0;
1006ba597c5SAnurag S. Maskey 
1016ba597c5SAnurag S. Maskey 	/*
1026ba597c5SAnurag S. Maskey 	 * It is safe to use strlen() as we sanitycheck string length on value
1036ba597c5SAnurag S. Maskey 	 * creation, so no string longer than NWAM_MAX_VALUE_LEN is accepted.
1046ba597c5SAnurag S. Maskey 	 */
1056ba597c5SAnurag S. Maskey 	for (i = 0; i < strlen(in); i++) {
1066ba597c5SAnurag S. Maskey 		switch (in[i]) {
1076ba597c5SAnurag S. Maskey 		case NWAM_FILE_VALUE_DELIMITER:
1086ba597c5SAnurag S. Maskey 		case NWAM_FILE_PROP_DELIMITER:
1096ba597c5SAnurag S. Maskey 		case NWAM_FILE_PROP_ESCAPE:
1106ba597c5SAnurag S. Maskey 			out[j++] = NWAM_FILE_PROP_ESCAPE;
1116ba597c5SAnurag S. Maskey 			out[j++] = in[i];
1126ba597c5SAnurag S. Maskey 			break;
1136ba597c5SAnurag S. Maskey 		default:
1146ba597c5SAnurag S. Maskey 			out[j++] = in[i];
1156ba597c5SAnurag S. Maskey 			break;
1166ba597c5SAnurag S. Maskey 		}
1176ba597c5SAnurag S. Maskey 	}
1186ba597c5SAnurag S. Maskey 	out[j] = '\0';
1196ba597c5SAnurag S. Maskey }
1206ba597c5SAnurag S. Maskey 
1216ba597c5SAnurag S. Maskey static char *
value_remove_escapes(char * in)1226ba597c5SAnurag S. Maskey value_remove_escapes(char *in)
1236ba597c5SAnurag S. Maskey {
1246ba597c5SAnurag S. Maskey 	char *out;
1256ba597c5SAnurag S. Maskey 	int i, j = 0;
1266ba597c5SAnurag S. Maskey 
1276ba597c5SAnurag S. Maskey 	if ((out = strdup(in)) == NULL)
1286ba597c5SAnurag S. Maskey 		return (NULL);
1296ba597c5SAnurag S. Maskey 
1306ba597c5SAnurag S. Maskey 	/*
1316ba597c5SAnurag S. Maskey 	 * It is safe to use strlen() as we sanitycheck string length on value
1326ba597c5SAnurag S. Maskey 	 * creation (i.e. before they are written to the file), so no string
1336ba597c5SAnurag S. Maskey 	 * longer than NWAM_MAX_VALUE_LEN is accepted.
1346ba597c5SAnurag S. Maskey 	 */
1356ba597c5SAnurag S. Maskey 	for (i = 0; i < strlen(in); i++) {
1366ba597c5SAnurag S. Maskey 		if (in[i] == NWAM_FILE_PROP_ESCAPE)
1376ba597c5SAnurag S. Maskey 			out[j++] = in[++i];
1386ba597c5SAnurag S. Maskey 		else
1396ba597c5SAnurag S. Maskey 			out[j++] = in[i];
1406ba597c5SAnurag S. Maskey 	}
1416ba597c5SAnurag S. Maskey 	out[j] = '\0';
1426ba597c5SAnurag S. Maskey 	return (out);
1436ba597c5SAnurag S. Maskey }
1446ba597c5SAnurag S. Maskey 
1456ba597c5SAnurag S. Maskey 
1466ba597c5SAnurag S. Maskey /*
1476ba597c5SAnurag S. Maskey  * Parse line into name and object list of properties.
1486ba597c5SAnurag S. Maskey  * Each line has the format:
1496ba597c5SAnurag S. Maskey  *
1506ba597c5SAnurag S. Maskey  * objname	[prop=type:val1[,val2..];..]
1516ba597c5SAnurag S. Maskey  */
1526ba597c5SAnurag S. Maskey nwam_error_t
nwam_line_to_object(char * line,char ** objname,void * proplist)1536ba597c5SAnurag S. Maskey nwam_line_to_object(char *line, char **objname, void *proplist)
1546ba597c5SAnurag S. Maskey {
1556ba597c5SAnurag S. Maskey 	char *next = line, *prop, *nextprop, *propname, *proptypestr, *nextval;
1566ba597c5SAnurag S. Maskey 	char **valstr, **newvalstr;
1576ba597c5SAnurag S. Maskey 	boolean_t *valbool, *newvalbool;
1586ba597c5SAnurag S. Maskey 	int64_t *valint, *newvalint;
1596ba597c5SAnurag S. Maskey 	uint64_t *valuint, *newvaluint;
1606ba597c5SAnurag S. Maskey 	uint_t nelem, i;
1616ba597c5SAnurag S. Maskey 	nwam_value_type_t proptype;
1626ba597c5SAnurag S. Maskey 	nwam_value_t val = NULL;
1636ba597c5SAnurag S. Maskey 	nwam_error_t err;
1646ba597c5SAnurag S. Maskey 
1656ba597c5SAnurag S. Maskey 	if ((err = nwam_alloc_object_list(proplist)) != NWAM_SUCCESS)
1666ba597c5SAnurag S. Maskey 		return (err);
1676ba597c5SAnurag S. Maskey 
1686ba597c5SAnurag S. Maskey 	*objname = line;
1696ba597c5SAnurag S. Maskey 
1706ba597c5SAnurag S. Maskey 	if ((*objname = nwam_tokenize_by_unescaped_delim(line, '\t', &prop))
1716ba597c5SAnurag S. Maskey 	    == NULL) {
1726ba597c5SAnurag S. Maskey 		nwam_free_object_list(*((char **)proplist));
1736ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
1746ba597c5SAnurag S. Maskey 	}
1756ba597c5SAnurag S. Maskey 
1766ba597c5SAnurag S. Maskey 	while ((prop = nwam_tokenize_by_unescaped_delim(prop,
1776ba597c5SAnurag S. Maskey 	    NWAM_FILE_PROP_DELIMITER, &nextprop)) != NULL) {
1786ba597c5SAnurag S. Maskey 		/*
1796ba597c5SAnurag S. Maskey 		 * Parse property into name=type,val[,val]
1806ba597c5SAnurag S. Maskey 		 */
1816ba597c5SAnurag S. Maskey 		if ((propname = nwam_tokenize_by_unescaped_delim(prop,
1826ba597c5SAnurag S. Maskey 		    NWAM_FILE_PROP_ASSIGN, &next)) == NULL ||
1836ba597c5SAnurag S. Maskey 		    (proptypestr = nwam_tokenize_by_unescaped_delim(next,
1846ba597c5SAnurag S. Maskey 		    NWAM_FILE_VALUE_DELIMITER, &next)) == NULL) {
1856ba597c5SAnurag S. Maskey 			nwam_free_object_list(*((char **)proplist));
1866ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_INVALID);
1876ba597c5SAnurag S. Maskey 		}
1886ba597c5SAnurag S. Maskey 		if ((proptype = nwam_string_to_value_type(proptypestr)) ==
1896ba597c5SAnurag S. Maskey 		    NWAM_VALUE_TYPE_UNKNOWN) {
1906ba597c5SAnurag S. Maskey 			nwam_free_object_list(*((char **)proplist));
1916ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_INVALID);
1926ba597c5SAnurag S. Maskey 		}
1936ba597c5SAnurag S. Maskey 		valbool = NULL;
1946ba597c5SAnurag S. Maskey 		valint = NULL;
1956ba597c5SAnurag S. Maskey 		valstr = NULL;
1966ba597c5SAnurag S. Maskey 		switch (proptype) {
1976ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_BOOLEAN:
1986ba597c5SAnurag S. Maskey 			valbool = calloc(NWAM_MAX_NUM_VALUES,
1996ba597c5SAnurag S. Maskey 			    sizeof (boolean_t));
2006ba597c5SAnurag S. Maskey 			break;
2016ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_INT64:
2026ba597c5SAnurag S. Maskey 			valint = calloc(NWAM_MAX_NUM_VALUES,
2036ba597c5SAnurag S. Maskey 			    sizeof (int64_t));
2046ba597c5SAnurag S. Maskey 			break;
2056ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_UINT64:
2066ba597c5SAnurag S. Maskey 			valuint = calloc(NWAM_MAX_NUM_VALUES,
2076ba597c5SAnurag S. Maskey 			    sizeof (uint64_t));
2086ba597c5SAnurag S. Maskey 			break;
2096ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_STRING:
2106ba597c5SAnurag S. Maskey 			valstr = calloc(NWAM_MAX_NUM_VALUES,
2116ba597c5SAnurag S. Maskey 			    sizeof (char *));
2126ba597c5SAnurag S. Maskey 			break;
2136ba597c5SAnurag S. Maskey 		default:
2146ba597c5SAnurag S. Maskey 			nwam_free_object_list(*((char **)proplist));
2156ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_INVALID_VALUE);
2166ba597c5SAnurag S. Maskey 		}
2176ba597c5SAnurag S. Maskey 		if (valbool == NULL && valint == NULL && valuint == NULL &&
2186ba597c5SAnurag S. Maskey 		    valstr == NULL) {
2196ba597c5SAnurag S. Maskey 			/* Memory allocation failed */
2206ba597c5SAnurag S. Maskey 			nwam_free_object_list(*((char **)proplist));
2216ba597c5SAnurag S. Maskey 			return (NWAM_NO_MEMORY);
2226ba597c5SAnurag S. Maskey 		}
2236ba597c5SAnurag S. Maskey 		nelem = 0;
2246ba597c5SAnurag S. Maskey 		while ((nextval = nwam_tokenize_by_unescaped_delim(next,
2256ba597c5SAnurag S. Maskey 		    NWAM_FILE_VALUE_DELIMITER, &next)) != NULL) {
2266ba597c5SAnurag S. Maskey 			nelem++;
2276ba597c5SAnurag S. Maskey 			switch (proptype) {
2286ba597c5SAnurag S. Maskey 			case NWAM_VALUE_TYPE_BOOLEAN:
2296ba597c5SAnurag S. Maskey 				if (strncmp(nextval, NWAM_FILE_BOOLEAN_TRUE,
2306ba597c5SAnurag S. Maskey 				    strlen(nextval)) == 0) {
2316ba597c5SAnurag S. Maskey 					valbool[nelem - 1] = B_TRUE;
2326ba597c5SAnurag S. Maskey 				} else if (strncmp(nextval,
2336ba597c5SAnurag S. Maskey 				    NWAM_FILE_BOOLEAN_FALSE, strlen(nextval))
2346ba597c5SAnurag S. Maskey 				    == 0) {
2356ba597c5SAnurag S. Maskey 					valbool[nelem - 1] = B_FALSE;
2366ba597c5SAnurag S. Maskey 				} else {
2376ba597c5SAnurag S. Maskey 					nwam_free_object_list
2386ba597c5SAnurag S. Maskey 					    (*((char **)proplist));
2396ba597c5SAnurag S. Maskey 					return (NWAM_ENTITY_INVALID_VALUE);
2406ba597c5SAnurag S. Maskey 				}
2416ba597c5SAnurag S. Maskey 				break;
2426ba597c5SAnurag S. Maskey 			case NWAM_VALUE_TYPE_INT64:
2436ba597c5SAnurag S. Maskey 				valint[nelem - 1] = (int64_t)atoll(nextval);
2446ba597c5SAnurag S. Maskey 				break;
2456ba597c5SAnurag S. Maskey 			case NWAM_VALUE_TYPE_UINT64:
2466ba597c5SAnurag S. Maskey 				valuint[nelem - 1] = (uint64_t)atoll(nextval);
2476ba597c5SAnurag S. Maskey 				break;
2486ba597c5SAnurag S. Maskey 			case NWAM_VALUE_TYPE_STRING:
2496ba597c5SAnurag S. Maskey 				valstr[nelem - 1] =
2506ba597c5SAnurag S. Maskey 				    value_remove_escapes(nextval);
2516ba597c5SAnurag S. Maskey 				break;
2526ba597c5SAnurag S. Maskey 			default:
2536ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
2546ba597c5SAnurag S. Maskey 				return (NWAM_ENTITY_INVALID_VALUE);
2556ba597c5SAnurag S. Maskey 			}
2566ba597c5SAnurag S. Maskey 		}
2576ba597c5SAnurag S. Maskey 		switch (proptype) {
2586ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_BOOLEAN:
2596ba597c5SAnurag S. Maskey 			if ((newvalbool = realloc(valbool,
2606ba597c5SAnurag S. Maskey 			    nelem * sizeof (boolean_t))) == NULL) {
2616ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
2626ba597c5SAnurag S. Maskey 				return (NWAM_NO_MEMORY);
2636ba597c5SAnurag S. Maskey 			}
2646ba597c5SAnurag S. Maskey 			if ((err = nwam_value_create_boolean_array(newvalbool,
2656ba597c5SAnurag S. Maskey 			    nelem, &val)) != NWAM_SUCCESS ||
2666ba597c5SAnurag S. Maskey 			    (err = nwam_set_prop_value(*((char **)proplist),
2676ba597c5SAnurag S. Maskey 			    propname, val)) != NWAM_SUCCESS) {
2686ba597c5SAnurag S. Maskey 				free(newvalbool);
2696ba597c5SAnurag S. Maskey 				nwam_value_free(val);
2706ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
2716ba597c5SAnurag S. Maskey 				return (err);
2726ba597c5SAnurag S. Maskey 			}
2736ba597c5SAnurag S. Maskey 			free(newvalbool);
2746ba597c5SAnurag S. Maskey 			nwam_value_free(val);
2756ba597c5SAnurag S. Maskey 			break;
2766ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_INT64:
2776ba597c5SAnurag S. Maskey 			if ((newvalint = realloc(valint,
2786ba597c5SAnurag S. Maskey 			    nelem * sizeof (int64_t))) == NULL) {
2796ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
2806ba597c5SAnurag S. Maskey 				return (NWAM_NO_MEMORY);
2816ba597c5SAnurag S. Maskey 			}
2826ba597c5SAnurag S. Maskey 			if ((err = nwam_value_create_int64_array(newvalint,
2836ba597c5SAnurag S. Maskey 			    nelem, &val)) != NWAM_SUCCESS ||
2846ba597c5SAnurag S. Maskey 			    (err = nwam_set_prop_value(*((char **)proplist),
2856ba597c5SAnurag S. Maskey 			    propname, val)) != NWAM_SUCCESS) {
2866ba597c5SAnurag S. Maskey 				free(newvalint);
2876ba597c5SAnurag S. Maskey 				nwam_value_free(val);
2886ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
2896ba597c5SAnurag S. Maskey 				return (err);
2906ba597c5SAnurag S. Maskey 			}
2916ba597c5SAnurag S. Maskey 			free(newvalint);
2926ba597c5SAnurag S. Maskey 			nwam_value_free(val);
2936ba597c5SAnurag S. Maskey 			break;
2946ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_UINT64:
2956ba597c5SAnurag S. Maskey 			if ((newvaluint = realloc(valuint,
2966ba597c5SAnurag S. Maskey 			    nelem * sizeof (uint64_t))) == NULL) {
2976ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
2986ba597c5SAnurag S. Maskey 				return (NWAM_NO_MEMORY);
2996ba597c5SAnurag S. Maskey 			}
3006ba597c5SAnurag S. Maskey 			if ((err = nwam_value_create_uint64_array(newvaluint,
3016ba597c5SAnurag S. Maskey 			    nelem, &val)) != NWAM_SUCCESS ||
3026ba597c5SAnurag S. Maskey 			    (err = nwam_set_prop_value(*((char **)proplist),
3036ba597c5SAnurag S. Maskey 			    propname, val)) != NWAM_SUCCESS) {
3046ba597c5SAnurag S. Maskey 				free(newvaluint);
3056ba597c5SAnurag S. Maskey 				nwam_value_free(val);
3066ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
3076ba597c5SAnurag S. Maskey 				return (err);
3086ba597c5SAnurag S. Maskey 			}
3096ba597c5SAnurag S. Maskey 			free(newvaluint);
3106ba597c5SAnurag S. Maskey 			nwam_value_free(val);
3116ba597c5SAnurag S. Maskey 			break;
3126ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_STRING:
3136ba597c5SAnurag S. Maskey 			if ((newvalstr = realloc(valstr,
3146ba597c5SAnurag S. Maskey 			    nelem * sizeof (char *))) == NULL) {
3156ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
3166ba597c5SAnurag S. Maskey 				return (NWAM_NO_MEMORY);
3176ba597c5SAnurag S. Maskey 			}
3186ba597c5SAnurag S. Maskey 			if ((err = nwam_value_create_string_array(newvalstr,
3196ba597c5SAnurag S. Maskey 			    nelem, &val)) != NWAM_SUCCESS ||
3206ba597c5SAnurag S. Maskey 			    (err = nwam_set_prop_value(*((char **)proplist),
3216ba597c5SAnurag S. Maskey 			    propname, val)) != NWAM_SUCCESS) {
322