xref: /illumos-gate/usr/src/cmd/locator/locator.c (revision 2aeafac3612e19716bf8164f89c3c9196342979c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <libintl.h>
34 #include <locale.h>
35 #include <unistd.h>
36 #include <picl.h>
37 
38 #define	DEFAULT_NAME		"system"
39 
40 typedef struct locator_info {
41 	int		(*locator_func)(picl_nodehdl_t, struct locator_info *);
42 	int		found; 		/* Nonzero if found during walk */
43 	int		err;   		/* Last error from picl */
44 	char		*name; 		/* Name/LocatorName of locator node */
45 	int		new_state;	/* 0 = logical off, 1 = logical on */
46 	char		*on;		/* Logical on value for State */
47 	char		*off;		/* Logical off value for State */
48 } locator_info_t;
49 
50 static void
51 usage(char *prog_name)
52 {
53 	(void) fprintf(stderr, gettext("usage: %s [-n | -f]\n"), prog_name);
54 	exit(1);
55 }
56 
57 static int
58 change_locator_state(picl_nodehdl_t locator_node, locator_info_t *locator_info)
59 {
60 	picl_prophdl_t	state_prop;
61 	char		state[PICL_PROPNAMELEN_MAX];
62 	int		err;
63 	char		*new_state;
64 
65 	err = picl_get_prop_by_name(locator_node, "State", &state_prop);
66 	if (err != PICL_SUCCESS) {
67 		(void) fprintf(stderr,
68 			gettext("picl_get_prop_by_name failed: %s\n"),
69 			picl_strerror(err));
70 		return (err);
71 	}
72 
73 	err = picl_get_propval(state_prop, state, sizeof (state));
74 	if (err != PICL_SUCCESS) {
75 		(void) fprintf(stderr,
76 			gettext("picl_get_propval failed: %s\n"),
77 			picl_strerror(err));
78 		return (err);
79 	}
80 
81 	new_state = (locator_info->new_state) ? locator_info->on :
82 	    locator_info->off;
83 
84 	if (strcmp(state, new_state) != 0) {
85 		picl_propinfo_t prop_info;
86 		err = picl_get_propinfo(state_prop, &prop_info);
87 		if (err != PICL_SUCCESS) {
88 			(void) fprintf(stderr,
89 				gettext("picl_get_propinfo failed: %s\n"),
90 				picl_strerror(err));
91 			return (err);
92 		}
93 		err = picl_set_propval(state_prop, new_state, prop_info.size);
94 		if (err != PICL_SUCCESS) {
95 			(void) fprintf(stderr,
96 				gettext("picl_set_propval failed: %s\n"),
97 				picl_strerror(err));
98 			return (err);
99 		}
100 	}
101 	return (err);
102 }
103 
104 static int
105 display_locator_state(picl_nodehdl_t locator_node,
106     locator_info_t *locator_info)
107 {
108 	char		state[PICL_PROPNAMELEN_MAX];
109 	char		*display_state;
110 	int		err;
111 
112 	err = picl_get_propval_by_name(locator_node, "State",
113 		state, sizeof (state));
114 	if (err != PICL_SUCCESS) {
115 		(void) fprintf(stderr,
116 			gettext("picl_get_propval_by_name failed: %s\n"),
117 			picl_strerror(err));
118 		return (err);
119 	}
120 
121 	if (strcmp(state, locator_info->on) == 0)
122 		display_state = gettext("on");
123 	else if (strcmp(state, locator_info->off) == 0)
124 		display_state = gettext("off");
125 	else
126 		display_state = state;
127 
128 	(void) printf(gettext("The '%s' locator is %s.\n"),
129 		locator_info->name, display_state);
130 	return (err);
131 }
132 
133 static int
134 locator_walker_func(picl_nodehdl_t nodeh, void *arg)
135 {
136 	locator_info_t	*locator_info = (locator_info_t *)arg;
137 	int		err;
138 	char		is_locator[PICL_PROPNAMELEN_MAX];
139 	char		name[PICL_PROPNAMELEN_MAX];
140 	char		locator_on[PICL_PROPNAMELEN_MAX];
141 	char		locator_off[PICL_PROPNAMELEN_MAX];
142 
143 	err = picl_get_propval_by_name(nodeh, "IsLocator", is_locator,
144 		sizeof (is_locator));
145 
146 	if (err != PICL_SUCCESS)
147 		return (PICL_WALK_CONTINUE);
148 
149 	if (strcmp(is_locator, "true") != 0)
150 		return (PICL_WALK_CONTINUE);
151 
152 	err = picl_get_propval_by_name(nodeh, "LocatorName", name,
153 		sizeof (name));
154 
155 	if (err == PICL_PROPNOTFOUND)
156 		err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, name,
157 			sizeof (name));
158 
159 	if (err != PICL_SUCCESS)
160 		return (err);
161 
162 	if (strcmp(name, locator_info->name) != 0)
163 		return (PICL_WALK_CONTINUE);
164 
165 	err = picl_get_propval_by_name(nodeh, "LocatorOn", locator_on,
166 		sizeof (locator_on));
167 
168 	if (err == PICL_SUCCESS) {
169 		locator_info->on = locator_on;
170 	} else if (err == PICL_PROPNOTFOUND) {
171 		locator_info->on = "ON";
172 	} else {
173 		return (err);
174 	}
175 
176 	err = picl_get_propval_by_name(nodeh, "LocatorOff", locator_off,
177 		sizeof (locator_off));
178 
179 	if (err == PICL_SUCCESS) {
180 		locator_info->off = locator_off;
181 	} else if (err == PICL_PROPNOTFOUND) {
182 		locator_info->off = "OFF";
183 	} else {
184 		return (err);
185 	}
186 
187 	locator_info->err = (locator_info->locator_func)(nodeh,
188 		locator_info);
189 	locator_info->found = 1;
190 
191 	return (PICL_WALK_TERMINATE);
192 }
193 
194 int
195 main(int argc, char **argv)
196 {
197 	locator_info_t	locator_info = {0, 0, 0, 0, 0};
198 	picl_nodehdl_t	rooth;
199 	int		err;
200 	int		c;
201 	int		on_flag = 0;
202 	int		off_flag = 0;
203 	char		*progname;
204 	char		*locator_name = DEFAULT_NAME;
205 
206 	(void) setlocale(LC_ALL, "");
207 	(void) textdomain(TEXT_DOMAIN);
208 
209 	if ((progname = strrchr(argv[0], '/')) == NULL)
210 		progname = argv[0];
211 	else
212 		progname++;
213 
214 	while ((c = getopt(argc, argv, "nf")) != EOF) {
215 		switch (c) {
216 		case 'n':
217 			on_flag++;
218 			break;
219 		case 'f':
220 			off_flag++;
221 			break;
222 		case '?':
223 			/*FALLTHROUGH*/
224 		default:
225 			usage(progname);
226 		}
227 	}
228 	if (argc != optind)
229 		usage(progname);
230 
231 	/* We only take one option */
232 	if (on_flag && off_flag)
233 		usage(progname);
234 
235 	err = picl_initialize();
236 	if (err != PICL_SUCCESS) {
237 		(void) fprintf(stderr, gettext("picl_initialize failed: %s\n"),
238 			picl_strerror(err));
239 		exit(2);
240 	}
241 
242 	err = picl_get_root(&rooth);
243 	if (err != PICL_SUCCESS) {
244 		(void) fprintf(stderr, gettext("picl_get_root failed: %s\n"),
245 			picl_strerror(err));
246 		err = 2;
247 		goto OUT;
248 	}
249 
250 	if (on_flag) {
251 		locator_info.locator_func = change_locator_state;
252 		locator_info.new_state = 1;
253 	} else if (off_flag) {
254 		locator_info.locator_func = change_locator_state;
255 		locator_info.new_state = 0;
256 	} else {
257 		locator_info.locator_func = display_locator_state;
258 	}
259 
260 	locator_info.name = locator_name;
261 
262 	err = picl_walk_tree_by_class(rooth, "led", &locator_info,
263 		locator_walker_func);
264 	if (err != PICL_SUCCESS) {
265 		(void) fprintf(stderr,
266 			gettext("picl_walk_tree_by_class failed: %s\n"),
267 			picl_strerror(err));
268 		err = 2;
269 		goto OUT;
270 	}
271 
272 	if (locator_info.found == 0) {
273 		(void) fprintf(stderr, gettext("'%s' locator not found\n"),
274 			locator_name);
275 		err = 2;
276 	}
277 	if (locator_info.err != PICL_SUCCESS)
278 		err = 2;
279 OUT:
280 	(void) picl_shutdown();
281 	return (err);
282 }
283