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) {
3226ba597c5SAnurag S. Maskey 				for (i = 0; i < nelem; i++)
3236ba597c5SAnurag S. Maskey 					free(newvalstr[i]);
3246ba597c5SAnurag S. Maskey 				free(newvalstr);
3256ba597c5SAnurag S. Maskey 				nwam_value_free(val);
3266ba597c5SAnurag S. Maskey 				nwam_free_object_list(*((char **)proplist));
3276ba597c5SAnurag S. Maskey 				return (err);
3286ba597c5SAnurag S. Maskey 			}
3296ba597c5SAnurag S. Maskey 			for (i = 0; i < nelem; i++)
3306ba597c5SAnurag S. Maskey 				free(newvalstr[i]);
3316ba597c5SAnurag S. Maskey 			free(newvalstr);
3326ba597c5SAnurag S. Maskey 			nwam_value_free(val);
3336ba597c5SAnurag S. Maskey 			break;
3346ba597c5SAnurag S. Maskey 		}
3356ba597c5SAnurag S. Maskey 		prop = nextprop;
3366ba597c5SAnurag S. Maskey 	}
3376ba597c5SAnurag S. Maskey 
3386ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
3396ba597c5SAnurag S. Maskey }
3406ba597c5SAnurag S. Maskey 
3416ba597c5SAnurag S. Maskey /*
3426ba597c5SAnurag S. Maskey  * Create list of NCP files used for walk of NCPs and for case-insensitive
3436ba597c5SAnurag S. Maskey  * matching of NCP name to file.
3446ba597c5SAnurag S. Maskey  */
3456ba597c5SAnurag S. Maskey static nwam_error_t
create_ncp_file_list(char *** ncpfilesp,uint_t * num_filesp)3466ba597c5SAnurag S. Maskey create_ncp_file_list(char ***ncpfilesp, uint_t *num_filesp)
3476ba597c5SAnurag S. Maskey {
3486ba597c5SAnurag S. Maskey 	DIR *dirp = NULL;
3496ba597c5SAnurag S. Maskey 	struct dirent *dp;
3506ba597c5SAnurag S. Maskey 	char *ncpname, **ncpfiles = NULL;
3516ba597c5SAnurag S. Maskey 	nwam_error_t err = NWAM_SUCCESS;
3526ba597c5SAnurag S. Maskey 	uint_t i;
3536ba597c5SAnurag S. Maskey 
3546ba597c5SAnurag S. Maskey 	ncpfiles = calloc(NWAM_MAX_NUM_OBJECTS, sizeof (char *));
3556ba597c5SAnurag S. Maskey 	if (ncpfiles == NULL)
3566ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
3576ba597c5SAnurag S. Maskey 	*num_filesp = 0;
3586ba597c5SAnurag S. Maskey 
3596ba597c5SAnurag S. Maskey 	/*
3606ba597c5SAnurag S. Maskey 	 * Construct NCP list by finding all files in NWAM directory
3616ba597c5SAnurag S. Maskey 	 * that match the NCP filename format.
3626ba597c5SAnurag S. Maskey 	 */
3636ba597c5SAnurag S. Maskey 	if ((dirp = opendir(NWAM_CONF_DIR)) == NULL) {
3646ba597c5SAnurag S. Maskey 		err = nwam_errno_to_nwam_error(errno);
3656ba597c5SAnurag S. Maskey 		goto done;
3666ba597c5SAnurag S. Maskey 	}
3676ba597c5SAnurag S. Maskey 
3686ba597c5SAnurag S. Maskey 	while ((dp = readdir(dirp)) != NULL) {
3696ba597c5SAnurag S. Maskey 		uint_t filenamelen;
3706ba597c5SAnurag S. Maskey 
3716ba597c5SAnurag S. Maskey 		/* Ensure filename is valid */
3726ba597c5SAnurag S. Maskey 		if (nwam_ncp_file_to_name(dp->d_name, &ncpname) != NWAM_SUCCESS)
3736ba597c5SAnurag S. Maskey 			continue;
3746ba597c5SAnurag S. Maskey 		free(ncpname);
3756ba597c5SAnurag S. Maskey 		filenamelen = strlen(NWAM_CONF_DIR) + strlen(dp->d_name) + 1;
3766ba597c5SAnurag S. Maskey 		if ((ncpfiles[*num_filesp] = malloc(filenamelen)) == NULL) {
3776ba597c5SAnurag S. Maskey 			err = NWAM_NO_MEMORY;
3786ba597c5SAnurag S. Maskey 			goto done;
3796ba597c5SAnurag S. Maskey 		}
3806ba597c5SAnurag S. Maskey 		(void) strlcpy(ncpfiles[*num_filesp], NWAM_CONF_DIR,
3816ba597c5SAnurag S. Maskey 		    strlen(NWAM_CONF_DIR) + 1);
3826ba597c5SAnurag S. Maskey 		(void) strlcpy(ncpfiles[*num_filesp] + strlen(NWAM_CONF_DIR),
3836ba597c5SAnurag S. Maskey 		    dp->d_name, filenamelen - strlen(NWAM_CONF_DIR));
3846ba597c5SAnurag S. Maskey 		(*num_filesp)++;
3856ba597c5SAnurag S. Maskey 	}
3866ba597c5SAnurag S. Maskey done:
3876ba597c5SAnurag S. Maskey 	if (dirp != NULL)
3886ba597c5SAnurag S. Maskey 		(void) closedir(dirp);
3896ba597c5SAnurag S. Maskey 
3906ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
3916ba597c5SAnurag S. Maskey 		for (i = 0; i < *num_filesp; i++)
3926ba597c5SAnurag S. Maskey 			free(ncpfiles[i]);
3936ba597c5SAnurag S. Maskey 		free(ncpfiles);
3946ba597c5SAnurag S. Maskey 	} else {
3956ba597c5SAnurag S. Maskey 		*ncpfilesp = realloc(ncpfiles, sizeof (char *) * (*num_filesp));
396*69b43529SMichael Hunter 		if (*num_filesp != 0 && *ncpfilesp == NULL)
3976ba597c5SAnurag S. Maskey 			err = NWAM_NO_MEMORY;
3986ba597c5SAnurag S. Maskey 	}
3996ba597c5SAnurag S. Maskey 	return (err);
4006ba597c5SAnurag S. Maskey }
4016ba597c5SAnurag S. Maskey 
4026ba597c5SAnurag S. Maskey /*
4036ba597c5SAnurag S. Maskey  * Read object specified by objname from file, converting it to
4046ba597c5SAnurag S. Maskey  * an object list.  If filename is NULL, a list of configuration object
4056ba597c5SAnurag S. Maskey  * containers is returned, represented as an object lists with elements "enms"
4066ba597c5SAnurag S. Maskey  * "locs" and "ncps". Each of these is a list of configuration files for each
4076ba597c5SAnurag S. Maskey  * object. This corresponds to the enm.conf file, loc.conf file and list of
4086ba597c5SAnurag S. Maskey  * ncp conf files. If objname is NULL, read all objects, and create
4096ba597c5SAnurag S. Maskey  * an nvlist with one element - "object-list" - which has as its values
4106ba597c5SAnurag S. Maskey  * the names of the objects found.  Otherwise obj points to an object list
4116ba597c5SAnurag S. Maskey  * of properties for the first object in the file that case-insensitively
4126ba597c5SAnurag S. Maskey  * matches objname.  We write the found name into objname so that it can be
4136ba597c5SAnurag S. Maskey  * returned to the caller (and set in the object handle).
4146ba597c5SAnurag S. Maskey  */
4156ba597c5SAnurag S. Maskey /* ARGSUSED2 */
4166ba597c5SAnurag S. Maskey nwam_error_t
nwam_read_object_from_files_backend(char * filename,char * objname,uint64_t flags,void * obj)4176ba597c5SAnurag S. Maskey nwam_read_object_from_files_backend(char *filename, char *objname,
4186ba597c5SAnurag S. Maskey     uint64_t flags, void *obj)
4196ba597c5SAnurag S. Maskey {
4206ba597c5SAnurag S. Maskey 	char line[NWAM_FILE_LINE_MAX];
4216ba597c5SAnurag S. Maskey 	char *cp, *foundobjname, **objnames = NULL, **ncpfiles = NULL;
4226ba597c5SAnurag S. Maskey 	uint_t num_files = 0;
4236ba597c5SAnurag S. Maskey 	FILE *fp = NULL;
4246ba597c5SAnurag S. Maskey 	nwam_error_t err;
4256ba597c5SAnurag S. Maskey 	void *objlist = NULL, *proplist = NULL;
4266ba597c5SAnurag S. Maskey 	uint_t i = 0, j = 0;
4276ba597c5SAnurag S. Maskey 	nwam_value_t objnamesval = NULL;
4286ba597c5SAnurag S. Maskey 
4296ba597c5SAnurag S. Maskey 	assert(obj != NULL);
4306ba597c5SAnurag S. Maskey 
4316ba597c5SAnurag S. Maskey 	*((char **)obj) = NULL;
4326ba597c5SAnurag S. Maskey 
4336ba597c5SAnurag S. Maskey 	if (filename == NULL) {
4346ba597c5SAnurag S. Maskey 		nwam_value_t enmval = NULL, locval = NULL, ncpval = NULL;
4356ba597c5SAnurag S. Maskey 
4366ba597c5SAnurag S. Maskey 		/*
4376ba597c5SAnurag S. Maskey 		 * When the filename is not specified, it signifies a
4386ba597c5SAnurag S. Maskey 		 * request for the list of configuration object containers -
4396ba597c5SAnurag S. Maskey 		 * in this case files.
4406ba597c5SAnurag S. Maskey 		 *
4416ba597c5SAnurag S. Maskey 		 * A list of all object files is returned. For ENMs
4426ba597c5SAnurag S. Maskey 		 * and locations, only the default loc.conf and enm.conf
4436ba597c5SAnurag S. Maskey 		 * files are used, but for NCPs we need to walk the
4446ba597c5SAnurag S. Maskey 		 * files in the NWAM directory retrieving each one that
4456ba597c5SAnurag S. Maskey 		 * matches the NCP pattern.
4466ba597c5SAnurag S. Maskey 		 */
4476ba597c5SAnurag S. Maskey 		if ((err = nwam_alloc_object_list(&objlist)) != NWAM_SUCCESS)
4486ba597c5SAnurag S. Maskey 			return (err);
4496ba597c5SAnurag S. Maskey 
4506ba597c5SAnurag S. Maskey 		if ((err = nwam_value_create_string(NWAM_ENM_CONF_FILE,
4516ba597c5SAnurag S. Maskey 		    &enmval)) != NWAM_SUCCESS ||
4526ba597c5SAnurag S. Maskey 		    (err = nwam_value_create_string(NWAM_LOC_CONF_FILE,
4536ba597c5SAnurag S. Maskey 		    &locval)) != NWAM_SUCCESS ||
4546ba597c5SAnurag S. Maskey 		    (err = nwam_set_prop_value(objlist, NWAM_ENM_OBJECT_STRING,
4556ba597c5SAnurag S. Maskey 		    enmval)) != NWAM_SUCCESS ||
4566ba597c5SAnurag S. Maskey 		    (err = nwam_set_prop_value(objlist, NWAM_LOC_OBJECT_STRING,
4576ba597c5SAnurag S. Maskey 		    locval)) != NWAM_SUCCESS)
4586ba597c5SAnurag S. Maskey 			goto done_with_containers;
4596ba597c5SAnurag S. Maskey 
4606ba597c5SAnurag S. Maskey 		/*
4616ba597c5SAnurag S. Maskey 		 * Construct NCP list by finding all files in NWAM directory
4626ba597c5SAnurag S. Maskey 		 * that match the NCP filename format.
4636ba597c5SAnurag S. Maskey 		 */
4646ba597c5SAnurag S. Maskey 		if ((err = create_ncp_file_list(&ncpfiles, &num_files))
4656ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS)
4666ba597c5SAnurag S. Maskey 			goto done_with_containers;
4676ba597c5SAnurag S. Maskey 
4686ba597c5SAnurag S. Maskey 		if ((err = nwam_value_create_string_array(ncpfiles, num_files,
4696ba597c5SAnurag S. Maskey 		    &ncpval)) == NWAM_SUCCESS) {
4706ba597c5SAnurag S. Maskey 			err = nwam_set_prop_value(objlist,
4716ba597c5SAnurag S. Maskey 			    NWAM_NCP_OBJECT_STRING, ncpval);
4726ba597c5SAnurag S. Maskey 		}
4736ba597c5SAnurag S. Maskey 
4746ba597c5SAnurag S. Maskey done_with_containers:
4756ba597c5SAnurag S. Maskey 		nwam_value_free(enmval);
4766ba597c5SAnurag S. Maskey 		nwam_value_free(locval);
4776ba597c5SAnurag S. Maskey 		nwam_value_free(ncpval);
4786ba597c5SAnurag S. Maskey 		if (ncpfiles != NULL) {
4796ba597c5SAnurag S. Maskey 			for (j = 0; j < num_files; j++)
4806ba597c5SAnurag S. Maskey 				free(ncpfiles[j]);
4816ba597c5SAnurag S. Maskey 			free(ncpfiles);
4826ba597c5SAnurag S. Maskey 		}
4836ba597c5SAnurag S. Maskey 		if (err != NWAM_SUCCESS)
4846ba597c5SAnurag S. Maskey 			nwam_free_object_list(objlist);
4856ba597c5SAnurag S. Maskey 		else
4866ba597c5SAnurag S. Maskey 			*((char **)obj) = objlist;
4876ba597c5SAnurag S. Maskey 		return (err);
4886ba597c5SAnurag S. Maskey 	}
4896ba597c5SAnurag S. Maskey 
4906ba597c5SAnurag S. Maskey 	if (objname == NULL) {
4916ba597c5SAnurag S. Maskey 		/* Allocate string array to store object names */
4926ba597c5SAnurag S. Maskey 		if ((objnames = calloc(NWAM_MAX_NUM_OBJECTS, sizeof (char *)))
4936ba597c5SAnurag S. Maskey 		    == NULL)
4946ba597c5SAnurag S. Maskey 			return (NWAM_NO_MEMORY);
4956ba597c5SAnurag S. Maskey 	}
4966ba597c5SAnurag S. Maskey 
4976ba597c5SAnurag S. Maskey 	fp = fopen(filename, "r");
4986ba597c5SAnurag S. Maskey 	if (fp == NULL) {
4996ba597c5SAnurag S. Maskey 		if (errno != ENOENT) {
5006ba597c5SAnurag S. Maskey 			if (objname == NULL)
5016ba597c5SAnurag S. Maskey 				free(objnames);
5026ba597c5SAnurag S. Maskey 			return (NWAM_ERROR_INTERNAL);
5036ba597c5SAnurag S. Maskey 		}
5046ba597c5SAnurag S. Maskey 
5056ba597c5SAnurag S. Maskey 		/*
5066ba597c5SAnurag S. Maskey 		 * Check NCP file list in case filename passed in was derived
5076ba597c5SAnurag S. Maskey 		 * from a case-insensitive NCP name.
5086ba597c5SAnurag S. Maskey 		 */
5096ba597c5SAnurag S. Maskey 		if ((err = create_ncp_file_list(&ncpfiles, &num_files))
5106ba597c5SAnurag S. Maskey 		    == NWAM_SUCCESS) {
5116ba597c5SAnurag S. Maskey 			for (j = 0; j < num_files; j++) {
5126ba597c5SAnurag S. Maskey 				if (strcasecmp(ncpfiles[j], filename) == 0) {
5136ba597c5SAnurag S. Maskey 					fp = fopen(ncpfiles[j], "r");
5146ba597c5SAnurag S. Maskey 					if (fp != NULL) {
5156ba597c5SAnurag S. Maskey 						/* Copy real filename back */
5166ba597c5SAnurag S. Maskey 						(void) strlcpy(filename,
5176ba597c5SAnurag S. Maskey 						    ncpfiles[j],
5186ba597c5SAnurag S. Maskey 						    strlen(filename) + 1);
5196ba597c5SAnurag S. Maskey 						break;
5206ba597c5SAnurag S. Maskey 					}
5216ba597c5SAnurag S. Maskey 				}
5226ba597c5SAnurag S. Maskey 			}
5236ba597c5SAnurag S. Maskey 			for (j = 0; j < num_files; j++)
5246ba597c5SAnurag S. Maskey 				free(ncpfiles[j]);
5256ba597c5SAnurag S. Maskey 			free(ncpfiles);
5266ba597c5SAnurag S. Maskey 		}
5276ba597c5SAnurag S. Maskey 		/* Return NOT_FOUND if file not found */
5286ba597c5SAnurag S. Maskey 		if (fp == NULL) {
5296ba597c5SAnurag S. Maskey 			if (objname == NULL)
5306ba597c5SAnurag S. Maskey 				free(objnames);
5316ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_NOT_FOUND);
5326ba597c5SAnurag S. Maskey 		}
5336ba597c5SAnurag S. Maskey 	}
5346ba597c5SAnurag S. Maskey 
5356ba597c5SAnurag S. Maskey 	while (fgets(line, sizeof (line), fp) != NULL) {
5366ba597c5SAnurag S. Maskey 		if (line[strlen(line) - 1] == '\n')
5376ba597c5SAnurag S. Maskey 			line[strlen(line) - 1] = '\0';
5386ba597c5SAnurag S. Maskey 
5396ba597c5SAnurag S. Maskey 		cp = line;
5406ba597c5SAnurag S. Maskey 
5416ba597c5SAnurag S. Maskey 		while (isspace(*cp))
5426ba597c5SAnurag S. Maskey 			cp++;
5436ba597c5SAnurag S. Maskey 
5446ba597c5SAnurag S. Maskey 		if (*cp == '#' || *cp == '\0')
5456ba597c5SAnurag S. Maskey 			continue;
5466ba597c5SAnurag S. Maskey 
5476ba597c5SAnurag S. Maskey 		if ((err = nwam_line_to_object(cp, &foundobjname, &proplist))
5486ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS)
5496ba597c5SAnurag S. Maskey 			goto done;
5506ba597c5SAnurag S. Maskey 
5516ba597c5SAnurag S. Maskey 		if (objname != NULL) {
5526ba597c5SAnurag S. Maskey 			/*
5536ba597c5SAnurag S. Maskey 			 * Is this the specified object?  If so set objname and
5546ba597c5SAnurag S. Maskey 			 * obj and bail.
5556ba597c5SAnurag S. Maskey 			 */
5566ba597c5SAnurag S. Maskey 			if (strcasecmp(objname, foundobjname) == 0) {
5576ba597c5SAnurag S. Maskey 				*((char **)obj) = proplist;
5586ba597c5SAnurag S. Maskey 				(void) strlcpy(objname, foundobjname,
5596ba597c5SAnurag S. Maskey 				    NWAM_MAX_NAME_LEN);
5606ba597c5SAnurag S. Maskey 				break;
5616ba597c5SAnurag S. Maskey 			} else {
5626ba597c5SAnurag S. Maskey 				nwam_free_object_list(proplist);
5636ba597c5SAnurag S. Maskey 			}
5646ba597c5SAnurag S. Maskey 		} else {
5656ba597c5SAnurag S. Maskey 			objnames[i] = strdup(foundobjname);
5666ba597c5SAnurag S. Maskey 			nwam_free_object_list(proplist);
5676ba597c5SAnurag S. Maskey 			if (objnames[i] == NULL) {
5686ba597c5SAnurag S. Maskey 				err = NWAM_NO_MEMORY;
5696ba597c5SAnurag S. Maskey 				goto done;
5706ba597c5SAnurag S. Maskey 			}
5716ba597c5SAnurag S. Maskey 			i++;
5726ba597c5SAnurag S. Maskey 		}
5736ba597c5SAnurag S. Maskey 
5746ba597c5SAnurag S. Maskey 	}
5756ba597c5SAnurag S. Maskey 	if (objname == NULL) {
5766ba597c5SAnurag S. Maskey 		/*
5776ba597c5SAnurag S. Maskey 		 * Allocate object list with one value named
5786ba597c5SAnurag S. Maskey 		 * NWAM_OBJECT_NAMES_STRING - it's values are the names of
5796ba597c5SAnurag S. Maskey 		 * the objects found.
5806ba597c5SAnurag S. Maskey 		 */
5816ba597c5SAnurag S. Maskey 		if ((err = nwam_alloc_object_list(&objlist)) == NWAM_SUCCESS &&
5826ba597c5SAnurag S. Maskey 		    (err = nwam_value_create_string_array(objnames, i,
5836ba597c5SAnurag S. Maskey 		    &objnamesval)) == NWAM_SUCCESS) {
5846ba597c5SAnurag S. Maskey 			err = nwam_set_prop_value(objlist,
5856ba597c5SAnurag S. Maskey 			    NWAM_OBJECT_NAMES_STRING, objnamesval);
5866ba597c5SAnurag S. Maskey 		}
5876ba597c5SAnurag S. Maskey 	}
5886ba597c5SAnurag S. Maskey 
5896ba597c5SAnurag S. Maskey done:
5906ba597c5SAnurag S. Maskey 	if (fp != NULL)
5916ba597c5SAnurag S. Maskey 		(void) fclose(fp);
5926ba597c5SAnurag S. Maskey 
5936ba597c5SAnurag S. Maskey 	/*
5946ba597c5SAnurag S. Maskey 	 * We're done, either we have success, and return our object list
5956ba597c5SAnurag S. Maskey 	 * containing object names, or we have failure and we need to free
5966ba597c5SAnurag S. Maskey 	 * the object list.
5976ba597c5SAnurag S. Maskey 	 */
5986ba597c5SAnurag S. Maskey 	if (objname == NULL) {
5996ba597c5SAnurag S. Maskey 		for (j = 0; j < i; j++)
6006ba597c5SAnurag S. Maskey 			free(objnames[j]);
6016ba597c5SAnurag S. Maskey 		free(objnames);
6026ba597c5SAnurag S. Maskey 		nwam_value_free(objnamesval);
6036ba597c5SAnurag S. Maskey 		if (err == NWAM_SUCCESS) {
6046ba597c5SAnurag S. Maskey 			*((char **)obj) = objlist;
6056ba597c5SAnurag S. Maskey 		} else {
6066ba597c5SAnurag S. Maskey 			*((char **)obj) = NULL;
6076ba597c5SAnurag S. Maskey 			nwam_free_object_list(objlist);
6086ba597c5SAnurag S. Maskey 		}
6096ba597c5SAnurag S. Maskey 	} else {
6106ba597c5SAnurag S. Maskey 		/* Check if to-be-read object was not found */
6116ba597c5SAnurag S. Maskey 		if (*((char **)obj) == NULL && err == NWAM_SUCCESS)
6126ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_NOT_FOUND);
6136ba597c5SAnurag S. Maskey 	}
6146ba597c5SAnurag S. Maskey 
6156ba597c5SAnurag S. Maskey 	return (err);
6166ba597c5SAnurag S. Maskey }
6176ba597c5SAnurag S. Maskey 
6186ba597c5SAnurag S. Maskey nwam_error_t
nwam_object_to_line(FILE * fp,const char * objname,void * proplist)6196ba597c5SAnurag S. Maskey nwam_object_to_line(FILE *fp, const char *objname, void *proplist)
6206ba597c5SAnurag S. Maskey {
6216ba597c5SAnurag S. Maskey 	char *propname, *lastpropname = NULL;
6226ba597c5SAnurag S. Maskey 	boolean_t *valbool;
6236ba597c5SAnurag S. Maskey 	int64_t *valint;
6246ba597c5SAnurag S. Maskey 	uint64_t *valuint;
6256ba597c5SAnurag S. Maskey 	char **valstr;
6266ba597c5SAnurag S. Maskey 	uint_t nelem, i;
6276ba597c5SAnurag S. Maskey 	nwam_value_t val;
6286ba597c5SAnurag S. Maskey 	nwam_value_type_t type;
6296ba597c5SAnurag S. Maskey 
6306ba597c5SAnurag S. Maskey 	(void) fprintf(fp, "%s\t", objname);
6316ba597c5SAnurag S. Maskey 
6326ba597c5SAnurag S. Maskey 	while (nwam_next_object_prop(proplist, lastpropname, &propname, &val)
6336ba597c5SAnurag S. Maskey 	    == NWAM_SUCCESS) {
6346ba597c5SAnurag S. Maskey 
6356ba597c5SAnurag S. Maskey 		(void) fprintf(fp, "%s%c", propname, NWAM_FILE_PROP_ASSIGN);
6366ba597c5SAnurag S. Maskey 
6376ba597c5SAnurag S. Maskey 		if (nwam_value_get_type(val, &type) != NWAM_SUCCESS)
6386ba597c5SAnurag S. Maskey 			return (NWAM_INVALID_ARG);
6396ba597c5SAnurag S. Maskey 
6406ba597c5SAnurag S. Maskey 		switch (type) {
6416ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_BOOLEAN:
6426ba597c5SAnurag S. Maskey 			(void) fprintf(fp, "%s",
6436ba597c5SAnurag S. Maskey 			    nwam_value_type_to_string(NWAM_VALUE_TYPE_BOOLEAN));
6446ba597c5SAnurag S. Maskey 			if (nwam_value_get_boolean_array(val, &valbool, &nelem)
6456ba597c5SAnurag S. Maskey 			    != NWAM_SUCCESS) {
6466ba597c5SAnurag S. Maskey 				nwam_value_free(val);
6476ba597c5SAnurag S. Maskey 				return (NWAM_INVALID_ARG);
6486ba597c5SAnurag S. Maskey 			}
6496ba597c5SAnurag S. Maskey 			for (i = 0; i < nelem; i++) {
6506ba597c5SAnurag S. Maskey 				(void) fprintf(fp, "%c",
6516ba597c5SAnurag S. Maskey 				    NWAM_FILE_VALUE_DELIMITER);
6526ba597c5SAnurag S. Maskey 				if (valbool[i]) {
6536ba597c5SAnurag S. Maskey 					(void) fprintf(fp,
6546ba597c5SAnurag S. Maskey 					    NWAM_FILE_BOOLEAN_TRUE);
6556ba597c5SAnurag S. Maskey 				} else {
6566ba597c5SAnurag S. Maskey 					(void) fprintf(fp,
6576ba597c5SAnurag S. Maskey 					    NWAM_FILE_BOOLEAN_FALSE);
6586ba597c5SAnurag S. Maskey 				}
6596ba597c5SAnurag S. Maskey 			}
6606ba597c5SAnurag S. Maskey 			break;
6616ba597c5SAnurag S. Maskey 
6626ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_INT64:
6636ba597c5SAnurag S. Maskey 			(void) fprintf(fp, "%s",
6646ba597c5SAnurag S. Maskey 			    nwam_value_type_to_string(NWAM_VALUE_TYPE_INT64));
6656ba597c5SAnurag S. Maskey 			if (nwam_value_get_int64_array(val, &valint, &nelem)
6666ba597c5SAnurag S. Maskey 			    != NWAM_SUCCESS) {
6676ba597c5SAnurag S. Maskey 				nwam_value_free(val);
6686ba597c5SAnurag S. Maskey 				return (NWAM_INVALID_ARG);
6696ba597c5SAnurag S. Maskey 			}
6706ba597c5SAnurag S. Maskey 			for (i = 0; i < nelem; i++) {
6716ba597c5SAnurag S. Maskey 				(void) fprintf(fp, "%c%lld",
6726ba597c5SAnurag S. Maskey 				    NWAM_FILE_VALUE_DELIMITER, valint[i]);
6736ba597c5SAnurag S. Maskey 			}
6746ba597c5SAnurag S. Maskey 			break;
6756ba597c5SAnurag S. Maskey 
6766ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_UINT64:
6776ba597c5SAnurag S. Maskey 			(void) fprintf(fp, "%s",
6786ba597c5SAnurag S. Maskey 			    nwam_value_type_to_string(NWAM_VALUE_TYPE_UINT64));
6796ba597c5SAnurag S. Maskey 			if (nwam_value_get_uint64_array(val, &valuint, &nelem)
6806ba597c5SAnurag S. Maskey 			    != NWAM_SUCCESS) {
6816ba597c5SAnurag S. Maskey 				nwam_value_free(val);
6826ba597c5SAnurag S. Maskey 				return (NWAM_INVALID_ARG);
6836ba597c5SAnurag S. Maskey 			}
6846ba597c5SAnurag S. Maskey 			for (i = 0; i < nelem; i++) {
6856ba597c5SAnurag S. Maskey 				(void) fprintf(fp, "%c%lld",
6866ba597c5SAnurag S. Maskey 				    NWAM_FILE_VALUE_DELIMITER, valuint[i]);
6876ba597c5SAnurag S. Maskey 			}
6886ba597c5SAnurag S. Maskey 			break;
6896ba597c5SAnurag S. Maskey 
6906ba597c5SAnurag S. Maskey 		case NWAM_VALUE_TYPE_STRING:
6916ba597c5SAnurag S. Maskey 			(void) fprintf(fp, "%s",
6926ba597c5SAnurag S. Maskey 			    nwam_value_type_to_string(NWAM_VALUE_TYPE_STRING));
6936ba597c5SAnurag S. Maskey 			if (nwam_value_get_string_array(val, &valstr, &nelem)
6946ba597c5SAnurag S. Maskey 			    != NWAM_SUCCESS) {
6956ba597c5SAnurag S. Maskey 				nwam_value_free(val);
6966ba597c5SAnurag S. Maskey 				return (NWAM_INVALID_ARG);
6976ba597c5SAnurag S. Maskey 			}
6986ba597c5SAnurag S. Maskey 			for (i = 0; i < nelem; i++) {
6996ba597c5SAnurag S. Maskey 				char evalstr[NWAM_MAX_VALUE_LEN];
7006ba597c5SAnurag S. Maskey 				/* Add escape chars as necessary */
7016ba597c5SAnurag S. Maskey 				value_add_escapes(valstr[i], evalstr);
7026ba597c5SAnurag S. Maskey 				(void) fprintf(fp, "%c%s",
7036ba597c5SAnurag S. Maskey 				    NWAM_FILE_VALUE_DELIMITER, evalstr);
7046ba597c5SAnurag S. Maskey 			}
7056ba597c5SAnurag S. Maskey 			break;
7066ba597c5SAnurag S. Maskey 		default:
7076ba597c5SAnurag S. Maskey 			nwam_value_free(val);
7086ba597c5SAnurag S. Maskey 			return (NWAM_INVALID_ARG);
7096ba597c5SAnurag S. Maskey 		}
7106ba597c5SAnurag S. Maskey 		nwam_value_free(val);
7116ba597c5SAnurag S. Maskey 		(void) fprintf(fp, "%c", NWAM_FILE_PROP_DELIMITER);
7126ba597c5SAnurag S. Maskey 
7136ba597c5SAnurag S. Maskey 		lastpropname = propname;
7146ba597c5SAnurag S. Maskey 
7156ba597c5SAnurag S. Maskey 	}
7166ba597c5SAnurag S. Maskey 	(void) fprintf(fp, "\n");
7176ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
7186ba597c5SAnurag S. Maskey }
7196ba597c5SAnurag S. Maskey 
7206ba597c5SAnurag S. Maskey /*
7216ba597c5SAnurag S. Maskey  * Write object specified by objname to file.  If objname is NULL, objlist
7226ba597c5SAnurag S. Maskey  * must be a list of lists, where each list corresponds to an
7236ba597c5SAnurag S. Maskey  * object to write to the file.  Otherwise objlist should point to a list of
7246ba597c5SAnurag S. Maskey  * properties for the object specified by objname.  The write operation is
7256ba597c5SAnurag S. Maskey  * first done to filename.new, and if this succeeds, the file is renamed to
7266ba597c5SAnurag S. Maskey  * filename.  Since rename(2) is atomic, this approach guarantees a complete
7276ba597c5SAnurag S. Maskey  * configuration will end up in filename as a result of an aborted operation.
7286ba597c5SAnurag S. Maskey  */
7296ba597c5SAnurag S. Maskey nwam_error_t
nwam_write_object_to_files_backend(const char * filename,const char * objname,uint64_t flags,void * objlist)7306ba597c5SAnurag S. Maskey nwam_write_object_to_files_backend(const char *filename, const char *objname,
7316ba597c5SAnurag S. Maskey     uint64_t flags, void *objlist)
7326ba597c5SAnurag S. Maskey {
7336ba597c5SAnurag S. Maskey 	void *proplist;
7346ba597c5SAnurag S. Maskey 	char *currobjname, *lastobjname = NULL;
7356ba597c5SAnurag S. Maskey 	int fd, cmd;
7366ba597c5SAnurag S. Maskey 	nwam_error_t err = NWAM_SUCCESS;
7376ba597c5SAnurag S. Maskey 	char *dir;
7386ba597c5SAnurag S. Maskey 	char tmpfilename[MAXPATHLEN], filename_copy[MAXPATHLEN];
7396ba597c5SAnurag S. Maskey 	FILE *fp;
7406ba597c5SAnurag S. Maskey 	mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
7416ba597c5SAnurag S. Maskey 	mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
7426ba597c5SAnurag S. Maskey 	struct flock fl = { F_WRLCK, SEEK_SET, 0, 0, 0};
7436ba597c5SAnurag S. Maskey 	struct flock fu = { F_UNLCK, SEEK_SET, 0, 0, 0};
7446ba597c5SAnurag S. Maskey 
7456ba597c5SAnurag S. Maskey 	assert(filename != NULL);
7466ba597c5SAnurag S. Maskey 
7476ba597c5SAnurag S. Maskey 	/* Create the directory in case it does not exist. */
7486ba597c5SAnurag S. Maskey 	(void) strlcpy(filename_copy, filename, MAXPATHLEN);
7496ba597c5SAnurag S. Maskey 	if ((dir = dirname(filename_copy)) == NULL)
7506ba597c5SAnurag S. Maskey 		return (nwam_errno_to_nwam_error(errno));
7516ba597c5SAnurag S. Maskey 	if (mkdir(dir, dirmode) != 0) {
7526ba597c5SAnurag S. Maskey 		if (errno != EEXIST)
7536ba597c5SAnurag S. Maskey 			return (nwam_errno_to_nwam_error(errno));
7546ba597c5SAnurag S. Maskey 	}
7556ba597c5SAnurag S. Maskey 
7566ba597c5SAnurag S. Maskey 	(void) snprintf(tmpfilename, MAXPATHLEN, "%s.new", filename);
7576ba597c5SAnurag S. Maskey 
7586ba597c5SAnurag S. Maskey 	if ((fd = open(tmpfilename, O_RDWR | O_CREAT | O_TRUNC, mode)) < 0)
7596ba597c5SAnurag S. Maskey 			return (nwam_errno_to_nwam_error(errno));
7606ba597c5SAnurag S. Maskey 
7616ba597c5SAnurag S. Maskey 	if ((fp = fdopen(fd, "w")) == NULL) {
7626ba597c5SAnurag S. Maskey 		err = nwam_errno_to_nwam_error(errno);
7636ba597c5SAnurag S. Maskey 		goto done;
7646ba597c5SAnurag S. Maskey 	}
7656ba597c5SAnurag S. Maskey 	/*
7666ba597c5SAnurag S. Maskey 	 * Need to lock filename.new to prevent multiple commits colliding
7676ba597c5SAnurag S. Maskey 	 * at this point.
7686ba597c5SAnurag S. Maskey 	 */
7696ba597c5SAnurag S. Maskey 	if (flags & NWAM_FLAG_BLOCKING)
7706ba597c5SAnurag S. Maskey 		cmd = F_SETLKW;
7716ba597c5SAnurag S. Maskey 	else
7726ba597c5SAnurag S. Maskey 		cmd = F_SETLK;
7736ba597c5SAnurag S. Maskey 	if (fcntl(fd, cmd, &fl) != 0) {
7746ba597c5SAnurag S. Maskey 		if (errno == EAGAIN)
7756ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_IN_USE);
7766ba597c5SAnurag S. Maskey 		else
7776ba597c5SAnurag S. Maskey 			return (NWAM_ERROR_INTERNAL);
7786ba597c5SAnurag S. Maskey 	}
7796ba597c5SAnurag S. Maskey 
7806ba597c5SAnurag S. Maskey 	if (objname != NULL) {
7816ba597c5SAnurag S. Maskey 		/* Only one object to write */
7826ba597c5SAnurag S. Maskey 		err = nwam_object_to_line(fp, objname, objlist);
7836ba597c5SAnurag S. Maskey 	} else {
7846ba597c5SAnurag S. Maskey 		if (objlist == NULL) {
7856ba597c5SAnurag S. Maskey 			err = NWAM_SUCCESS;
7866ba597c5SAnurag S. Maskey 			goto done;
7876ba597c5SAnurag S. Maskey 		}
7886ba597c5SAnurag S. Maskey 		/* Otherwise, write each object in turn. */
7896ba597c5SAnurag S. Maskey 		while ((err = nwam_next_object_list(objlist, lastobjname,
7906ba597c5SAnurag S. Maskey 		    &currobjname, &proplist)) == NWAM_SUCCESS) {
7916ba597c5SAnurag S. Maskey 			if ((err = nwam_object_to_line(fp, currobjname,
7926ba597c5SAnurag S. Maskey 			    proplist)) != NWAM_SUCCESS)
7936ba597c5SAnurag S. Maskey 				break;
7946ba597c5SAnurag S. Maskey 			lastobjname = currobjname;
7956ba597c5SAnurag S. Maskey 		}
7966ba597c5SAnurag S. Maskey 		if (err == NWAM_LIST_END)
7976ba597c5SAnurag S. Maskey 			err = NWAM_SUCCESS;
7986ba597c5SAnurag S. Maskey 	}
7996ba597c5SAnurag S. Maskey done:
8006ba597c5SAnurag S. Maskey 	if (err == NWAM_SUCCESS) {
8016ba597c5SAnurag S. Maskey 		if (rename(tmpfilename, filename) == 0) {
8026ba597c5SAnurag S. Maskey 			(void) fcntl(fd, F_SETLKW, &fu);
8036ba597c5SAnurag S. Maskey 			(void) fclose(fp);
8046ba597c5SAnurag S. Maskey 			return (NWAM_SUCCESS);
8056ba597c5SAnurag S. Maskey 		} else {
8066ba597c5SAnurag S. Maskey 			err = nwam_errno_to_nwam_error(errno);
8076ba597c5SAnurag S. Maskey 		}
8086ba597c5SAnurag S. Maskey 	}
8096ba597c5SAnurag S. Maskey 	(void) fcntl(fd, F_SETLKW, &fu);
8106ba597c5SAnurag S. Maskey 	(void) fclose(fp);
8116ba597c5SAnurag S. Maskey 	(void) unlink(tmpfilename);
8126ba597c5SAnurag S. Maskey 
8136ba597c5SAnurag S. Maskey 	return (err);
8146ba597c5SAnurag S. Maskey }
8156ba597c5SAnurag S. Maskey 
8166ba597c5SAnurag S. Maskey /*
8176ba597c5SAnurag S. Maskey  * Read in all objects from file and update object corresponding to objname
8186ba597c5SAnurag S. Maskey  * with properties recorded in proplist, and then write results to filename.
8196ba597c5SAnurag S. Maskey  * If objname is empty, no object needs to be updated.  If proplist is NULL,
8206ba597c5SAnurag S. Maskey  * object is to be removed (this is done by simply not adding it to the list
8216ba597c5SAnurag S. Maskey  * of objects).
8226ba597c5SAnurag S. Maskey  */
8236ba597c5SAnurag S. Maskey nwam_error_t
nwam_update_object_in_files_backend(char * filename,char * objname,uint64_t flags,void * proplist)8246ba597c5SAnurag S. Maskey nwam_update_object_in_files_backend(char *filename, char *objname,
8256ba597c5SAnurag S. Maskey     uint64_t flags, void *proplist)
8266ba597c5SAnurag S. Maskey {
8276ba597c5SAnurag S. Maskey 	nwam_error_t err;
8286ba597c5SAnurag S. Maskey 	void *objlist, *objnamelist;
8296ba597c5SAnurag S. Maskey 	char **object_names;
8306ba597c5SAnurag S. Maskey 	nwam_value_t value = NULL;
8316ba597c5SAnurag S. Maskey 	uint_t i, num_objects;
8326ba597c5SAnurag S. Maskey 
8336ba597c5SAnurag S. Maskey 	assert(filename != NULL);
8346ba597c5SAnurag S. Maskey 
8356ba597c5SAnurag S. Maskey 	/*  If we find existing object, fail if creation was specified */
8366ba597c5SAnurag S. Maskey 	if (flags & NWAM_FLAG_CREATE) {
8376ba597c5SAnurag S. Maskey 		char discard_objname[NWAM_MAX_NAME_LEN];
8386ba597c5SAnurag S. Maskey 		void *discard_objlist;
8396ba597c5SAnurag S. Maskey 
8406ba597c5SAnurag S. Maskey 		(void) strlcpy(discard_objname, objname,
8416ba597c5SAnurag S. Maskey 		    sizeof (discard_objname));
8426ba597c5SAnurag S. Maskey 		if ((err = nwam_read_object_from_files_backend(filename,
8436ba597c5SAnurag S. Maskey 		    discard_objname, 0, &discard_objlist)) == NWAM_SUCCESS) {
8446ba597c5SAnurag S. Maskey 			nwam_free_object_list(discard_objlist);
8456ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_EXISTS);
8466ba597c5SAnurag S. Maskey 		}
8476ba597c5SAnurag S. Maskey 	}
8486ba597c5SAnurag S. Maskey 
8496ba597c5SAnurag S. Maskey 	/* Get existing list of object names (if any) */
8506ba597c5SAnurag S. Maskey 	err = nwam_read_object_from_files_backend(filename, NULL, flags,
8516ba597c5SAnurag S. Maskey 	    &objnamelist);
8526ba597c5SAnurag S. Maskey 	switch (err) {
8536ba597c5SAnurag S. Maskey 	case NWAM_SUCCESS:
8546ba597c5SAnurag S. Maskey 		/*
8556ba597c5SAnurag S. Maskey 		 * For each object name on list other than the one to be
8566ba597c5SAnurag S. Maskey 		 * updated,  add an object list consisting of its properties.
8576ba597c5SAnurag S. Maskey 		 * The object to be updated (if any) will be added below.
8586ba597c5SAnurag S. Maskey 		 */
8596ba597c5SAnurag S. Maskey 		if ((err = nwam_alloc_object_list(&objlist)) != NWAM_SUCCESS) {
8606ba597c5SAnurag S. Maskey 			nwam_free_object_list(objnamelist);
8616ba597c5SAnurag S. Maskey 			return (err);
8626ba597c5SAnurag S. Maskey 		}
8636ba597c5SAnurag S. Maskey 		if ((err = nwam_get_prop_value(objnamelist,
8646ba597c5SAnurag S. Maskey 		    NWAM_OBJECT_NAMES_STRING, &value)) != NWAM_SUCCESS ||
8656ba597c5SAnurag S. Maskey 		    (err = nwam_value_get_string_array(value, &object_names,
8666ba597c5SAnurag S. Maskey 		    &num_objects)) != NWAM_SUCCESS) {
8676ba597c5SAnurag S. Maskey 			nwam_value_free(value);
8686ba597c5SAnurag S. Maskey 			nwam_free_object_list(objnamelist);
8696ba597c5SAnurag S. Maskey 			nwam_free_object_list(objlist);
8706ba597c5SAnurag S. Maskey 			return (err);
8716ba597c5SAnurag S. Maskey 		}
8726ba597c5SAnurag S. Maskey 		nwam_free_object_list(objnamelist);
8736ba597c5SAnurag S. Maskey 
8746ba597c5SAnurag S. Maskey 		for (i = 0; i < num_objects; i++) {
8756ba597c5SAnurag S. Maskey 			void *oproplist = NULL;
8766ba597c5SAnurag S. Maskey 
8776ba597c5SAnurag S. Maskey 			if (objname != NULL &&
8786ba597c5SAnurag S. Maskey 			    strcmp(objname, object_names[i]) == 0)
8796ba597c5SAnurag S. Maskey 					continue;
8806ba597c5SAnurag S. Maskey 
8816ba597c5SAnurag S. Maskey 			if ((err = nwam_read_object_from_files_backend(filename,
8826ba597c5SAnurag S. Maskey 			    object_names[i], flags, &oproplist))
8836ba597c5SAnurag S. Maskey 			    != NWAM_SUCCESS ||
8846ba597c5SAnurag S. Maskey 			    (err = nwam_object_list_add_object_list(objlist,
8856ba597c5SAnurag S. Maskey 			    object_names[i], oproplist)) != NWAM_SUCCESS) {
8866ba597c5SAnurag S. Maskey 				nwam_free_object_list(oproplist);
8876ba597c5SAnurag S. Maskey 				nwam_free_object_list(objlist);
8886ba597c5SAnurag S. Maskey 				nwam_value_free(value);
8896ba597c5SAnurag S. Maskey 				return (err);
8906ba597c5SAnurag S. Maskey 			}
8916ba597c5SAnurag S. Maskey 			nwam_free_object_list(oproplist);
8926ba597c5SAnurag S. Maskey 		}
8936ba597c5SAnurag S. Maskey 		nwam_value_free(value);
8946ba597c5SAnurag S. Maskey 		break;
8956ba597c5SAnurag S. Maskey 
8966ba597c5SAnurag S. Maskey 	case NWAM_ENTITY_NOT_FOUND:
8976ba597c5SAnurag S. Maskey 		/*
8986ba597c5SAnurag S. Maskey 		 * Just need to write/remove this single object.
8996ba597c5SAnurag S. Maskey 		 */
9006ba597c5SAnurag S. Maskey 		return (nwam_write_object_to_files_backend(filename, objname,
9016ba597c5SAnurag S. Maskey 		    flags, proplist));
9026ba597c5SAnurag S. Maskey 
9036ba597c5SAnurag S. Maskey 	default:
9046ba597c5SAnurag S. Maskey 		return (err);
9056ba597c5SAnurag S. Maskey 	}
9066ba597c5SAnurag S. Maskey 
9076ba597c5SAnurag S. Maskey 	/*
9086ba597c5SAnurag S. Maskey 	 * Add the object to be updated to our list of objects if the
9096ba597c5SAnurag S. Maskey 	 * property list is non-NULL (NULL signifies remove the object).
9106ba597c5SAnurag S. Maskey 	 */
9116ba597c5SAnurag S. Maskey 	if (objname != NULL && proplist != NULL) {
9126ba597c5SAnurag S. Maskey 		if ((err = nwam_object_list_add_object_list(objlist,
9136ba597c5SAnurag S. Maskey 		    (char *)objname, proplist)) != NWAM_SUCCESS) {
9146ba597c5SAnurag S. Maskey 			nwam_free_object_list(objlist);
9156ba597c5SAnurag S. Maskey 			return (err);
9166ba597c5SAnurag S. Maskey 		}
9176ba597c5SAnurag S. Maskey 	}
9186ba597c5SAnurag S. Maskey 
9196ba597c5SAnurag S. Maskey 	err = nwam_write_object_to_files_backend(filename, NULL, flags,
9206ba597c5SAnurag S. Maskey 	    objlist);
9216ba597c5SAnurag S. Maskey 
9226ba597c5SAnurag S. Maskey 	nwam_free_object_list(objlist);
9236ba597c5SAnurag S. Maskey 
9246ba597c5SAnurag S. Maskey 	return (err);
9256ba597c5SAnurag S. Maskey }
9266ba597c5SAnurag S. Maskey 
9276ba597c5SAnurag S. Maskey /*
9286ba597c5SAnurag S. Maskey  * Remove specified object from file by reading in the list of objects,
9296ba597c5SAnurag S. Maskey  * removing objname and writing the remainder.
9306ba597c5SAnurag S. Maskey  */
9316ba597c5SAnurag S. Maskey nwam_error_t
nwam_remove_object_from_files_backend(char * filename,char * objname,uint64_t flags)9326ba597c5SAnurag S. Maskey nwam_remove_object_from_files_backend(char *filename, char *objname,
9336ba597c5SAnurag S. Maskey     uint64_t flags)
9346ba597c5SAnurag S. Maskey {
9356ba597c5SAnurag S. Maskey 	int uerr;
9366ba597c5SAnurag S. Maskey 
9376ba597c5SAnurag S. Maskey 	assert(filename != NULL);
9386ba597c5SAnurag S. Maskey 
9396ba597c5SAnurag S. Maskey 	if (objname == NULL) {
9406ba597c5SAnurag S. Maskey 		/*
9416ba597c5SAnurag S. Maskey 		 * NULL objname signifies remove file.
9426ba597c5SAnurag S. Maskey 		 */
9436ba597c5SAnurag S. Maskey 		uerr = unlink(filename);
9446ba597c5SAnurag S. Maskey 		if (uerr != 0)
9456ba597c5SAnurag S. Maskey 			return (nwam_errno_to_nwam_error(errno));
9466ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
9476ba597c5SAnurag S. Maskey 	}
9486ba597c5SAnurag S. Maskey 
9496ba597c5SAnurag S. Maskey 	return (nwam_update_object_in_files_backend(filename, objname, flags,
9506ba597c5SAnurag S. Maskey 	    NULL));
9516ba597c5SAnurag S. Maskey }
952