xref: /onnv-gate/usr/src/lib/libnwam/common/libnwam_files.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 <dirent.h>
2911767SAnurag.Maskey@Sun.COM #include <ctype.h>
3011767SAnurag.Maskey@Sun.COM #include <libgen.h>
3111767SAnurag.Maskey@Sun.COM #include <errno.h>
3211767SAnurag.Maskey@Sun.COM #include <fcntl.h>
3311767SAnurag.Maskey@Sun.COM #include <sys/param.h>
3411767SAnurag.Maskey@Sun.COM #include <sys/types.h>
3511767SAnurag.Maskey@Sun.COM #include <sys/stat.h>
3611767SAnurag.Maskey@Sun.COM #include <stdio.h>
3711767SAnurag.Maskey@Sun.COM #include <stdlib.h>
3811767SAnurag.Maskey@Sun.COM #include <strings.h>
3911767SAnurag.Maskey@Sun.COM #include <unistd.h>
4011767SAnurag.Maskey@Sun.COM 
4111767SAnurag.Maskey@Sun.COM #include "libnwam_impl.h"
4211767SAnurag.Maskey@Sun.COM #include <libnwam_priv.h>
4311767SAnurag.Maskey@Sun.COM #include <libnwam.h>
4411767SAnurag.Maskey@Sun.COM 
4511767SAnurag.Maskey@Sun.COM /*
4611767SAnurag.Maskey@Sun.COM  * Implementation of files backend for libnwam configuration objects.
4711767SAnurag.Maskey@Sun.COM  * /etc/dladm/datalink.conf-like format is used.
4811767SAnurag.Maskey@Sun.COM  */
4911767SAnurag.Maskey@Sun.COM #define	NWAM_FILE_LINE_MAX		2048
5011767SAnurag.Maskey@Sun.COM #define	NWAM_FILE_PROP_ESCAPE		'\\'
5111767SAnurag.Maskey@Sun.COM #define	NWAM_FILE_PROP_DELIMITER	';'
5211767SAnurag.Maskey@Sun.COM #define	NWAM_FILE_PROP_ASSIGN		'='
5311767SAnurag.Maskey@Sun.COM #define	NWAM_FILE_VALUE_DELIMITER	','
5411767SAnurag.Maskey@Sun.COM #define	NWAM_FILE_BOOLEAN_TRUE		"true"
5511767SAnurag.Maskey@Sun.COM #define	NWAM_FILE_BOOLEAN_FALSE		"false"
5611767SAnurag.Maskey@Sun.COM 
5711767SAnurag.Maskey@Sun.COM /*
5811767SAnurag.Maskey@Sun.COM  * strtok_r-like function that takes a string, finds the next unescaped
5911767SAnurag.Maskey@Sun.COM  * delimiter char after in, nullifies it and sets nextp to point to the
6011767SAnurag.Maskey@Sun.COM  * remaining string (if any). Returns in, setting nextp to NULL if no such
6111767SAnurag.Maskey@Sun.COM  * delimiter is found.
6211767SAnurag.Maskey@Sun.COM  */
6311767SAnurag.Maskey@Sun.COM char *
nwam_tokenize_by_unescaped_delim(char * in,char delim,char ** nextp)6411767SAnurag.Maskey@Sun.COM nwam_tokenize_by_unescaped_delim(char *in, char delim, char **nextp)
6511767SAnurag.Maskey@Sun.COM {
6611767SAnurag.Maskey@Sun.COM 	boolean_t escaped = B_FALSE;
6711767SAnurag.Maskey@Sun.COM 	size_t totlen;
6811767SAnurag.Maskey@Sun.COM 
6911767SAnurag.Maskey@Sun.COM 	if (in == NULL)
7011767SAnurag.Maskey@Sun.COM 		return (NULL);
7111767SAnurag.Maskey@Sun.COM 
7211767SAnurag.Maskey@Sun.COM 	totlen = strlen(in);
7311767SAnurag.Maskey@Sun.COM 
7411767SAnurag.Maskey@Sun.COM 	for (*nextp = in; (*nextp - in) < strlen(in); (*nextp)++) {
7511767SAnurag.Maskey@Sun.COM 		if ((*nextp)[0] == NWAM_FILE_PROP_ESCAPE) {
7611767SAnurag.Maskey@Sun.COM 			escaped = !escaped;
7711767SAnurag.Maskey@Sun.COM 		} else if (!escaped && (*nextp)[0] == delim) {
7811767SAnurag.Maskey@Sun.COM 			/* Nullify delimiter */
7911767SAnurag.Maskey@Sun.COM 			(*nextp)[0] = '\0';
8011767SAnurag.Maskey@Sun.COM 			/*
8111767SAnurag.Maskey@Sun.COM 			 * If more string left to go, nextp points to string
8211767SAnurag.Maskey@Sun.COM 			 * after delimiter, otherwise NULL.
8311767SAnurag.Maskey@Sun.COM 			 */
8411767SAnurag.Maskey@Sun.COM 			(*nextp)++;
8511767SAnurag.Maskey@Sun.COM 			*nextp = ((*nextp - in) < totlen) ? (*nextp) : NULL;
8611767SAnurag.Maskey@Sun.COM 			return (in);
8711767SAnurag.Maskey@Sun.COM 		} else {
8811767SAnurag.Maskey@Sun.COM 			escaped = B_FALSE;
8911767SAnurag.Maskey@Sun.COM 		}
9011767SAnurag.Maskey@Sun.COM 	}
9111767SAnurag.Maskey@Sun.COM 	*nextp = NULL;
9211767SAnurag.Maskey@Sun.COM 	return (in);
9311767SAnurag.Maskey@Sun.COM }
9411767SAnurag.Maskey@Sun.COM 
9511767SAnurag.Maskey@Sun.COM /* Add escape chars to value string */
9611767SAnurag.Maskey@Sun.COM static void
value_add_escapes(char * in,char * out)9711767SAnurag.Maskey@Sun.COM value_add_escapes(char *in, char *out)
9811767SAnurag.Maskey@Sun.COM {
9911767SAnurag.Maskey@Sun.COM 	int i, j = 0;
10011767SAnurag.Maskey@Sun.COM 
10111767SAnurag.Maskey@Sun.COM 	/*
10211767SAnurag.Maskey@Sun.COM 	 * It is safe to use strlen() as we sanitycheck string length on value
10311767SAnurag.Maskey@Sun.COM 	 * creation, so no string longer than NWAM_MAX_VALUE_LEN is accepted.
10411767SAnurag.Maskey@Sun.COM 	 */
10511767SAnurag.Maskey@Sun.COM 	for (i = 0; i < strlen(in); i++) {
10611767SAnurag.Maskey@Sun.COM 		switch (in[i]) {
10711767SAnurag.Maskey@Sun.COM 		case NWAM_FILE_VALUE_DELIMITER:
10811767SAnurag.Maskey@Sun.COM 		case NWAM_FILE_PROP_DELIMITER:
10911767SAnurag.Maskey@Sun.COM 		case NWAM_FILE_PROP_ESCAPE:
11011767SAnurag.Maskey@Sun.COM 			out[j++] = NWAM_FILE_PROP_ESCAPE;
11111767SAnurag.Maskey@Sun.COM 			out[j++] = in[i];
11211767SAnurag.Maskey@Sun.COM 			break;
11311767SAnurag.Maskey@Sun.COM 		default:
11411767SAnurag.Maskey@Sun.COM 			out[j++] = in[i];
11511767SAnurag.Maskey@Sun.COM 			break;
11611767SAnurag.Maskey@Sun.COM 		}
11711767SAnurag.Maskey@Sun.COM 	}
11811767SAnurag.Maskey@Sun.COM 	out[j] = '\0';
11911767SAnurag.Maskey@Sun.COM }
12011767SAnurag.Maskey@Sun.COM 
12111767SAnurag.Maskey@Sun.COM static char *
value_remove_escapes(char * in)12211767SAnurag.Maskey@Sun.COM value_remove_escapes(char *in)
12311767SAnurag.Maskey@Sun.COM {
12411767SAnurag.Maskey@Sun.COM 	char *out;
12511767SAnurag.Maskey@Sun.COM 	int i, j = 0;
12611767SAnurag.Maskey@Sun.COM 
12711767SAnurag.Maskey@Sun.COM 	if ((out = strdup(in)) == NULL)
12811767SAnurag.Maskey@Sun.COM 		return (NULL);
12911767SAnurag.Maskey@Sun.COM 
13011767SAnurag.Maskey@Sun.COM 	/*
13111767SAnurag.Maskey@Sun.COM 	 * It is safe to use strlen() as we sanitycheck string length on value
13211767SAnurag.Maskey@Sun.COM 	 * creation (i.e. before they are written to the file), so no string
13311767SAnurag.Maskey@Sun.COM 	 * longer than NWAM_MAX_VALUE_LEN is accepted.
13411767SAnurag.Maskey@Sun.COM 	 */
13511767SAnurag.Maskey@Sun.COM 	for (i = 0; i < strlen(in); i++) {
13611767SAnurag.Maskey@Sun.COM 		if (in[i] == NWAM_FILE_PROP_ESCAPE)
13711767SAnurag.Maskey@Sun.COM 			out[j++] = in[++i];
13811767SAnurag.Maskey@Sun.COM 		else
13911767SAnurag.Maskey@Sun.COM 			out[j++] = in[i];
14011767SAnurag.Maskey@Sun.COM 	}
14111767SAnurag.Maskey@Sun.COM 	out[j] = '\0';
14211767SAnurag.Maskey@Sun.COM 	return (out);
14311767SAnurag.Maskey@Sun.COM }
14411767SAnurag.Maskey@Sun.COM 
14511767SAnurag.Maskey@Sun.COM 
14611767SAnurag.Maskey@Sun.COM /*
14711767SAnurag.Maskey@Sun.COM  * Parse line into name and object list of properties.
14811767SAnurag.Maskey@Sun.COM  * Each line has the format:
14911767SAnurag.Maskey@Sun.COM  *
15011767SAnurag.Maskey@Sun.COM  * objname	[prop=type:val1[,val2..];..]
15111767SAnurag.Maskey@Sun.COM  */
15211767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_line_to_object(char * line,char ** objname,void * proplist)15311767SAnurag.Maskey@Sun.COM nwam_line_to_object(char *line, char **objname, void *proplist)
15411767SAnurag.Maskey@Sun.COM {
15511767SAnurag.Maskey@Sun.COM 	char *next = line, *prop, *nextprop, *propname, *proptypestr, *nextval;
15611767SAnurag.Maskey@Sun.COM 	char **valstr, **newvalstr;
15711767SAnurag.Maskey@Sun.COM 	boolean_t *valbool, *newvalbool;
15811767SAnurag.Maskey@Sun.COM 	int64_t *valint, *newvalint;
15911767SAnurag.Maskey@Sun.COM 	uint64_t *valuint, *newvaluint;
16011767SAnurag.Maskey@Sun.COM 	uint_t nelem, i;
16111767SAnurag.Maskey@Sun.COM 	nwam_value_type_t proptype;
16211767SAnurag.Maskey@Sun.COM 	nwam_value_t val = NULL;
16311767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
16411767SAnurag.Maskey@Sun.COM 
16511767SAnurag.Maskey@Sun.COM 	if ((err = nwam_alloc_object_list(proplist)) != NWAM_SUCCESS)
16611767SAnurag.Maskey@Sun.COM 		return (err);
16711767SAnurag.Maskey@Sun.COM 
16811767SAnurag.Maskey@Sun.COM 	*objname = line;
16911767SAnurag.Maskey@Sun.COM 
17011767SAnurag.Maskey@Sun.COM 	if ((*objname = nwam_tokenize_by_unescaped_delim(line, '\t', &prop))
17111767SAnurag.Maskey@Sun.COM 	    == NULL) {
17211767SAnurag.Maskey@Sun.COM 		nwam_free_object_list(*((char **)proplist));
17311767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
17411767SAnurag.Maskey@Sun.COM 	}
17511767SAnurag.Maskey@Sun.COM 
17611767SAnurag.Maskey@Sun.COM 	while ((prop = nwam_tokenize_by_unescaped_delim(prop,
17711767SAnurag.Maskey@Sun.COM 	    NWAM_FILE_PROP_DELIMITER, &nextprop)) != NULL) {
17811767SAnurag.Maskey@Sun.COM 		/*
17911767SAnurag.Maskey@Sun.COM 		 * Parse property into name=type,val[,val]
18011767SAnurag.Maskey@Sun.COM 		 */
18111767SAnurag.Maskey@Sun.COM 		if ((propname = nwam_tokenize_by_unescaped_delim(prop,
18211767SAnurag.Maskey@Sun.COM 		    NWAM_FILE_PROP_ASSIGN, &next)) == NULL ||
18311767SAnurag.Maskey@Sun.COM 		    (proptypestr = nwam_tokenize_by_unescaped_delim(next,
18411767SAnurag.Maskey@Sun.COM 		    NWAM_FILE_VALUE_DELIMITER, &next)) == NULL) {
18511767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(*((char **)proplist));
18611767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID);
18711767SAnurag.Maskey@Sun.COM 		}
18811767SAnurag.Maskey@Sun.COM 		if ((proptype = nwam_string_to_value_type(proptypestr)) ==
18911767SAnurag.Maskey@Sun.COM 		    NWAM_VALUE_TYPE_UNKNOWN) {
19011767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(*((char **)proplist));
19111767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID);
19211767SAnurag.Maskey@Sun.COM 		}
19311767SAnurag.Maskey@Sun.COM 		valbool = NULL;
19411767SAnurag.Maskey@Sun.COM 		valint = NULL;
19511767SAnurag.Maskey@Sun.COM 		valstr = NULL;
19611767SAnurag.Maskey@Sun.COM 		switch (proptype) {
19711767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_BOOLEAN:
19811767SAnurag.Maskey@Sun.COM 			valbool = calloc(NWAM_MAX_NUM_VALUES,
19911767SAnurag.Maskey@Sun.COM 			    sizeof (boolean_t));
20011767SAnurag.Maskey@Sun.COM 			break;
20111767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_INT64:
20211767SAnurag.Maskey@Sun.COM 			valint = calloc(NWAM_MAX_NUM_VALUES,
20311767SAnurag.Maskey@Sun.COM 			    sizeof (int64_t));
20411767SAnurag.Maskey@Sun.COM 			break;
20511767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_UINT64:
20611767SAnurag.Maskey@Sun.COM 			valuint = calloc(NWAM_MAX_NUM_VALUES,
20711767SAnurag.Maskey@Sun.COM 			    sizeof (uint64_t));
20811767SAnurag.Maskey@Sun.COM 			break;
20911767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_STRING:
21011767SAnurag.Maskey@Sun.COM 			valstr = calloc(NWAM_MAX_NUM_VALUES,
21111767SAnurag.Maskey@Sun.COM 			    sizeof (char *));
21211767SAnurag.Maskey@Sun.COM 			break;
21311767SAnurag.Maskey@Sun.COM 		default:
21411767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(*((char **)proplist));
21511767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
21611767SAnurag.Maskey@Sun.COM 		}
21711767SAnurag.Maskey@Sun.COM 		if (valbool == NULL && valint == NULL && valuint == NULL &&
21811767SAnurag.Maskey@Sun.COM 		    valstr == NULL) {
21911767SAnurag.Maskey@Sun.COM 			/* Memory allocation failed */
22011767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(*((char **)proplist));
22111767SAnurag.Maskey@Sun.COM 			return (NWAM_NO_MEMORY);
22211767SAnurag.Maskey@Sun.COM 		}
22311767SAnurag.Maskey@Sun.COM 		nelem = 0;
22411767SAnurag.Maskey@Sun.COM 		while ((nextval = nwam_tokenize_by_unescaped_delim(next,
22511767SAnurag.Maskey@Sun.COM 		    NWAM_FILE_VALUE_DELIMITER, &next)) != NULL) {
22611767SAnurag.Maskey@Sun.COM 			nelem++;
22711767SAnurag.Maskey@Sun.COM 			switch (proptype) {
22811767SAnurag.Maskey@Sun.COM 			case NWAM_VALUE_TYPE_BOOLEAN:
22911767SAnurag.Maskey@Sun.COM 				if (strncmp(nextval, NWAM_FILE_BOOLEAN_TRUE,
23011767SAnurag.Maskey@Sun.COM 				    strlen(nextval)) == 0) {
23111767SAnurag.Maskey@Sun.COM 					valbool[nelem - 1] = B_TRUE;
23211767SAnurag.Maskey@Sun.COM 				} else if (strncmp(nextval,
23311767SAnurag.Maskey@Sun.COM 				    NWAM_FILE_BOOLEAN_FALSE, strlen(nextval))
23411767SAnurag.Maskey@Sun.COM 				    == 0) {
23511767SAnurag.Maskey@Sun.COM 					valbool[nelem - 1] = B_FALSE;
23611767SAnurag.Maskey@Sun.COM 				} else {
23711767SAnurag.Maskey@Sun.COM 					nwam_free_object_list
23811767SAnurag.Maskey@Sun.COM 					    (*((char **)proplist));
23911767SAnurag.Maskey@Sun.COM 					return (NWAM_ENTITY_INVALID_VALUE);
24011767SAnurag.Maskey@Sun.COM 				}
24111767SAnurag.Maskey@Sun.COM 				break;
24211767SAnurag.Maskey@Sun.COM 			case NWAM_VALUE_TYPE_INT64:
24311767SAnurag.Maskey@Sun.COM 				valint[nelem - 1] = (int64_t)atoll(nextval);
24411767SAnurag.Maskey@Sun.COM 				break;
24511767SAnurag.Maskey@Sun.COM 			case NWAM_VALUE_TYPE_UINT64:
24611767SAnurag.Maskey@Sun.COM 				valuint[nelem - 1] = (uint64_t)atoll(nextval);
24711767SAnurag.Maskey@Sun.COM 				break;
24811767SAnurag.Maskey@Sun.COM 			case NWAM_VALUE_TYPE_STRING:
24911767SAnurag.Maskey@Sun.COM 				valstr[nelem - 1] =
25011767SAnurag.Maskey@Sun.COM 				    value_remove_escapes(nextval);
25111767SAnurag.Maskey@Sun.COM 				break;
25211767SAnurag.Maskey@Sun.COM 			default:
25311767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
25411767SAnurag.Maskey@Sun.COM 				return (NWAM_ENTITY_INVALID_VALUE);
25511767SAnurag.Maskey@Sun.COM 			}
25611767SAnurag.Maskey@Sun.COM 		}
25711767SAnurag.Maskey@Sun.COM 		switch (proptype) {
25811767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_BOOLEAN:
25911767SAnurag.Maskey@Sun.COM 			if ((newvalbool = realloc(valbool,
26011767SAnurag.Maskey@Sun.COM 			    nelem * sizeof (boolean_t))) == NULL) {
26111767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
26211767SAnurag.Maskey@Sun.COM 				return (NWAM_NO_MEMORY);
26311767SAnurag.Maskey@Sun.COM 			}
26411767SAnurag.Maskey@Sun.COM 			if ((err = nwam_value_create_boolean_array(newvalbool,
26511767SAnurag.Maskey@Sun.COM 			    nelem, &val)) != NWAM_SUCCESS ||
26611767SAnurag.Maskey@Sun.COM 			    (err = nwam_set_prop_value(*((char **)proplist),
26711767SAnurag.Maskey@Sun.COM 			    propname, val)) != NWAM_SUCCESS) {
26811767SAnurag.Maskey@Sun.COM 				free(newvalbool);
26911767SAnurag.Maskey@Sun.COM 				nwam_value_free(val);
27011767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
27111767SAnurag.Maskey@Sun.COM 				return (err);
27211767SAnurag.Maskey@Sun.COM 			}
27311767SAnurag.Maskey@Sun.COM 			free(newvalbool);
27411767SAnurag.Maskey@Sun.COM 			nwam_value_free(val);
27511767SAnurag.Maskey@Sun.COM 			break;
27611767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_INT64:
27711767SAnurag.Maskey@Sun.COM 			if ((newvalint = realloc(valint,
27811767SAnurag.Maskey@Sun.COM 			    nelem * sizeof (int64_t))) == NULL) {
27911767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
28011767SAnurag.Maskey@Sun.COM 				return (NWAM_NO_MEMORY);
28111767SAnurag.Maskey@Sun.COM 			}
28211767SAnurag.Maskey@Sun.COM 			if ((err = nwam_value_create_int64_array(newvalint,
28311767SAnurag.Maskey@Sun.COM 			    nelem, &val)) != NWAM_SUCCESS ||
28411767SAnurag.Maskey@Sun.COM 			    (err = nwam_set_prop_value(*((char **)proplist),
28511767SAnurag.Maskey@Sun.COM 			    propname, val)) != NWAM_SUCCESS) {
28611767SAnurag.Maskey@Sun.COM 				free(newvalint);
28711767SAnurag.Maskey@Sun.COM 				nwam_value_free(val);
28811767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
28911767SAnurag.Maskey@Sun.COM 				return (err);
29011767SAnurag.Maskey@Sun.COM 			}
29111767SAnurag.Maskey@Sun.COM 			free(newvalint);
29211767SAnurag.Maskey@Sun.COM 			nwam_value_free(val);
29311767SAnurag.Maskey@Sun.COM 			break;
29411767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_UINT64:
29511767SAnurag.Maskey@Sun.COM 			if ((newvaluint = realloc(valuint,
29611767SAnurag.Maskey@Sun.COM 			    nelem * sizeof (uint64_t))) == NULL) {
29711767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
29811767SAnurag.Maskey@Sun.COM 				return (NWAM_NO_MEMORY);
29911767SAnurag.Maskey@Sun.COM 			}
30011767SAnurag.Maskey@Sun.COM 			if ((err = nwam_value_create_uint64_array(newvaluint,
30111767SAnurag.Maskey@Sun.COM 			    nelem, &val)) != NWAM_SUCCESS ||
30211767SAnurag.Maskey@Sun.COM 			    (err = nwam_set_prop_value(*((char **)proplist),
30311767SAnurag.Maskey@Sun.COM 			    propname, val)) != NWAM_SUCCESS) {
30411767SAnurag.Maskey@Sun.COM 				free(newvaluint);
30511767SAnurag.Maskey@Sun.COM 				nwam_value_free(val);
30611767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
30711767SAnurag.Maskey@Sun.COM 				return (err);
30811767SAnurag.Maskey@Sun.COM 			}
30911767SAnurag.Maskey@Sun.COM 			free(newvaluint);
31011767SAnurag.Maskey@Sun.COM 			nwam_value_free(val);
31111767SAnurag.Maskey@Sun.COM 			break;
31211767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_STRING:
31311767SAnurag.Maskey@Sun.COM 			if ((newvalstr = realloc(valstr,
31411767SAnurag.Maskey@Sun.COM 			    nelem * sizeof (char *))) == NULL) {
31511767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
31611767SAnurag.Maskey@Sun.COM 				return (NWAM_NO_MEMORY);
31711767SAnurag.Maskey@Sun.COM 			}
31811767SAnurag.Maskey@Sun.COM 			if ((err = nwam_value_create_string_array(newvalstr,
31911767SAnurag.Maskey@Sun.COM 			    nelem, &val)) != NWAM_SUCCESS ||
32011767SAnurag.Maskey@Sun.COM 			    (err = nwam_set_prop_value(*((char **)proplist),
32111767SAnurag.Maskey@Sun.COM 			    propname, val)) != NWAM_SUCCESS) {
32211767SAnurag.Maskey@Sun.COM 				for (i = 0; i < nelem; i++)
32311767SAnurag.Maskey@Sun.COM 					free(newvalstr[i]);
32411767SAnurag.Maskey@Sun.COM 				free(newvalstr);
32511767SAnurag.Maskey@Sun.COM 				nwam_value_free(val);
32611767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(*((char **)proplist));
32711767SAnurag.Maskey@Sun.COM 				return (err);
32811767SAnurag.Maskey@Sun.COM 			}
32911767SAnurag.Maskey@Sun.COM 			for (i = 0; i < nelem; i++)
33011767SAnurag.Maskey@Sun.COM 				free(newvalstr[i]);
33111767SAnurag.Maskey@Sun.COM 			free(newvalstr);
33211767SAnurag.Maskey@Sun.COM 			nwam_value_free(val);
33311767SAnurag.Maskey@Sun.COM 			break;
33411767SAnurag.Maskey@Sun.COM 		}
33511767SAnurag.Maskey@Sun.COM 		prop = nextprop;
33611767SAnurag.Maskey@Sun.COM 	}
33711767SAnurag.Maskey@Sun.COM 
33811767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
33911767SAnurag.Maskey@Sun.COM }
34011767SAnurag.Maskey@Sun.COM 
34111767SAnurag.Maskey@Sun.COM /*
34211767SAnurag.Maskey@Sun.COM  * Create list of NCP files used for walk of NCPs and for case-insensitive
34311767SAnurag.Maskey@Sun.COM  * matching of NCP name to file.
34411767SAnurag.Maskey@Sun.COM  */
34511767SAnurag.Maskey@Sun.COM static nwam_error_t
create_ncp_file_list(char *** ncpfilesp,uint_t * num_filesp)34611767SAnurag.Maskey@Sun.COM create_ncp_file_list(char ***ncpfilesp, uint_t *num_filesp)
34711767SAnurag.Maskey@Sun.COM {
34811767SAnurag.Maskey@Sun.COM 	DIR *dirp = NULL;
34911767SAnurag.Maskey@Sun.COM 	struct dirent *dp;
35011767SAnurag.Maskey@Sun.COM 	char *ncpname, **ncpfiles = NULL;
35111767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
35211767SAnurag.Maskey@Sun.COM 	uint_t i;
35311767SAnurag.Maskey@Sun.COM 
35411767SAnurag.Maskey@Sun.COM 	ncpfiles = calloc(NWAM_MAX_NUM_OBJECTS, sizeof (char *));
35511767SAnurag.Maskey@Sun.COM 	if (ncpfiles == NULL)
35611767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
35711767SAnurag.Maskey@Sun.COM 	*num_filesp = 0;
35811767SAnurag.Maskey@Sun.COM 
35911767SAnurag.Maskey@Sun.COM 	/*
36011767SAnurag.Maskey@Sun.COM 	 * Construct NCP list by finding all files in NWAM directory
36111767SAnurag.Maskey@Sun.COM 	 * that match the NCP filename format.
36211767SAnurag.Maskey@Sun.COM 	 */
36311767SAnurag.Maskey@Sun.COM 	if ((dirp = opendir(NWAM_CONF_DIR)) == NULL) {
36411767SAnurag.Maskey@Sun.COM 		err = nwam_errno_to_nwam_error(errno);
36511767SAnurag.Maskey@Sun.COM 		goto done;
36611767SAnurag.Maskey@Sun.COM 	}
36711767SAnurag.Maskey@Sun.COM 
36811767SAnurag.Maskey@Sun.COM 	while ((dp = readdir(dirp)) != NULL) {
36911767SAnurag.Maskey@Sun.COM 		uint_t filenamelen;
37011767SAnurag.Maskey@Sun.COM 
37111767SAnurag.Maskey@Sun.COM 		/* Ensure filename is valid */
37211767SAnurag.Maskey@Sun.COM 		if (nwam_ncp_file_to_name(dp->d_name, &ncpname) != NWAM_SUCCESS)
37311767SAnurag.Maskey@Sun.COM 			continue;
37411767SAnurag.Maskey@Sun.COM 		free(ncpname);
37511767SAnurag.Maskey@Sun.COM 		filenamelen = strlen(NWAM_CONF_DIR) + strlen(dp->d_name) + 1;
37611767SAnurag.Maskey@Sun.COM 		if ((ncpfiles[*num_filesp] = malloc(filenamelen)) == NULL) {
37711767SAnurag.Maskey@Sun.COM 			err = NWAM_NO_MEMORY;
37811767SAnurag.Maskey@Sun.COM 			goto done;
37911767SAnurag.Maskey@Sun.COM 		}
38011767SAnurag.Maskey@Sun.COM 		(void) strlcpy(ncpfiles[*num_filesp], NWAM_CONF_DIR,
38111767SAnurag.Maskey@Sun.COM 		    strlen(NWAM_CONF_DIR) + 1);
38211767SAnurag.Maskey@Sun.COM 		(void) strlcpy(ncpfiles[*num_filesp] + strlen(NWAM_CONF_DIR),
38311767SAnurag.Maskey@Sun.COM 		    dp->d_name, filenamelen - strlen(NWAM_CONF_DIR));
38411767SAnurag.Maskey@Sun.COM 		(*num_filesp)++;
38511767SAnurag.Maskey@Sun.COM 	}
38611767SAnurag.Maskey@Sun.COM done:
38711767SAnurag.Maskey@Sun.COM 	if (dirp != NULL)
38811767SAnurag.Maskey@Sun.COM 		(void) closedir(dirp);
38911767SAnurag.Maskey@Sun.COM 
39011767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS) {
39111767SAnurag.Maskey@Sun.COM 		for (i = 0; i < *num_filesp; i++)
39211767SAnurag.Maskey@Sun.COM 			free(ncpfiles[i]);
39311767SAnurag.Maskey@Sun.COM 		free(ncpfiles);
39411767SAnurag.Maskey@Sun.COM 	} else {
39511767SAnurag.Maskey@Sun.COM 		*ncpfilesp = realloc(ncpfiles, sizeof (char *) * (*num_filesp));
396*12036SMichael.Hunter@Sun.COM 		if (*num_filesp != 0 && *ncpfilesp == NULL)
39711767SAnurag.Maskey@Sun.COM 			err = NWAM_NO_MEMORY;
39811767SAnurag.Maskey@Sun.COM 	}
39911767SAnurag.Maskey@Sun.COM 	return (err);
40011767SAnurag.Maskey@Sun.COM }
40111767SAnurag.Maskey@Sun.COM 
40211767SAnurag.Maskey@Sun.COM /*
40311767SAnurag.Maskey@Sun.COM  * Read object specified by objname from file, converting it to
40411767SAnurag.Maskey@Sun.COM  * an object list.  If filename is NULL, a list of configuration object
40511767SAnurag.Maskey@Sun.COM  * containers is returned, represented as an object lists with elements "enms"
40611767SAnurag.Maskey@Sun.COM  * "locs" and "ncps". Each of these is a list of configuration files for each
40711767SAnurag.Maskey@Sun.COM  * object. This corresponds to the enm.conf file, loc.conf file and list of
40811767SAnurag.Maskey@Sun.COM  * ncp conf files. If objname is NULL, read all objects, and create
40911767SAnurag.Maskey@Sun.COM  * an nvlist with one element - "object-list" - which has as its values
41011767SAnurag.Maskey@Sun.COM  * the names of the objects found.  Otherwise obj points to an object list
41111767SAnurag.Maskey@Sun.COM  * of properties for the first object in the file that case-insensitively
41211767SAnurag.Maskey@Sun.COM  * matches objname.  We write the found name into objname so that it can be
41311767SAnurag.Maskey@Sun.COM  * returned to the caller (and set in the object handle).
41411767SAnurag.Maskey@Sun.COM  */
41511767SAnurag.Maskey@Sun.COM /* ARGSUSED2 */
41611767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_read_object_from_files_backend(char * filename,char * objname,uint64_t flags,void * obj)41711767SAnurag.Maskey@Sun.COM nwam_read_object_from_files_backend(char *filename, char *objname,
41811767SAnurag.Maskey@Sun.COM     uint64_t flags, void *obj)
41911767SAnurag.Maskey@Sun.COM {
42011767SAnurag.Maskey@Sun.COM 	char line[NWAM_FILE_LINE_MAX];
42111767SAnurag.Maskey@Sun.COM 	char *cp, *foundobjname, **objnames = NULL, **ncpfiles = NULL;
42211767SAnurag.Maskey@Sun.COM 	uint_t num_files = 0;
42311767SAnurag.Maskey@Sun.COM 	FILE *fp = NULL;
42411767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
42511767SAnurag.Maskey@Sun.COM 	void *objlist = NULL, *proplist = NULL;
42611767SAnurag.Maskey@Sun.COM 	uint_t i = 0, j = 0;
42711767SAnurag.Maskey@Sun.COM 	nwam_value_t objnamesval = NULL;
42811767SAnurag.Maskey@Sun.COM 
42911767SAnurag.Maskey@Sun.COM 	assert(obj != NULL);
43011767SAnurag.Maskey@Sun.COM 
43111767SAnurag.Maskey@Sun.COM 	*((char **)obj) = NULL;
43211767SAnurag.Maskey@Sun.COM 
43311767SAnurag.Maskey@Sun.COM 	if (filename == NULL) {
43411767SAnurag.Maskey@Sun.COM 		nwam_value_t enmval = NULL, locval = NULL, ncpval = NULL;
43511767SAnurag.Maskey@Sun.COM 
43611767SAnurag.Maskey@Sun.COM 		/*
43711767SAnurag.Maskey@Sun.COM 		 * When the filename is not specified, it signifies a
43811767SAnurag.Maskey@Sun.COM 		 * request for the list of configuration object containers -
43911767SAnurag.Maskey@Sun.COM 		 * in this case files.
44011767SAnurag.Maskey@Sun.COM 		 *
44111767SAnurag.Maskey@Sun.COM 		 * A list of all object files is returned. For ENMs
44211767SAnurag.Maskey@Sun.COM 		 * and locations, only the default loc.conf and enm.conf
44311767SAnurag.Maskey@Sun.COM 		 * files are used, but for NCPs we need to walk the
44411767SAnurag.Maskey@Sun.COM 		 * files in the NWAM directory retrieving each one that
44511767SAnurag.Maskey@Sun.COM 		 * matches the NCP pattern.
44611767SAnurag.Maskey@Sun.COM 		 */
44711767SAnurag.Maskey@Sun.COM 		if ((err = nwam_alloc_object_list(&objlist)) != NWAM_SUCCESS)
44811767SAnurag.Maskey@Sun.COM 			return (err);
44911767SAnurag.Maskey@Sun.COM 
45011767SAnurag.Maskey@Sun.COM 		if ((err = nwam_value_create_string(NWAM_ENM_CONF_FILE,
45111767SAnurag.Maskey@Sun.COM 		    &enmval)) != NWAM_SUCCESS ||
45211767SAnurag.Maskey@Sun.COM 		    (err = nwam_value_create_string(NWAM_LOC_CONF_FILE,
45311767SAnurag.Maskey@Sun.COM 		    &locval)) != NWAM_SUCCESS ||
45411767SAnurag.Maskey@Sun.COM 		    (err = nwam_set_prop_value(objlist, NWAM_ENM_OBJECT_STRING,
45511767SAnurag.Maskey@Sun.COM 		    enmval)) != NWAM_SUCCESS ||
45611767SAnurag.Maskey@Sun.COM 		    (err = nwam_set_prop_value(objlist, NWAM_LOC_OBJECT_STRING,
45711767SAnurag.Maskey@Sun.COM 		    locval)) != NWAM_SUCCESS)
45811767SAnurag.Maskey@Sun.COM 			goto done_with_containers;
45911767SAnurag.Maskey@Sun.COM 
46011767SAnurag.Maskey@Sun.COM 		/*
46111767SAnurag.Maskey@Sun.COM 		 * Construct NCP list by finding all files in NWAM directory
46211767SAnurag.Maskey@Sun.COM 		 * that match the NCP filename format.
46311767SAnurag.Maskey@Sun.COM 		 */
46411767SAnurag.Maskey@Sun.COM 		if ((err = create_ncp_file_list(&ncpfiles, &num_files))
46511767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
46611767SAnurag.Maskey@Sun.COM 			goto done_with_containers;
46711767SAnurag.Maskey@Sun.COM 
46811767SAnurag.Maskey@Sun.COM 		if ((err = nwam_value_create_string_array(ncpfiles, num_files,
46911767SAnurag.Maskey@Sun.COM 		    &ncpval)) == NWAM_SUCCESS) {
47011767SAnurag.Maskey@Sun.COM 			err = nwam_set_prop_value(objlist,
47111767SAnurag.Maskey@Sun.COM 			    NWAM_NCP_OBJECT_STRING, ncpval);
47211767SAnurag.Maskey@Sun.COM 		}
47311767SAnurag.Maskey@Sun.COM 
47411767SAnurag.Maskey@Sun.COM done_with_containers:
47511767SAnurag.Maskey@Sun.COM 		nwam_value_free(enmval);
47611767SAnurag.Maskey@Sun.COM 		nwam_value_free(locval);
47711767SAnurag.Maskey@Sun.COM 		nwam_value_free(ncpval);
47811767SAnurag.Maskey@Sun.COM 		if (ncpfiles != NULL) {
47911767SAnurag.Maskey@Sun.COM 			for (j = 0; j < num_files; j++)
48011767SAnurag.Maskey@Sun.COM 				free(ncpfiles[j]);
48111767SAnurag.Maskey@Sun.COM 			free(ncpfiles);
48211767SAnurag.Maskey@Sun.COM 		}
48311767SAnurag.Maskey@Sun.COM 		if (err != NWAM_SUCCESS)
48411767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(objlist);
48511767SAnurag.Maskey@Sun.COM 		else
48611767SAnurag.Maskey@Sun.COM 			*((char **)obj) = objlist;
48711767SAnurag.Maskey@Sun.COM 		return (err);
48811767SAnurag.Maskey@Sun.COM 	}
48911767SAnurag.Maskey@Sun.COM 
49011767SAnurag.Maskey@Sun.COM 	if (objname == NULL) {
49111767SAnurag.Maskey@Sun.COM 		/* Allocate string array to store object names */
49211767SAnurag.Maskey@Sun.COM 		if ((objnames = calloc(NWAM_MAX_NUM_OBJECTS, sizeof (char *)))
49311767SAnurag.Maskey@Sun.COM 		    == NULL)
49411767SAnurag.Maskey@Sun.COM 			return (NWAM_NO_MEMORY);
49511767SAnurag.Maskey@Sun.COM 	}
49611767SAnurag.Maskey@Sun.COM 
49711767SAnurag.Maskey@Sun.COM 	fp = fopen(filename, "r");
49811767SAnurag.Maskey@Sun.COM 	if (fp == NULL) {
49911767SAnurag.Maskey@Sun.COM 		if (errno != ENOENT) {
50011767SAnurag.Maskey@Sun.COM 			if (objname == NULL)
50111767SAnurag.Maskey@Sun.COM 				free(objnames);
50211767SAnurag.Maskey@Sun.COM 			return (NWAM_ERROR_INTERNAL);
50311767SAnurag.Maskey@Sun.COM 		}
50411767SAnurag.Maskey@Sun.COM 
50511767SAnurag.Maskey@Sun.COM 		/*
50611767SAnurag.Maskey@Sun.COM 		 * Check NCP file list in case filename passed in was derived
50711767SAnurag.Maskey@Sun.COM 		 * from a case-insensitive NCP name.
50811767SAnurag.Maskey@Sun.COM 		 */
50911767SAnurag.Maskey@Sun.COM 		if ((err = create_ncp_file_list(&ncpfiles, &num_files))
51011767SAnurag.Maskey@Sun.COM 		    == NWAM_SUCCESS) {
51111767SAnurag.Maskey@Sun.COM 			for (j = 0; j < num_files; j++) {
51211767SAnurag.Maskey@Sun.COM 				if (strcasecmp(ncpfiles[j], filename) == 0) {
51311767SAnurag.Maskey@Sun.COM 					fp = fopen(ncpfiles[j], "r");
51411767SAnurag.Maskey@Sun.COM 					if (fp != NULL) {
51511767SAnurag.Maskey@Sun.COM 						/* Copy real filename back */
51611767SAnurag.Maskey@Sun.COM 						(void) strlcpy(filename,
51711767SAnurag.Maskey@Sun.COM 						    ncpfiles[j],
51811767SAnurag.Maskey@Sun.COM 						    strlen(filename) + 1);
51911767SAnurag.Maskey@Sun.COM 						break;
52011767SAnurag.Maskey@Sun.COM 					}
52111767SAnurag.Maskey@Sun.COM 				}
52211767SAnurag.Maskey@Sun.COM 			}
52311767SAnurag.Maskey@Sun.COM 			for (j = 0; j < num_files; j++)
52411767SAnurag.Maskey@Sun.COM 				free(ncpfiles[j]);
52511767SAnurag.Maskey@Sun.COM 			free(ncpfiles);
52611767SAnurag.Maskey@Sun.COM 		}
52711767SAnurag.Maskey@Sun.COM 		/* Return NOT_FOUND if file not found */
52811767SAnurag.Maskey@Sun.COM 		if (fp == NULL) {
52911767SAnurag.Maskey@Sun.COM 			if (objname == NULL)
53011767SAnurag.Maskey@Sun.COM 				free(objnames);
53111767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_NOT_FOUND);
53211767SAnurag.Maskey@Sun.COM 		}
53311767SAnurag.Maskey@Sun.COM 	}
53411767SAnurag.Maskey@Sun.COM 
53511767SAnurag.Maskey@Sun.COM 	while (fgets(line, sizeof (line), fp) != NULL) {
53611767SAnurag.Maskey@Sun.COM 		if (line[strlen(line) - 1] == '\n')
53711767SAnurag.Maskey@Sun.COM 			line[strlen(line) - 1] = '\0';
53811767SAnurag.Maskey@Sun.COM 
53911767SAnurag.Maskey@Sun.COM 		cp = line;
54011767SAnurag.Maskey@Sun.COM 
54111767SAnurag.Maskey@Sun.COM 		while (isspace(*cp))
54211767SAnurag.Maskey@Sun.COM 			cp++;
54311767SAnurag.Maskey@Sun.COM 
54411767SAnurag.Maskey@Sun.COM 		if (*cp == '#' || *cp == '\0')
54511767SAnurag.Maskey@Sun.COM 			continue;
54611767SAnurag.Maskey@Sun.COM 
54711767SAnurag.Maskey@Sun.COM 		if ((err = nwam_line_to_object(cp, &foundobjname, &proplist))
54811767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
54911767SAnurag.Maskey@Sun.COM 			goto done;
55011767SAnurag.Maskey@Sun.COM 
55111767SAnurag.Maskey@Sun.COM 		if (objname != NULL) {
55211767SAnurag.Maskey@Sun.COM 			/*
55311767SAnurag.Maskey@Sun.COM 			 * Is this the specified object?  If so set objname and
55411767SAnurag.Maskey@Sun.COM 			 * obj and bail.
55511767SAnurag.Maskey@Sun.COM 			 */
55611767SAnurag.Maskey@Sun.COM 			if (strcasecmp(objname, foundobjname) == 0) {
55711767SAnurag.Maskey@Sun.COM 				*((char **)obj) = proplist;
55811767SAnurag.Maskey@Sun.COM 				(void) strlcpy(objname, foundobjname,
55911767SAnurag.Maskey@Sun.COM 				    NWAM_MAX_NAME_LEN);
56011767SAnurag.Maskey@Sun.COM 				break;
56111767SAnurag.Maskey@Sun.COM 			} else {
56211767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(proplist);
56311767SAnurag.Maskey@Sun.COM 			}
56411767SAnurag.Maskey@Sun.COM 		} else {
56511767SAnurag.Maskey@Sun.COM 			objnames[i] = strdup(foundobjname);
56611767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(proplist);
56711767SAnurag.Maskey@Sun.COM 			if (objnames[i] == NULL) {
56811767SAnurag.Maskey@Sun.COM 				err = NWAM_NO_MEMORY;
56911767SAnurag.Maskey@Sun.COM 				goto done;
57011767SAnurag.Maskey@Sun.COM 			}
57111767SAnurag.Maskey@Sun.COM 			i++;
57211767SAnurag.Maskey@Sun.COM 		}
57311767SAnurag.Maskey@Sun.COM 
57411767SAnurag.Maskey@Sun.COM 	}
57511767SAnurag.Maskey@Sun.COM 	if (objname == NULL) {
57611767SAnurag.Maskey@Sun.COM 		/*
57711767SAnurag.Maskey@Sun.COM 		 * Allocate object list with one value named
57811767SAnurag.Maskey@Sun.COM 		 * NWAM_OBJECT_NAMES_STRING - it's values are the names of
57911767SAnurag.Maskey@Sun.COM 		 * the objects found.
58011767SAnurag.Maskey@Sun.COM 		 */
58111767SAnurag.Maskey@Sun.COM 		if ((err = nwam_alloc_object_list(&objlist)) == NWAM_SUCCESS &&
58211767SAnurag.Maskey@Sun.COM 		    (err = nwam_value_create_string_array(objnames, i,
58311767SAnurag.Maskey@Sun.COM 		    &objnamesval)) == NWAM_SUCCESS) {
58411767SAnurag.Maskey@Sun.COM 			err = nwam_set_prop_value(objlist,
58511767SAnurag.Maskey@Sun.COM 			    NWAM_OBJECT_NAMES_STRING, objnamesval);
58611767SAnurag.Maskey@Sun.COM 		}
58711767SAnurag.Maskey@Sun.COM 	}
58811767SAnurag.Maskey@Sun.COM 
58911767SAnurag.Maskey@Sun.COM done:
59011767SAnurag.Maskey@Sun.COM 	if (fp != NULL)
59111767SAnurag.Maskey@Sun.COM 		(void) fclose(fp);
59211767SAnurag.Maskey@Sun.COM 
59311767SAnurag.Maskey@Sun.COM 	/*
59411767SAnurag.Maskey@Sun.COM 	 * We're done, either we have success, and return our object list
59511767SAnurag.Maskey@Sun.COM 	 * containing object names, or we have failure and we need to free
59611767SAnurag.Maskey@Sun.COM 	 * the object list.
59711767SAnurag.Maskey@Sun.COM 	 */
59811767SAnurag.Maskey@Sun.COM 	if (objname == NULL) {
59911767SAnurag.Maskey@Sun.COM 		for (j = 0; j < i; j++)
60011767SAnurag.Maskey@Sun.COM 			free(objnames[j]);
60111767SAnurag.Maskey@Sun.COM 		free(objnames);
60211767SAnurag.Maskey@Sun.COM 		nwam_value_free(objnamesval);
60311767SAnurag.Maskey@Sun.COM 		if (err == NWAM_SUCCESS) {
60411767SAnurag.Maskey@Sun.COM 			*((char **)obj) = objlist;
60511767SAnurag.Maskey@Sun.COM 		} else {
60611767SAnurag.Maskey@Sun.COM 			*((char **)obj) = NULL;
60711767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(objlist);
60811767SAnurag.Maskey@Sun.COM 		}
60911767SAnurag.Maskey@Sun.COM 	} else {
61011767SAnurag.Maskey@Sun.COM 		/* Check if to-be-read object was not found */
61111767SAnurag.Maskey@Sun.COM 		if (*((char **)obj) == NULL && err == NWAM_SUCCESS)
61211767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_NOT_FOUND);
61311767SAnurag.Maskey@Sun.COM 	}
61411767SAnurag.Maskey@Sun.COM 
61511767SAnurag.Maskey@Sun.COM 	return (err);
61611767SAnurag.Maskey@Sun.COM }
61711767SAnurag.Maskey@Sun.COM 
61811767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_object_to_line(FILE * fp,const char * objname,void * proplist)61911767SAnurag.Maskey@Sun.COM nwam_object_to_line(FILE *fp, const char *objname, void *proplist)
62011767SAnurag.Maskey@Sun.COM {
62111767SAnurag.Maskey@Sun.COM 	char *propname, *lastpropname = NULL;
62211767SAnurag.Maskey@Sun.COM 	boolean_t *valbool;
62311767SAnurag.Maskey@Sun.COM 	int64_t *valint;
62411767SAnurag.Maskey@Sun.COM 	uint64_t *valuint;
62511767SAnurag.Maskey@Sun.COM 	char **valstr;
62611767SAnurag.Maskey@Sun.COM 	uint_t nelem, i;
62711767SAnurag.Maskey@Sun.COM 	nwam_value_t val;
62811767SAnurag.Maskey@Sun.COM 	nwam_value_type_t type;
62911767SAnurag.Maskey@Sun.COM 
63011767SAnurag.Maskey@Sun.COM 	(void) fprintf(fp, "%s\t", objname);
63111767SAnurag.Maskey@Sun.COM 
63211767SAnurag.Maskey@Sun.COM 	while (nwam_next_object_prop(proplist, lastpropname, &propname, &val)
63311767SAnurag.Maskey@Sun.COM 	    == NWAM_SUCCESS) {
63411767SAnurag.Maskey@Sun.COM 
63511767SAnurag.Maskey@Sun.COM 		(void) fprintf(fp, "%s%c", propname, NWAM_FILE_PROP_ASSIGN);
63611767SAnurag.Maskey@Sun.COM 
63711767SAnurag.Maskey@Sun.COM 		if (nwam_value_get_type(val, &type) != NWAM_SUCCESS)
63811767SAnurag.Maskey@Sun.COM 			return (NWAM_INVALID_ARG);
63911767SAnurag.Maskey@Sun.COM 
64011767SAnurag.Maskey@Sun.COM 		switch (type) {
64111767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_BOOLEAN:
64211767SAnurag.Maskey@Sun.COM 			(void) fprintf(fp, "%s",
64311767SAnurag.Maskey@Sun.COM 			    nwam_value_type_to_string(NWAM_VALUE_TYPE_BOOLEAN));
64411767SAnurag.Maskey@Sun.COM 			if (nwam_value_get_boolean_array(val, &valbool, &nelem)
64511767SAnurag.Maskey@Sun.COM 			    != NWAM_SUCCESS) {
64611767SAnurag.Maskey@Sun.COM 				nwam_value_free(val);
64711767SAnurag.Maskey@Sun.COM 				return (NWAM_INVALID_ARG);
64811767SAnurag.Maskey@Sun.COM 			}
64911767SAnurag.Maskey@Sun.COM 			for (i = 0; i < nelem; i++) {
65011767SAnurag.Maskey@Sun.COM 				(void) fprintf(fp, "%c",
65111767SAnurag.Maskey@Sun.COM 				    NWAM_FILE_VALUE_DELIMITER);
65211767SAnurag.Maskey@Sun.COM 				if (valbool[i]) {
65311767SAnurag.Maskey@Sun.COM 					(void) fprintf(fp,
65411767SAnurag.Maskey@Sun.COM 					    NWAM_FILE_BOOLEAN_TRUE);
65511767SAnurag.Maskey@Sun.COM 				} else {
65611767SAnurag.Maskey@Sun.COM 					(void) fprintf(fp,
65711767SAnurag.Maskey@Sun.COM 					    NWAM_FILE_BOOLEAN_FALSE);
65811767SAnurag.Maskey@Sun.COM 				}
65911767SAnurag.Maskey@Sun.COM 			}
66011767SAnurag.Maskey@Sun.COM 			break;
66111767SAnurag.Maskey@Sun.COM 
66211767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_INT64:
66311767SAnurag.Maskey@Sun.COM 			(void) fprintf(fp, "%s",
66411767SAnurag.Maskey@Sun.COM 			    nwam_value_type_to_string(NWAM_VALUE_TYPE_INT64));
66511767SAnurag.Maskey@Sun.COM 			if (nwam_value_get_int64_array(val, &valint, &nelem)
66611767SAnurag.Maskey@Sun.COM 			    != NWAM_SUCCESS) {
66711767SAnurag.Maskey@Sun.COM 				nwam_value_free(val);
66811767SAnurag.Maskey@Sun.COM 				return (NWAM_INVALID_ARG);
66911767SAnurag.Maskey@Sun.COM 			}
67011767SAnurag.Maskey@Sun.COM 			for (i = 0; i < nelem; i++) {
67111767SAnurag.Maskey@Sun.COM 				(void) fprintf(fp, "%c%lld",
67211767SAnurag.Maskey@Sun.COM 				    NWAM_FILE_VALUE_DELIMITER, valint[i]);
67311767SAnurag.Maskey@Sun.COM 			}
67411767SAnurag.Maskey@Sun.COM 			break;
67511767SAnurag.Maskey@Sun.COM 
67611767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_UINT64:
67711767SAnurag.Maskey@Sun.COM 			(void) fprintf(fp, "%s",
67811767SAnurag.Maskey@Sun.COM 			    nwam_value_type_to_string(NWAM_VALUE_TYPE_UINT64));
67911767SAnurag.Maskey@Sun.COM 			if (nwam_value_get_uint64_array(val, &valuint, &nelem)
68011767SAnurag.Maskey@Sun.COM 			    != NWAM_SUCCESS) {
68111767SAnurag.Maskey@Sun.COM 				nwam_value_free(val);
68211767SAnurag.Maskey@Sun.COM 				return (NWAM_INVALID_ARG);
68311767SAnurag.Maskey@Sun.COM 			}
68411767SAnurag.Maskey@Sun.COM 			for (i = 0; i < nelem; i++) {
68511767SAnurag.Maskey@Sun.COM 				(void) fprintf(fp, "%c%lld",
68611767SAnurag.Maskey@Sun.COM 				    NWAM_FILE_VALUE_DELIMITER, valuint[i]);
68711767SAnurag.Maskey@Sun.COM 			}
68811767SAnurag.Maskey@Sun.COM 			break;
68911767SAnurag.Maskey@Sun.COM 
69011767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_STRING:
69111767SAnurag.Maskey@Sun.COM 			(void) fprintf(fp, "%s",
69211767SAnurag.Maskey@Sun.COM 			    nwam_value_type_to_string(NWAM_VALUE_TYPE_STRING));
69311767SAnurag.Maskey@Sun.COM 			if (nwam_value_get_string_array(val, &valstr, &nelem)
69411767SAnurag.Maskey@Sun.COM 			    != NWAM_SUCCESS) {
69511767SAnurag.Maskey@Sun.COM 				nwam_value_free(val);
69611767SAnurag.Maskey@Sun.COM 				return (NWAM_INVALID_ARG);
69711767SAnurag.Maskey@Sun.COM 			}
69811767SAnurag.Maskey@Sun.COM 			for (i = 0; i < nelem; i++) {
69911767SAnurag.Maskey@Sun.COM 				char evalstr[NWAM_MAX_VALUE_LEN];
70011767SAnurag.Maskey@Sun.COM 				/* Add escape chars as necessary */
70111767SAnurag.Maskey@Sun.COM 				value_add_escapes(valstr[i], evalstr);
70211767SAnurag.Maskey@Sun.COM 				(void) fprintf(fp, "%c%s",
70311767SAnurag.Maskey@Sun.COM 				    NWAM_FILE_VALUE_DELIMITER, evalstr);
70411767SAnurag.Maskey@Sun.COM 			}
70511767SAnurag.Maskey@Sun.COM 			break;
70611767SAnurag.Maskey@Sun.COM 		default:
70711767SAnurag.Maskey@Sun.COM 			nwam_value_free(val);
70811767SAnurag.Maskey@Sun.COM 			return (NWAM_INVALID_ARG);
70911767SAnurag.Maskey@Sun.COM 		}
71011767SAnurag.Maskey@Sun.COM 		nwam_value_free(val);
71111767SAnurag.Maskey@Sun.COM 		(void) fprintf(fp, "%c", NWAM_FILE_PROP_DELIMITER);
71211767SAnurag.Maskey@Sun.COM 
71311767SAnurag.Maskey@Sun.COM 		lastpropname = propname;
71411767SAnurag.Maskey@Sun.COM 
71511767SAnurag.Maskey@Sun.COM 	}
71611767SAnurag.Maskey@Sun.COM 	(void) fprintf(fp, "\n");
71711767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
71811767SAnurag.Maskey@Sun.COM }
71911767SAnurag.Maskey@Sun.COM 
72011767SAnurag.Maskey@Sun.COM /*
72111767SAnurag.Maskey@Sun.COM  * Write object specified by objname to file.  If objname is NULL, objlist
72211767SAnurag.Maskey@Sun.COM  * must be a list of lists, where each list corresponds to an
72311767SAnurag.Maskey@Sun.COM  * object to write to the file.  Otherwise objlist should point to a list of
72411767SAnurag.Maskey@Sun.COM  * properties for the object specified by objname.  The write operation is
72511767SAnurag.Maskey@Sun.COM  * first done to filename.new, and if this succeeds, the file is renamed to
72611767SAnurag.Maskey@Sun.COM  * filename.  Since rename(2) is atomic, this approach guarantees a complete
72711767SAnurag.Maskey@Sun.COM  * configuration will end up in filename as a result of an aborted operation.
72811767SAnurag.Maskey@Sun.COM  */
72911767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_write_object_to_files_backend(const char * filename,const char * objname,uint64_t flags,void * objlist)73011767SAnurag.Maskey@Sun.COM nwam_write_object_to_files_backend(const char *filename, const char *objname,
73111767SAnurag.Maskey@Sun.COM     uint64_t flags, void *objlist)
73211767SAnurag.Maskey@Sun.COM {
73311767SAnurag.Maskey@Sun.COM 	void *proplist;
73411767SAnurag.Maskey@Sun.COM 	char *currobjname, *lastobjname = NULL;
73511767SAnurag.Maskey@Sun.COM 	int fd, cmd;
73611767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
73711767SAnurag.Maskey@Sun.COM 	char *dir;
73811767SAnurag.Maskey@Sun.COM 	char tmpfilename[MAXPATHLEN], filename_copy[MAXPATHLEN];
73911767SAnurag.Maskey@Sun.COM 	FILE *fp;
74011767SAnurag.Maskey@Sun.COM 	mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
74111767SAnurag.Maskey@Sun.COM 	mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
74211767SAnurag.Maskey@Sun.COM 	struct flock fl = { F_WRLCK, SEEK_SET, 0, 0, 0};
74311767SAnurag.Maskey@Sun.COM 	struct flock fu = { F_UNLCK, SEEK_SET, 0, 0, 0};
74411767SAnurag.Maskey@Sun.COM 
74511767SAnurag.Maskey@Sun.COM 	assert(filename != NULL);
74611767SAnurag.Maskey@Sun.COM 
74711767SAnurag.Maskey@Sun.COM 	/* Create the directory in case it does not exist. */
74811767SAnurag.Maskey@Sun.COM 	(void) strlcpy(filename_copy, filename, MAXPATHLEN);
74911767SAnurag.Maskey@Sun.COM 	if ((dir = dirname(filename_copy)) == NULL)
75011767SAnurag.Maskey@Sun.COM 		return (nwam_errno_to_nwam_error(errno));
75111767SAnurag.Maskey@Sun.COM 	if (mkdir(dir, dirmode) != 0) {
75211767SAnurag.Maskey@Sun.COM 		if (errno != EEXIST)
75311767SAnurag.Maskey@Sun.COM 			return (nwam_errno_to_nwam_error(errno));
75411767SAnurag.Maskey@Sun.COM 	}
75511767SAnurag.Maskey@Sun.COM 
75611767SAnurag.Maskey@Sun.COM 	(void) snprintf(tmpfilename, MAXPATHLEN, "%s.new", filename);
75711767SAnurag.Maskey@Sun.COM 
75811767SAnurag.Maskey@Sun.COM 	if ((fd = open(tmpfilename, O_RDWR | O_CREAT | O_TRUNC, mode)) < 0)
75911767SAnurag.Maskey@Sun.COM 			return (nwam_errno_to_nwam_error(errno));
76011767SAnurag.Maskey@Sun.COM 
76111767SAnurag.Maskey@Sun.COM 	if ((fp = fdopen(fd, "w")) == NULL) {
76211767SAnurag.Maskey@Sun.COM 		err = nwam_errno_to_nwam_error(errno);
76311767SAnurag.Maskey@Sun.COM 		goto done;
76411767SAnurag.Maskey@Sun.COM 	}
76511767SAnurag.Maskey@Sun.COM 	/*
76611767SAnurag.Maskey@Sun.COM 	 * Need to lock filename.new to prevent multiple commits colliding
76711767SAnurag.Maskey@Sun.COM 	 * at this point.
76811767SAnurag.Maskey@Sun.COM 	 */
76911767SAnurag.Maskey@Sun.COM 	if (flags & NWAM_FLAG_BLOCKING)
77011767SAnurag.Maskey@Sun.COM 		cmd = F_SETLKW;
77111767SAnurag.Maskey@Sun.COM 	else
77211767SAnurag.Maskey@Sun.COM 		cmd = F_SETLK;
77311767SAnurag.Maskey@Sun.COM 	if (fcntl(fd, cmd, &fl) != 0) {
77411767SAnurag.Maskey@Sun.COM 		if (errno == EAGAIN)
77511767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_IN_USE);
77611767SAnurag.Maskey@Sun.COM 		else
77711767SAnurag.Maskey@Sun.COM 			return (NWAM_ERROR_INTERNAL);
77811767SAnurag.Maskey@Sun.COM 	}
77911767SAnurag.Maskey@Sun.COM 
78011767SAnurag.Maskey@Sun.COM 	if (objname != NULL) {
78111767SAnurag.Maskey@Sun.COM 		/* Only one object to write */
78211767SAnurag.Maskey@Sun.COM 		err = nwam_object_to_line(fp, objname, objlist);
78311767SAnurag.Maskey@Sun.COM 	} else {
78411767SAnurag.Maskey@Sun.COM 		if (objlist == NULL) {
78511767SAnurag.Maskey@Sun.COM 			err = NWAM_SUCCESS;
78611767SAnurag.Maskey@Sun.COM 			goto done;
78711767SAnurag.Maskey@Sun.COM 		}
78811767SAnurag.Maskey@Sun.COM 		/* Otherwise, write each object in turn. */
78911767SAnurag.Maskey@Sun.COM 		while ((err = nwam_next_object_list(objlist, lastobjname,
79011767SAnurag.Maskey@Sun.COM 		    &currobjname, &proplist)) == NWAM_SUCCESS) {
79111767SAnurag.Maskey@Sun.COM 			if ((err = nwam_object_to_line(fp, currobjname,
79211767SAnurag.Maskey@Sun.COM 			    proplist)) != NWAM_SUCCESS)
79311767SAnurag.Maskey@Sun.COM 				break;
79411767SAnurag.Maskey@Sun.COM 			lastobjname = currobjname;
79511767SAnurag.Maskey@Sun.COM 		}
79611767SAnurag.Maskey@Sun.COM 		if (err == NWAM_LIST_END)
79711767SAnurag.Maskey@Sun.COM 			err = NWAM_SUCCESS;
79811767SAnurag.Maskey@Sun.COM 	}
79911767SAnurag.Maskey@Sun.COM done:
80011767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS) {
80111767SAnurag.Maskey@Sun.COM 		if (rename(tmpfilename, filename) == 0) {
80211767SAnurag.Maskey@Sun.COM 			(void) fcntl(fd, F_SETLKW, &fu);
80311767SAnurag.Maskey@Sun.COM 			(void) fclose(fp);
80411767SAnurag.Maskey@Sun.COM 			return (NWAM_SUCCESS);
80511767SAnurag.Maskey@Sun.COM 		} else {
80611767SAnurag.Maskey@Sun.COM 			err = nwam_errno_to_nwam_error(errno);
80711767SAnurag.Maskey@Sun.COM 		}
80811767SAnurag.Maskey@Sun.COM 	}
80911767SAnurag.Maskey@Sun.COM 	(void) fcntl(fd, F_SETLKW, &fu);
81011767SAnurag.Maskey@Sun.COM 	(void) fclose(fp);
81111767SAnurag.Maskey@Sun.COM 	(void) unlink(tmpfilename);
81211767SAnurag.Maskey@Sun.COM 
81311767SAnurag.Maskey@Sun.COM 	return (err);
81411767SAnurag.Maskey@Sun.COM }
81511767SAnurag.Maskey@Sun.COM 
81611767SAnurag.Maskey@Sun.COM /*
81711767SAnurag.Maskey@Sun.COM  * Read in all objects from file and update object corresponding to objname
81811767SAnurag.Maskey@Sun.COM  * with properties recorded in proplist, and then write results to filename.
81911767SAnurag.Maskey@Sun.COM  * If objname is empty, no object needs to be updated.  If proplist is NULL,
82011767SAnurag.Maskey@Sun.COM  * object is to be removed (this is done by simply not adding it to the list
82111767SAnurag.Maskey@Sun.COM  * of objects).
82211767SAnurag.Maskey@Sun.COM  */
82311767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_update_object_in_files_backend(char * filename,char * objname,uint64_t flags,void * proplist)82411767SAnurag.Maskey@Sun.COM nwam_update_object_in_files_backend(char *filename, char *objname,
82511767SAnurag.Maskey@Sun.COM     uint64_t flags, void *proplist)
82611767SAnurag.Maskey@Sun.COM {
82711767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
82811767SAnurag.Maskey@Sun.COM 	void *objlist, *objnamelist;
82911767SAnurag.Maskey@Sun.COM 	char **object_names;
83011767SAnurag.Maskey@Sun.COM 	nwam_value_t value = NULL;
83111767SAnurag.Maskey@Sun.COM 	uint_t i, num_objects;
83211767SAnurag.Maskey@Sun.COM 
83311767SAnurag.Maskey@Sun.COM 	assert(filename != NULL);
83411767SAnurag.Maskey@Sun.COM 
83511767SAnurag.Maskey@Sun.COM 	/*  If we find existing object, fail if creation was specified */
83611767SAnurag.Maskey@Sun.COM 	if (flags & NWAM_FLAG_CREATE) {
83711767SAnurag.Maskey@Sun.COM 		char discard_objname[NWAM_MAX_NAME_LEN];
83811767SAnurag.Maskey@Sun.COM 		void *discard_objlist;
83911767SAnurag.Maskey@Sun.COM 
84011767SAnurag.Maskey@Sun.COM 		(void) strlcpy(discard_objname, objname,
84111767SAnurag.Maskey@Sun.COM 		    sizeof (discard_objname));
84211767SAnurag.Maskey@Sun.COM 		if ((err = nwam_read_object_from_files_backend(filename,
84311767SAnurag.Maskey@Sun.COM 		    discard_objname, 0, &discard_objlist)) == NWAM_SUCCESS) {
84411767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(discard_objlist);
84511767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_EXISTS);
84611767SAnurag.Maskey@Sun.COM 		}
84711767SAnurag.Maskey@Sun.COM 	}
84811767SAnurag.Maskey@Sun.COM 
84911767SAnurag.Maskey@Sun.COM 	/* Get existing list of object names (if any) */
85011767SAnurag.Maskey@Sun.COM 	err = nwam_read_object_from_files_backend(filename, NULL, flags,
85111767SAnurag.Maskey@Sun.COM 	    &objnamelist);
85211767SAnurag.Maskey@Sun.COM 	switch (err) {
85311767SAnurag.Maskey@Sun.COM 	case NWAM_SUCCESS:
85411767SAnurag.Maskey@Sun.COM 		/*
85511767SAnurag.Maskey@Sun.COM 		 * For each object name on list other than the one to be
85611767SAnurag.Maskey@Sun.COM 		 * updated,  add an object list consisting of its properties.
85711767SAnurag.Maskey@Sun.COM 		 * The object to be updated (if any) will be added below.
85811767SAnurag.Maskey@Sun.COM 		 */
85911767SAnurag.Maskey@Sun.COM 		if ((err = nwam_alloc_object_list(&objlist)) != NWAM_SUCCESS) {
86011767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(objnamelist);
86111767SAnurag.Maskey@Sun.COM 			return (err);
86211767SAnurag.Maskey@Sun.COM 		}
86311767SAnurag.Maskey@Sun.COM 		if ((err = nwam_get_prop_value(objnamelist,
86411767SAnurag.Maskey@Sun.COM 		    NWAM_OBJECT_NAMES_STRING, &value)) != NWAM_SUCCESS ||
86511767SAnurag.Maskey@Sun.COM 		    (err = nwam_value_get_string_array(value, &object_names,
86611767SAnurag.Maskey@Sun.COM 		    &num_objects)) != NWAM_SUCCESS) {
86711767SAnurag.Maskey@Sun.COM 			nwam_value_free(value);
86811767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(objnamelist);
86911767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(objlist);
87011767SAnurag.Maskey@Sun.COM 			return (err);
87111767SAnurag.Maskey@Sun.COM 		}
87211767SAnurag.Maskey@Sun.COM 		nwam_free_object_list(objnamelist);
87311767SAnurag.Maskey@Sun.COM 
87411767SAnurag.Maskey@Sun.COM 		for (i = 0; i < num_objects; i++) {
87511767SAnurag.Maskey@Sun.COM 			void *oproplist = NULL;
87611767SAnurag.Maskey@Sun.COM 
87711767SAnurag.Maskey@Sun.COM 			if (objname != NULL &&
87811767SAnurag.Maskey@Sun.COM 			    strcmp(objname, object_names[i]) == 0)
87911767SAnurag.Maskey@Sun.COM 					continue;
88011767SAnurag.Maskey@Sun.COM 
88111767SAnurag.Maskey@Sun.COM 			if ((err = nwam_read_object_from_files_backend(filename,
88211767SAnurag.Maskey@Sun.COM 			    object_names[i], flags, &oproplist))
88311767SAnurag.Maskey@Sun.COM 			    != NWAM_SUCCESS ||
88411767SAnurag.Maskey@Sun.COM 			    (err = nwam_object_list_add_object_list(objlist,
88511767SAnurag.Maskey@Sun.COM 			    object_names[i], oproplist)) != NWAM_SUCCESS) {
88611767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(oproplist);
88711767SAnurag.Maskey@Sun.COM 				nwam_free_object_list(objlist);
88811767SAnurag.Maskey@Sun.COM 				nwam_value_free(value);
88911767SAnurag.Maskey@Sun.COM 				return (err);
89011767SAnurag.Maskey@Sun.COM 			}
89111767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(oproplist);
89211767SAnurag.Maskey@Sun.COM 		}
89311767SAnurag.Maskey@Sun.COM 		nwam_value_free(value);
89411767SAnurag.Maskey@Sun.COM 		break;
89511767SAnurag.Maskey@Sun.COM 
89611767SAnurag.Maskey@Sun.COM 	case NWAM_ENTITY_NOT_FOUND:
89711767SAnurag.Maskey@Sun.COM 		/*
89811767SAnurag.Maskey@Sun.COM 		 * Just need to write/remove this single object.
89911767SAnurag.Maskey@Sun.COM 		 */
90011767SAnurag.Maskey@Sun.COM 		return (nwam_write_object_to_files_backend(filename, objname,
90111767SAnurag.Maskey@Sun.COM 		    flags, proplist));
90211767SAnurag.Maskey@Sun.COM 
90311767SAnurag.Maskey@Sun.COM 	default:
90411767SAnurag.Maskey@Sun.COM 		return (err);
90511767SAnurag.Maskey@Sun.COM 	}
90611767SAnurag.Maskey@Sun.COM 
90711767SAnurag.Maskey@Sun.COM 	/*
90811767SAnurag.Maskey@Sun.COM 	 * Add the object to be updated to our list of objects if the
90911767SAnurag.Maskey@Sun.COM 	 * property list is non-NULL (NULL signifies remove the object).
91011767SAnurag.Maskey@Sun.COM 	 */
91111767SAnurag.Maskey@Sun.COM 	if (objname != NULL && proplist != NULL) {
91211767SAnurag.Maskey@Sun.COM 		if ((err = nwam_object_list_add_object_list(objlist,
91311767SAnurag.Maskey@Sun.COM 		    (char *)objname, proplist)) != NWAM_SUCCESS) {
91411767SAnurag.Maskey@Sun.COM 			nwam_free_object_list(objlist);
91511767SAnurag.Maskey@Sun.COM 			return (err);
91611767SAnurag.Maskey@Sun.COM 		}
91711767SAnurag.Maskey@Sun.COM 	}
91811767SAnurag.Maskey@Sun.COM 
91911767SAnurag.Maskey@Sun.COM 	err = nwam_write_object_to_files_backend(filename, NULL, flags,
92011767SAnurag.Maskey@Sun.COM 	    objlist);
92111767SAnurag.Maskey@Sun.COM 
92211767SAnurag.Maskey@Sun.COM 	nwam_free_object_list(objlist);
92311767SAnurag.Maskey@Sun.COM 
92411767SAnurag.Maskey@Sun.COM 	return (err);
92511767SAnurag.Maskey@Sun.COM }
92611767SAnurag.Maskey@Sun.COM 
92711767SAnurag.Maskey@Sun.COM /*
92811767SAnurag.Maskey@Sun.COM  * Remove specified object from file by reading in the list of objects,
92911767SAnurag.Maskey@Sun.COM  * removing objname and writing the remainder.
93011767SAnurag.Maskey@Sun.COM  */
93111767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_remove_object_from_files_backend(char * filename,char * objname,uint64_t flags)93211767SAnurag.Maskey@Sun.COM nwam_remove_object_from_files_backend(char *filename, char *objname,
93311767SAnurag.Maskey@Sun.COM     uint64_t flags)
93411767SAnurag.Maskey@Sun.COM {
93511767SAnurag.Maskey@Sun.COM 	int uerr;
93611767SAnurag.Maskey@Sun.COM 
93711767SAnurag.Maskey@Sun.COM 	assert(filename != NULL);
93811767SAnurag.Maskey@Sun.COM 
93911767SAnurag.Maskey@Sun.COM 	if (objname == NULL) {
94011767SAnurag.Maskey@Sun.COM 		/*
94111767SAnurag.Maskey@Sun.COM 		 * NULL objname signifies remove file.
94211767SAnurag.Maskey@Sun.COM 		 */
94311767SAnurag.Maskey@Sun.COM 		uerr = unlink(filename);
94411767SAnurag.Maskey@Sun.COM 		if (uerr != 0)
94511767SAnurag.Maskey@Sun.COM 			return (nwam_errno_to_nwam_error(errno));
94611767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
94711767SAnurag.Maskey@Sun.COM 	}
94811767SAnurag.Maskey@Sun.COM 
94911767SAnurag.Maskey@Sun.COM 	return (nwam_update_object_in_files_backend(filename, objname, flags,
95011767SAnurag.Maskey@Sun.COM 	    NULL));
95111767SAnurag.Maskey@Sun.COM }
952