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