#include <stdio.h>
#include "lscf.h"
#if defined(NV_SUNOS)
* This facility is responsible for running programs and services
* and store their configuration information (named properties)
* The configuration information for the X server are managed by
* this facility. The functions in this source file use the library
* libscf (Service Configuration Facility) to access and modify
* the properties for the X server, more specifically the default depth.
* On Solaris, changing the default depth in the xorg.conf file is not
* enough. The session manager overrides the xorg.conf default depth:
* it passes the option -defdepth to the X server with the value
* retrieved from the Service Management Facility.
*
* For more information refer to the manpages of fmf(5), libsfc(3LIB),
* and to the source code of svccfg(1M) available on cvs.opensolaris.org.
*/
#include <libscf.h>
static int lscf_init_handle(scf_handle_t **scf_handle,
scf_scope_t **scf_scope);
static int lscf_select(scf_handle_t *scf_handle,
scf_scope_t *scf_scope,
const char *selection,
scf_service_t **current_svc);
static int lscf_setprop_int(scf_handle_t *scf_handle,
scf_scope_t *scf_scope,
scf_service_t *current_svc,
const char *group,
const char *name, int value);
int update_scf_depth(int depth)
{
static scf_handle_t *scf_handle = NULL;
static scf_scope_t *scf_scope = NULL;
scf_service_t *curren_svc = NULL;
int status = 1;
lscf_init_handle(&scf_handle, &scf_scope);
if (scf_handle == NULL) {
status =0;
goto done;
}
if(!lscf_select(scf_handle, scf_scope, "application/x11/x11-server",
¤_svc)) {
status =0;
goto done;
}
if(!lscf_setprop_int(scf_handle, scf_scope, curren_svc,
"options", "default_depth", depth)) {
status =0;
goto done;
}
done:
if(curren_svc) scf_service_destroy(curren_svc);
if(scf_scope) scf_scope_destroy(scf_scope);
if(scf_handle) {
scf_handle_unbind(scf_handle);
scf_handle_destroy(scf_handle);
}
if (!status) {
fprintf(stderr, "Unable to set X server default depth through Solaris "
"Service Management Facility");
}
return status;
}
static int lscf_init_handle(scf_handle_t **scf_handle,
scf_scope_t **scf_scope)
{
scf_handle_t *handle = NULL;
scf_scope_t *scope = NULL;;
*scf_handle = NULL;
*scf_scope = NULL;
handle = scf_handle_create(SCF_VERSION);
if (handle == NULL) {
return 0;
}
if (scf_handle_bind(handle) != 0) {
scf_handle_destroy(handle);
return 0;
}
scope = scf_scope_create(handle);
if (scope == NULL) {
scf_handle_unbind(handle);
scf_handle_destroy(handle);
return 0;
}
if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) !=0) {
scf_scope_destroy(scope);
scf_handle_unbind(handle);
scf_handle_destroy(handle);
return 0;
}
*scf_handle = handle;
*scf_scope = scope;
return 1;
}
static int lscf_select(scf_handle_t *scf_handle,
scf_scope_t *scf_scope,
const char *selection,
scf_service_t **current_svc)
{
scf_service_t *svc;
svc = scf_service_create(scf_handle);
if (svc == NULL) {
return 0;
}
if (scf_scope_get_service(scf_scope, selection, svc) == SCF_SUCCESS) {
*current_svc = svc;
return 1;
}
scf_service_destroy(svc);
return 0;
}
static int lscf_setprop_int(scf_handle_t *scf_handle,
scf_scope_t *scf_scope,
scf_service_t *current_svc,
const char *group,
const char *name, int value)
{
scf_transaction_entry_t *entry=NULL;
scf_propertygroup_t *pg = NULL;
scf_property_t *prop = NULL;
scf_transaction_t *transax = NULL;
scf_value_t *v = NULL;
int status = 1;
entry = scf_entry_create(scf_handle);
if (entry == NULL) {
status=0;
goto done;
}
pg = scf_pg_create(scf_handle);
if (pg == NULL) {
status=0;
goto done;
}
prop = scf_property_create(scf_handle);
if (prop == NULL) {
status=0;
goto done;
}
transax = scf_transaction_create(scf_handle);
if (transax == NULL) {
status=0;
goto done;
}
v = scf_value_create(scf_handle);
if (v == NULL) {
status=0;
goto done;
}
if (scf_service_get_pg(current_svc, group, pg) != SCF_SUCCESS) {
status=0;
goto done;
}
if (scf_pg_update(pg) == -1) {
status=0;
goto done;
}
if (scf_transaction_start(transax, pg) != SCF_SUCCESS) {
status=0;
goto done;
}
if (scf_pg_get_property(pg, name, prop) == SCF_SUCCESS) {
if (scf_transaction_property_change_type(transax, entry,
name, SCF_TYPE_INTEGER) == -1) {
status=0;
goto done;
}
} else {
if (scf_transaction_property_new(transax, entry,
name, SCF_TYPE_INTEGER)
== -1) {
status=0;
goto done;
}
}
scf_value_set_integer(v, value);
if (scf_entry_add_value(entry, v) != SCF_SUCCESS) {
status=0;
goto done;
}
if (scf_transaction_commit(transax) < 0) {
status=0;
}
done:
if (entry) scf_entry_destroy(entry);
if (pg) scf_pg_destroy(pg);
if (prop) scf_property_destroy(prop);
if (transax) scf_transaction_destroy(transax);
if (v) scf_value_destroy(v);
return status;
}
#else
int update_scf_depth(int depth)
{
return 1;
}
#endif