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 * 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 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 * 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 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 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 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 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 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 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 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