/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <libdladm_impl.h>
#include <libdlflow_impl.h>
/*
* XXX duplicate defines
*/
static void
{
}
}
}
/*
* Generate an entry in the property database.
* Each entry has this format:
* <name> <prop0>=<val0>,...,<valn>;...;<propn>=<val0>,...,<valn>;
*/
static void
{
/*
* Delete line if there are no properties left.
*/
buf[0] = '\0';
return;
}
/*
* Skip properties without values.
*/
continue;
}
}
return;
}
}
/*
* This function is used to update or create an entry in the persistent db.
* process_prop_db() will first scan the db for an entry matching the
* specified name. If a match is found, this function is invoked with the
* entry's contents (buf) and its linked-list representation (listp). lsp
* holds the name and values of the property to be added or updated; this
* information will be merged with listp. Subsequently, an updated entry
* will be written to buf, which will in turn be written to disk by
* process_prop_db(). If no entry matches the specified name, listp
* will be NULL; a new entry will be generated in this case and it will
* contain only the property information in lsp.
*/
/* ARGSUSED */
{
int i;
buf[0] = '\0';
return (B_FALSE);
}
/*
* Find the prop we want to change.
*/
break;
}
/*
* If the prop is not found, append it to the list.
*/
goto fail;
}
/*
* nlip will need to be freed later if there is no list to
* append to.
*/
} else {
/*
* If the prop is found, delete the existing values from it.
*/
}
}
/*
* Fill our prop with the specified values.
*/
for (i = 0; i < *lsp->ls_valcntp; i++) {
goto fail;
}
}
} else {
}
return (B_FALSE);
fail:
return (B_FALSE);
}
/*
* This function is used for retrieving the values for a specific property.
* It gets called if an entry matching the specified name exists in the db.
* The entry is converted into a linked-list listp. This list is then scanned
* for the specified property name; if a matching property exists, its
* associated values are copied to the array lsp->ls_propval.
*/
/* ARGSUSED */
{
/*
* Find the prop we want to get.
*/
break;
}
return (B_FALSE);
}
return (B_FALSE);
}
}
/*
* This function is meant to be called at most once for each call
* to process_prop_db(). For this reason, it's ok to overwrite
* the caller's valcnt array size with the actual number of values
* returned.
*/
return (B_FALSE);
}
/*
* This is used for initializing properties.
* Unlike the other routines, this gets called for every entry in the
* database. lsp->ls_name is not user-specified but instead is set to
* the current name being processed.
*/
/* ARGSUSED */
{
char **propval;
/*
* Construct the propval array and fill it with
* values from listp.
*/
}
break;
}
/*
* We continue with initializing other properties even
* after encountering an error. This error will be
* propagated to the caller via 'statusp'.
*/
if (status != DLADM_STATUS_OK)
}
return (B_TRUE);
}
static int
{
int i, len;
char *curr;
for (i = 0; i < len; i++) {
char c = buf[i];
/*
* Move to the next character if there is no match and
* if we have not reached the last character.
*/
continue;
if (match) {
/*
* Nul-terminate the string pointed to by 'curr'.
*/
buf[i] = '\0';
if (*curr == '\0')
goto fail;
}
/*
* We get here after we have processed the "<prop>="
* pattern. The pattern we are now interested in is
* "<val0>,<val1>,...,<valn>;". For each value we
* find, a prop_val_t will be allocated and
* added to the current 'lip'.
*/
if (c == '=')
goto fail;
goto fail;
if (c == ';') {
}
} else {
/*
* lip == NULL indicates that 'curr' must be refering
* to a property name. We allocate a new prop_db_info_t
* append it to the list given by the caller.
*/
if (c != '=')
goto fail;
goto fail;
}
}
/*
* The list must be non-empty and the last character must be ';'.
*/
goto fail;
return (0);
fail:
free_props(*lipp);
return (-1);
}
static boolean_t
{
/*
* Skip leading spaces, blank lines, and comments.
*/
for (i = 0; i < len; i++) {
break;
}
return (B_TRUE);
/*
* Skip names we're not interested in.
* Note that strncmp() and isspace() are used here
* instead of strtok() and strcmp() because we don't
* want to modify buf in case it does not contain the
* specified name.
*/
return (B_TRUE);
} else {
/*
* If a name is not specified, find the name
* and assign it to lsp->ls_name.
*/
goto fail;
}
goto fail;
/*
* Now find the list of properties.
*/
goto fail;
goto fail;
if (noname)
return (cont);
fail:
if (noname)
/*
* Delete corrupted line.
*/
buf[0] = '\0';
return (B_TRUE);
}
{
/*
* This loop processes each line of the configuration file.
* buf can potentially be modified by process_prop_line().
* If this is a write operation and buf is not truncated, buf will
* be written to disk. process_prop_line() will no longer be
* called after it returns B_FALSE; at which point the remainder
* of the file will continue to be read and, if necessary, written
* to disk as well.
*/
if (cont)
break;
}
}
return (status);
/*
* If the specified name is not found above, we add the
* name and its properties to the configuration file.
*/
}
return (status);
}
{
int i;
return (DLADM_STATUS_BADARG);
break;
return (DLADM_STATUS_NOTFOUND);
switch (type) {
case DLADM_PROP_VAL_CURRENT:
break;
case DLADM_PROP_VAL_DEFAULT:
break;
}
*val_cntp = 1;
break;
val_cntp);
break;
}
if (cnt == 0) {
} else {
for (i = 0; i < cnt; i++) {
}
}
break;
default:
break;
}
return (status);
}
static dladm_status_t
{
return (DLADM_STATUS_TEMPONLY);
return (DLADM_STATUS_PROPRDONLY);
else
if (status != DLADM_STATUS_OK)
return (status);
} else {
return (DLADM_STATUS_NOTSUP);
return (DLADM_STATUS_NOMEM);
cnt = 1;
}
return (status);
}
{
int i;
continue;
status = s;
break;
} else {
if (s != DLADM_STATUS_OK &&
s != DLADM_STATUS_NOTSUP) {
status = s;
break;
}
}
}
if (!found)
return (status);
}
{
int i;
return (B_FALSE);
continue;
if (pdp->pd_temponly)
return (B_TRUE);
}
return (B_FALSE);
}
void
{
}
{
goto fail;
return (DLADM_STATUS_OK);
fail:
return (DLADM_STATUS_PROP_PARSE_ERR);
}