OpenSolaris_b135/cmd/locator/locator.c

Compare this file to the similar file:
Show the results in this format:

/*
 * 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
 * or http://www.opensolaris.org/os/licensing.
 * 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 2006 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <libintl.h>
#include <locale.h>
#include <unistd.h>
#include <picl.h>

#define	DEFAULT_NAME		"system"

typedef struct locator_info {
	int		(*locator_func)(picl_nodehdl_t, struct locator_info *);
	int		found; 		/* Nonzero if found during walk */
	int		err;   		/* Last error from picl */
	char		*name; 		/* Name/LocatorName of locator node */
	int		new_state;	/* 0 = logical off, 1 = logical on */
	char		*on;		/* Logical on value for State */
	char		*off;		/* Logical off value for State */
} locator_info_t;

static void
usage(char *prog_name)
{
	(void) fprintf(stderr, gettext("usage: %s [-n | -f]\n"), prog_name);
	exit(1);
}

static int
change_locator_state(picl_nodehdl_t locator_node, locator_info_t *locator_info)
{
	picl_prophdl_t	state_prop;
	char		state[PICL_PROPNAMELEN_MAX];
	int		err;
	char		*new_state;

	err = picl_get_prop_by_name(locator_node, "State", &state_prop);
	if (err != PICL_SUCCESS) {
		(void) fprintf(stderr,
			gettext("picl_get_prop_by_name failed: %s\n"),
			picl_strerror(err));
		return (err);
	}

	err = picl_get_propval(state_prop, state, sizeof (state));
	if (err != PICL_SUCCESS) {
		(void) fprintf(stderr,
			gettext("picl_get_propval failed: %s\n"),
			picl_strerror(err));
		return (err);
	}

	new_state = (locator_info->new_state) ? locator_info->on :
	    locator_info->off;

	if (strcmp(state, new_state) != 0) {
		picl_propinfo_t prop_info;
		err = picl_get_propinfo(state_prop, &prop_info);
		if (err != PICL_SUCCESS) {
			(void) fprintf(stderr,
				gettext("picl_get_propinfo failed: %s\n"),
				picl_strerror(err));
			return (err);
		}
		err = picl_set_propval(state_prop, new_state, prop_info.size);
		if (err != PICL_SUCCESS) {
			(void) fprintf(stderr,
				gettext("picl_set_propval failed: %s\n"),
				picl_strerror(err));
			return (err);
		}
	}
	return (err);
}

static int
display_locator_state(picl_nodehdl_t locator_node,
    locator_info_t *locator_info)
{
	char		state[PICL_PROPNAMELEN_MAX];
	char		*display_state;
	int		err;

	err = picl_get_propval_by_name(locator_node, "State",
		state, sizeof (state));
	if (err != PICL_SUCCESS) {
		(void) fprintf(stderr,
			gettext("picl_get_propval_by_name failed: %s\n"),
			picl_strerror(err));
		return (err);
	}

	if (strcmp(state, locator_info->on) == 0)
		display_state = gettext("on");
	else if (strcmp(state, locator_info->off) == 0)
		display_state = gettext("off");
	else
		display_state = state;

	(void) printf(gettext("The '%s' locator is %s.\n"),
		locator_info->name, display_state);
	return (err);
}

static int
locator_walker_func(picl_nodehdl_t nodeh, void *arg)
{
	locator_info_t	*locator_info = (locator_info_t *)arg;
	int		err;
	char		is_locator[PICL_PROPNAMELEN_MAX];
	char		name[PICL_PROPNAMELEN_MAX];
	char		locator_on[PICL_PROPNAMELEN_MAX];
	char		locator_off[PICL_PROPNAMELEN_MAX];

	err = picl_get_propval_by_name(nodeh, "IsLocator", is_locator,
		sizeof (is_locator));

	if (err != PICL_SUCCESS)
		return (PICL_WALK_CONTINUE);

	if (strcmp(is_locator, "true") != 0)
		return (PICL_WALK_CONTINUE);

	err = picl_get_propval_by_name(nodeh, "LocatorName", name,
		sizeof (name));

	if (err == PICL_PROPNOTFOUND)
		err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, name,
			sizeof (name));

	if (err != PICL_SUCCESS)
		return (err);

	if (strcmp(name, locator_info->name) != 0)
		return (PICL_WALK_CONTINUE);

	err = picl_get_propval_by_name(nodeh, "LocatorOn", locator_on,
		sizeof (locator_on));

	if (err == PICL_SUCCESS) {
		locator_info->on = locator_on;
	} else if (err == PICL_PROPNOTFOUND) {
		locator_info->on = "ON";
	} else {
		return (err);
	}

	err = picl_get_propval_by_name(nodeh, "LocatorOff", locator_off,
		sizeof (locator_off));

	if (err == PICL_SUCCESS) {
		locator_info->off = locator_off;
	} else if (err == PICL_PROPNOTFOUND) {
		locator_info->off = "OFF";
	} else {
		return (err);
	}

	locator_info->err = (locator_info->locator_func)(nodeh,
		locator_info);
	locator_info->found = 1;

	return (PICL_WALK_TERMINATE);
}

int
main(int argc, char **argv)
{
	locator_info_t	locator_info = {0, 0, 0, 0, 0};
	picl_nodehdl_t	rooth;
	int		err;
	int		c;
	int		on_flag = 0;
	int		off_flag = 0;
	char		*progname;
	char		*locator_name = DEFAULT_NAME;

	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);

	if ((progname = strrchr(argv[0], '/')) == NULL)
		progname = argv[0];
	else
		progname++;

	while ((c = getopt(argc, argv, "nf")) != EOF) {
		switch (c) {
		case 'n':
			on_flag++;
			break;
		case 'f':
			off_flag++;
			break;
		case '?':
			/*FALLTHROUGH*/
		default:
			usage(progname);
		}
	}
	if (argc != optind)
		usage(progname);

	/* We only take one option */
	if (on_flag && off_flag)
		usage(progname);

	err = picl_initialize();
	if (err != PICL_SUCCESS) {
		(void) fprintf(stderr, gettext("picl_initialize failed: %s\n"),
			picl_strerror(err));
		exit(2);
	}

	err = picl_get_root(&rooth);
	if (err != PICL_SUCCESS) {
		(void) fprintf(stderr, gettext("picl_get_root failed: %s\n"),
			picl_strerror(err));
		err = 2;
		goto OUT;
	}

	if (on_flag) {
		locator_info.locator_func = change_locator_state;
		locator_info.new_state = 1;
	} else if (off_flag) {
		locator_info.locator_func = change_locator_state;
		locator_info.new_state = 0;
	} else {
		locator_info.locator_func = display_locator_state;
	}

	locator_info.name = locator_name;

	err = picl_walk_tree_by_class(rooth, "led", &locator_info,
		locator_walker_func);
	if (err != PICL_SUCCESS) {
		(void) fprintf(stderr,
			gettext("picl_walk_tree_by_class failed: %s\n"),
			picl_strerror(err));
		err = 2;
		goto OUT;
	}

	if (locator_info.found == 0) {
		(void) fprintf(stderr, gettext("'%s' locator not found\n"),
			locator_name);
		err = 2;
	}
	if (locator_info.err != PICL_SUCCESS)
		err = 2;
OUT:
	(void) picl_shutdown();
	return (err);
}