/*
* 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"
/*
* This module implements the PICL Interface used by PICL clients
* to access services of the PICL daemon
*
* Locking Strategy
* to the picl daemon, and the reference count, refcnt, variable.
* A reader lock is obtained to send a request to the daemon.
* A writer lock is obtained to initialize, reinitialize, or shutdown
* the interface.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <alloca.h>
#include <fcntl.h>
#include <libintl.h>
#include <errno.h>
#include <door.h>
#include <assert.h>
#include <synch.h>
#include <limits.h>
#include <picl.h>
#include "picl2door.h"
/*
* Module variables
*/
static char *picl_errmsg[] = {
"No error",
"General system failure",
"Daemon not responding",
"Unknown PICL service",
"Session not initialized",
"Invalid arguments",
"Argument too big",
"Property not found",
"Not a table property handle",
"Not a node handle",
"Not a property handle",
"End of property list",
"Property already exists",
"Property not writable",
"Insufficient permissions",
"Invalid handle",
"Stale handle",
"Unsupported version",
"Wait timed out",
"Attempting to destroy before delete",
"PICL Tree is busy",
"Already has a parent",
"Property name is reserved",
"Invalid reference value",
"Continue tree walk",
"Terminate tree walk",
"Node not found",
"Not enough space available",
"Property not readable",
"Property value unavailable"
};
/*
* This function sends the client request to the daemon using a door call.
* If door_handle is -1, it returns PICL_NOTINITIALIZED.
* If the door_call fails, it returns PICL_NORESPONSE. Otherwise, it
* checks the response from the daemon for error. If an error is returned
* this function returns the error code returned and unmaps any
* memory mapped by the door call. For successful results, the caller is
* responsible to unmap the mapped memory after retrieving the results.
*
* This function does not attempt to reinitialize the interface if the
* initial door_call fails. It is called from handshake() , shutdown()
* and trysend_req() routines.
*/
static int
{
int err;
int req_cnum;
return (PICL_NORESPONSE);
/*LINTED*/
return (PICL_SUCCESS);
else
return (err);
}
/*
* This function posts an INIT message to the daemon to
* verify communication channel.
*/
static int
handshake(void)
{
int err;
return (err);
return (PICL_SUCCESS);
}
/*
* This function calls post_req() to make door_call and reinitializes
* the interface is post_req() fails.
*/
static int
unsigned int trycount)
{
int err;
int write_locked;
write_locked = 0;
if (refcnt == 0) {
return (PICL_NOTINITIALIZED);
}
if (trycount == 0) /* no more retry */
break;
(void) close(door_handle);
break;
}
--trycount;
continue;
}
/*
* Upgrade read to a write lock
*/
/*
* if picl_shutdown happens during lock upgrade
*/
if (refcnt == 0) {
break;
}
write_locked = 1;
continue;
}
return (err);
}
/*
* Initialize the PICL interface
* Increment the reference count.
*/
int
picl_initialize(void)
{
int err;
if (refcnt > 0) { /* previously initialized */
if (err == PICL_SUCCESS) {
++refcnt;
return (err);
}
if (err != PICL_NORESPONSE) {
return (err);
}
}
/*
* Open picld door and initialize door_handle
*/
return (PICL_NORESPONSE);
}
if (err != PICL_SUCCESS)
(void) close(door_handle);
else
++refcnt;
return (err);
}
/*
* Shutdown the PICL interface
* Decrement the reference count and close the door_handle if refcnt is zero
*/
int
picl_shutdown(void)
{
int err;
if (refcnt == 0) {
return (PICL_NOTINITIALIZED);
}
--refcnt;
if (refcnt == 0)
(void) close(door_handle);
if (err != PICL_SUCCESS)
return (err);
return (PICL_SUCCESS);
}
/*
* This function waits for the specified number of seconds for a PICL
* tree refresh.
*/
int
{
int err;
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (err);
}
/*
* This function copies the handle of the root node of the PICL tree into
* the buffer <rooth>
*/
int
{
int err;
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (PICL_SUCCESS);
}
/*
* This function copies the value of the property specified by its handle
* into the buffer <valbuf>.
*/
int
{
int err;
return (PICL_VALUETOOBIG);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
else
return (err);
}
/*
* This function copies the value of the property specified by its
* name into the buffer <valbuf>
*/
int
{
int err;
return (PICL_VALUETOOBIG);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
else
return (err);
}
/*
* This function sets the value of the property specified by its
* handle with the value specified in <valbuf>.
*/
int
{
int err;
return (PICL_VALUETOOBIG);
return (PICL_VALUETOOBIG);
sizeof (picl_retsetattrval_t), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
return (PICL_SUCCESS);
}
/*
* This function sets the value of the property specified by its
* name with the value given in <valbuf>
*/
int
{
int err;
return (PICL_VALUETOOBIG);
return (PICL_VALUETOOBIG);
&ret_setattrvalbyname, sizeof (picl_retsetattrvalbyname_t),
if (err != PICL_SUCCESS)
return (err);
return (PICL_SUCCESS);
}
/*
* This function copies the information of the specified property
* into <pinfo>
*/
int
{
int err;
sizeof (picl_retattrinfo_t), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (PICL_SUCCESS);
}
/*
* This function copies the handle of the first property of a node into
* <proph>
*/
int
{
int err;
sizeof (picl_retfirstattr_t), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (PICL_SUCCESS);
}
/*
* This function copies the handle of the next property in list
* into <nextprop>.
*/
int
{
int err;
sizeof (picl_retnextattr_t), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (PICL_SUCCESS);
}
/*
* This function copies the handle of the property specified by its
* name into <proph>.
*/
int
{
int err;
sizeof (picl_retattrbyname_t), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (PICL_SUCCESS);
}
/*
* This function copies the handle of the next property on the same
* row of the table into <rowproph>.
* When proph is the table handle, the handle of the property that is
* in first row and first column is copied.
*/
int
{
int err;
sizeof (picl_retattrbyrow_t), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (PICL_SUCCESS);
}
/*
* This function copies the handle of the next property on the same
* column of the table into <colproph>.
* When proph is the table handle, the handle of the property that is
* in the first row and first column is copied.
*/
int
{
int err;
sizeof (picl_retattrbycol_t), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (PICL_SUCCESS);
}
/*
* This function returns the picl error messages corresponding to the
* error number.
*/
char *
{
}
return ((char *)NULL);
}
/*
* recursively visit all nodes
*/
static int
{
int err;
sizeof (chdh));
while (err == PICL_SUCCESS) {
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_WALK_CONTINUE)
return (err);
}
return (err);
sizeof (chdh));
}
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* This function walks the tree by class and invokes the callback
* function on class name matches.
*/
int
{
int err;
if (callback_fn == NULL)
return (PICL_INVALIDARG);
return (PICL_SUCCESS);
return (err);
}
/*
* This function gets propinfo and prop handle of the named property
*/
int
{
int err;
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
return (PICL_SUCCESS);
}
int
{
int err;
return (PICL_VALUETOOBIG);
sizeof (out), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (err);
}
int
{
int err;
return (PICL_VALUETOOBIG);
return (PICL_VALUETOOBIG);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (err);
}
int
{
int err;
sizeof (out), SEND_REQ_TRYCOUNT);
if (err != PICL_SUCCESS)
return (err);
/*LINTED*/
return (err);
}