/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <assert.h>
#include <libscf.h>
#include <libscf_priv.h>
#include <libuutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include "startd.h"
/*
* Return an allocated copy of str, with the Bourne shell's metacharacters
* escaped by '\'. Returns NULL on (allocation) failure.
*/
static char *
{
const char *sp;
dst_len = 0;
++dst_len;
++dst_len;
}
return (safe_strdup(str));
return (NULL);
*dp++ = '\\';
}
*dp = '\0';
return (dst);
}
/*
* Return an allocated string representation of the value v.
* Return NULL on error.
*/
static char *
{
char *buf;
return (NULL);
return (buf);
}
/*
* Look up a property in the given snapshot, or the editing one
* if not found. Returns scf_error() on failure, or 0 otherwise.
*/
static int
{
int ret;
if (ret != 0) {
if (scf_error() == SCF_ERROR_NOT_FOUND)
if (ret != 0)
return (scf_error());
}
return (0);
return (scf_error());
if (ret != 0)
return (scf_error());
return (0);
return (scf_error());
}
/*
* Get an allocated string representation of the values of the property
* specified by inst & prop_spec and store it in *retstr. prop_spec may
* be a full property FMRI, or a "property-group/property" pair relative
* to inst, or the name of a property in inst's "application" property
* group. In the latter two cases, the property is looked up in inst's
* snap snapshot. In the first case, the target instance's running
* snapshot will be used. In any case, if the property or its group
* can't be found, the "editing" snapshot will be checked. Multiple
* values will be separated by sep.
*
* On error, non-zero is returned, and *retstr is set to an error
* string.
*
* *retstr should always be freed by the caller.
*/
static int
{
char *spec;
int ret;
&pn) != 0)
goto scferr;
return (-1);
}
goto scferr;
scope) != 0)
goto properr;
goto properr;
goto properr;
goto properr;
} else {
goto scferr;
goto properr;
goto scferr;
goto properr;
}
} else {
prop = scf_property_create(h);
goto scferr;
pg = scf_pg_create(h);
goto scferr;
pgn = "application";
} else {
*slash = '\0';
}
goto properr;
}
iter = scf_iter_create(h);
goto scferr;
goto scferr;
val = scf_value_create(h);
goto scferr;
if (ret == 0) {
goto out;
} else if (ret == -1) {
goto scferr;
}
goto err;
goto err;
void *p;
/* Append sep & val_to_str(val) to str. */
goto err;
}
goto err;
}
if (p == NULL) {
goto err;
}
str = p;
}
if (ret == -1) {
goto scferr;
}
out:
return (ret);
ret = -1;
goto out;
ret = -1;
if (scf_error() != SCF_ERROR_NOT_FOUND)
goto scferr;
goto out;
err:
ret = -1;
goto out;
}
/*
* Interpret the token at the beginning of str (which should be just
* after the escape character), and set *retstr to point at it. Returns
* the number of characters swallowed. On error, this returns -1, and
* *retstr is set to an error string.
*
* *retstr should always be freed by the caller.
*/
static int
int method_type, char **retstr)
{
switch (str[0]) {
case 's': { /* service */
char *sname;
int ret;
svc = scf_service_create(h);
return (-1);
}
if (ret != 0) {
return (-1);
}
if (sname_len < 0) {
return (-1);
}
return (-1);
}
if (szret < 0) {
return (-1);
}
return (1);
}
case 'i': { /* instance */
char *iname;
if (iname_len < 0) {
return (-1);
}
return (-1);
}
if (szret < 0) {
return (-1);
}
return (1);
}
case 'f': { /* fmri */
char *fmri;
int ret;
if (fmri_len == -1) {
return (-1);
}
return (-1);
}
if (ret == -1) {
return (-1);
}
return (1);
}
case 'm': { /* method */
switch (method_type) {
case METHOD_START:
str = "start";
break;
case METHOD_STOP:
str = "stop";
break;
case METHOD_REFRESH:
str = "refresh";
break;
default:
assert(0);
return (-1);
}
return (1);
}
case 'r': /* restarter */
return (1);
case '{': {
/* prop_spec[,:]? See get_prop_val_str() for prop_spec. */
char *close;
char *buf;
char sep;
int ret;
int skip;
return (-1);
}
/*
* If the last character is , or :, use it as the separator.
* Otherwise default to space.
*/
--len;
else
sep = ' ';
return (-1);
}
if (ret != 0) {
return (-1);
}
return (skip);
}
default:
return (-1);
}
}
/*
* Expand method tokens in the given string, and place the result in
* *retstr. Tokens begin with the ESCAPE character. Returns 0 on
* success. On failure, returns -1 and an error string is placed in
* *retstr. Caller should free *retstr.
*/
int
{
char *expanded;
const char *sp;
int ei;
return (-1);
}
return (-1);
}
/*
* Copy str into expanded, expanding %-tokens & realloc()ing as we go.
*/
ei = 0;
for (;;) {
char *esc;
return (0);
}
/* Copy up to the escape character. */
return (0);
}
sp += 2;
ei++;
} else {
char *tokval;
int skip;
char *p;
method_type, &tokval);
if (skip == -1) {
return (-1);
}
if (p == NULL) {
return (-1);
}
expanded = p;
}
}
/* NOTREACHED */
}