libbrand.c revision db52f3aed012d3e73f2a8a861d7eee8d87ac71bc
/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fnmatch.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <synch.h>
#include <sys/systeminfo.h>
#include <thread.h>
#include <zone.h>
#include <libbrand_impl.h>
#include <libbrand.h>
#define DTD_ENTITY_TRUE "true"
static char i_curr_arch[MAXNAMELEN];
static char i_curr_zone[ZONENAME_MAX];
/*ARGSUSED*/
static void
{
/*
* Ignore error messages from libxml
*/
}
static boolean_t
{
(void) mutex_lock(&initialize_lock);
if (libbrand_initialized) {
(void) mutex_unlock(&initialize_lock);
return (B_TRUE);
}
(void) mutex_unlock(&initialize_lock);
return (B_FALSE);
}
sizeof (i_curr_zone)) < 0) {
(void) mutex_unlock(&initialize_lock);
return (B_FALSE);
}
/*
* Note that here we're initializing per-process libxml2
* state. By doing so we're implicitly assuming that
* no other code in this process is also trying to
* use libxml2. But in most case we know this not to
* be true since we're almost always used in conjunction
* with libzonecfg, which also uses libxml2. Lucky for
* us, libzonecfg initializes libxml2 to essentially
* the same defaults as we're using below.
*/
(void) xmlKeepBlanksDefault(0);
(void) mutex_unlock(&initialize_lock);
return (B_TRUE);
}
static const char *
get_curr_arch(void)
{
if (!libbrand_initialize())
return (NULL);
return (i_curr_arch);
}
static const char *
get_curr_zone(void)
{
if (!libbrand_initialize())
return (NULL);
return (i_curr_zone);
}
/*
* Internal function to open an XML file
*
* Returns the XML doc pointer, or NULL on failure. It will validate the
* document, as well as removing any comments from the document structure.
*/
static xmlDocPtr
open_xml_file(const char *file)
{
int valid;
if (!libbrand_initialize())
return (NULL);
/*
* Parse the file
*/
return (NULL);
/*
* Validate the file
*/
return (NULL);
}
if (valid == 0) {
return (NULL);
}
return (doc);
}
/*
* Open a handle to the named brand.
*
* Returns a handle to the named brand, which is used for all subsequent brand
* interaction, or NULL if unable to open or initialize the brand.
*/
brand_open(const char *name)
{
struct brand_handle *bhp;
char path[MAXPATHLEN];
/*
* Make sure brand name isn't too long
*/
return (NULL);
/*
* Check that the brand exists
*/
return (NULL);
/*
* Allocate brand handle
*/
return (NULL);
/*
* Open the configuration file
*/
return (NULL);
}
/*
* Verify that the name of the brand matches the directory in which it
* is installed.
*/
return (NULL);
}
return (NULL);
}
return (NULL);
}
return (NULL);
}
/*
* Open handle to platform configuration file.
*/
return (NULL);
}
return ((brand_handle_t)bhp);
}
/*
* Closes the given brand handle
*/
void
{
}
static int
{
/*
* Walk through the characters, substituting values as needed.
*/
dbuf[0] = '\0';
dst = 0;
continue;
}
case '%':
break;
case 'R':
break;
break;
case 'u':
break;
break;
case 'Z':
break;
/* name of the zone we're running in */
break;
case 'z':
/* name of the zone we're operating on */
break;
break;
case '*':
break;
for (i = 0; i < argc; i++)
" \"%s\"", argv[i]);
break;
}
}
return (-1);
return (0);
}
/*
* Retrieve the given tag from the brand.
* Perform the following substitutions as necessary:
*
* %% %
* %u Username
* %z Name of target zone
* %Z Name of current zone
* %R Root of zone
* %* Additional arguments (argc, argv)
*
* Returns 0 on success, -1 on failure.
*/
static int
{
int err = 0;
/*
* Retrieve the specified value from the XML doc
*/
return (-1);
return (-1);
break;
}
if (optional) {
buf[0] = '\0';
return (0);
} else {
return (-1);
}
}
return (-1);
/*
* If the entry in the config file is empty, check to see
* whether this is an optional field. If so, we return the
* empty buffer. If not, we return an error.
*/
if (optional) {
buf[0] = '\0';
} else {
err = -1;
}
} else {
/* Substitute token values as needed. */
if (substitute) {
err = -1;
} else {
err = -1;
}
}
return (err);
}
int
{
}
int
{
return (-1);
return (0);
}
int
{
}
int
{
}
int
{
const char *curr_zone = get_curr_zone();
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
{
return (B_FALSE);
if (allow_excl == NULL)
return (B_FALSE);
/* Note: only return B_TRUE if it's "true" */
else
return (ret);
}
/*
* Iterate over brand privileges
*
* Walks the brand config, searching for <privilege> elements, calling the
* specified callback for each. Returns 0 on success, or -1 on failure.
*/
int
{
int ret;
return (-1);
continue;
return (-1);
}
if (ret != 0)
return (-1);
}
return (0);
}
static int
int (*func)(void *, const char *, const char *, const char *,
{
char special_exp[MAXPATHLEN];
char opt_exp[MAXPATHLEN];
int ret;
return (-1);
continue;
ret = -1;
goto next;
}
/* Substitute token values as needed. */
special_exp, sizeof (special_exp),
goto next;
/* opt might not be defined */
} else {
goto next;
}
next:
if (ret != 0)
return (-1);
}
return (0);
}
/*
* Iterate over global platform filesystems
*
* Walks the platform, searching for <global_mount> elements, calling the
* specified callback for each. Returns 0 on success, or -1 on failure.
*
* Perform the following substitutions as necessary:
*
* %R Root of zone
*/
int
int (*func)(void *, const char *, const char *, const char *,
const char *), void *data)
{
}
/*
* Iterate over non-global zone platform filesystems
*
* Walks the platform, searching for <mount> elements, calling the
* specified callback for each. Returns 0 on success, or -1 on failure.
*/
int
const char *, const char *, const char *, const char *), void *data)
{
}
/*
* Iterate over platform symlinks
*
* Walks the platform, searching for <symlink> elements, calling the
* specified callback for each. Returns 0 on success, or -1 on failure.
*/
int
{
int ret;
return (-1);
continue;
return (-1);
}
if (ret != 0)
return (-1);
}
return (0);
}
/*
* Iterate over platform devices
*
* Walks the platform, searching for <device> elements, calling the
* specified callback for each. Returns 0 on success, or -1 on failure.
*/
int
const char *curr_iptype)
{
const char *curr_arch = get_curr_arch();
char match_exp[MAXPATHLEN];
int ret = 0;
return (-1);
continue;
goto next;
}
/* check if the arch matches */
goto next;
/* check if the iptype matches */
goto next;
/* Substitute token values as needed. */
goto next;
}
/* name might not be defined */
}
/* invoke the callback */
next:
if (err)
return (-1);
if (ret != 0)
return (-1);
}
return (0);
}