xref: /illumos-gate/usr/src/cmd/locator/locator.c (revision 2a8bcb4e)
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 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <libintl.h>
32 #include <locale.h>
33 #include <unistd.h>
34 #include <picl.h>
35 
36 #define	DEFAULT_NAME		"system"
37 
38 typedef struct locator_info {
39 	int		(*locator_func)(picl_nodehdl_t, struct locator_info *);
40 	int		found; 		/* Nonzero if found during walk */
41 	int		err;   		/* Last error from picl */
42 	char		*name; 		/* Name/LocatorName of locator node */
43 	int		new_state;	/* 0 = logical off, 1 = logical on */
44 	char		*on;		/* Logical on value for State */
45 	char		*off;		/* Logical off value for State */
46 } locator_info_t;
47 
48 static void
usage(char * prog_name)49 usage(char *prog_name)
50 {
51 	(void) fprintf(stderr, gettext("usage: %s [-n | -f]\n"), prog_name);
52 	exit(1);
53 }
54 
55 static int
change_locator_state(picl_nodehdl_t locator_node,locator_info_t * locator_info)56 change_locator_state(picl_nodehdl_t locator_node, locator_info_t *locator_info)
57 {
58 	picl_prophdl_t	state_prop;
59 	char		state[PICL_PROPNAMELEN_MAX];
60 	int		err;
61 	char		*new_state;
62 
63 	err = picl_get_prop_by_name(locator_node, "State", &state_prop);
64 	if (err != PICL_SUCCESS) {
65 		(void) fprintf(stderr,
66 			gettext("picl_get_prop_by_name failed: %s\n"),
67 			picl_strerror(err));
68 		return (err);
69 	}
70 
71 	err = picl_get_propval(state_prop, state, sizeof (state));
72 	if (err != PICL_SUCCESS) {
73 		(void) fprintf(stderr,
74 			gettext("picl_get_propval failed: %s\n"),
75 			picl_strerror(err));
76 		return (err);
77 	}
78 
79 	new_state = (locator_info->new_state) ? locator_info->on :
80 	    locator_info->off;
81 
82 	if (strcmp(state, new_state) != 0) {
83 		picl_propinfo_t prop_info;
84 		err = picl_get_propinfo(state_prop, &prop_info);
85 		if (err != PICL_SUCCESS) {
86 			(void) fprintf(stderr,
87 				gettext("picl_get_propinfo failed: %s\n"),
88 				picl_strerror(err));
89 			return (err);
90 		}
91 		err = picl_set_propval(state_prop, new_state, prop_info.size);
92 		if (err != PICL_SUCCESS) {
93 			(void) fprintf(stderr,
94 				gettext("picl_set_propval failed: %s\n"),
95 				picl_strerror(err));
96 			return (err);
97 		}
98 	}
99 	return (err);
100 }
101 
102 static int
display_locator_state(picl_nodehdl_t locator_node,locator_info_t * locator_info)103 display_locator_state(picl_nodehdl_t locator_node,
104     locator_info_t *locator_info)
105 {
106 	char		state[PICL_PROPNAMELEN_MAX];
107 	char		*display_state;
108 	int		err;
109 
110 	err = picl_get_propval_by_name(locator_node, "State",
111 		state, sizeof (state));
112 	if (err != PICL_SUCCESS) {
113 		(void) fprintf(stderr,
114 			gettext("picl_get_propval_by_name failed: %s\n"),
115 			picl_strerror(err));
116 		return (err);
117 	}
118 
119 	if (strcmp(state, locator_info->on) == 0)
120 		display_state = gettext("on");
121 	else if (strcmp(state, locator_info->off) == 0)
122 		display_state = gettext("off");
123 	else
124 		display_state = state;
125 
126 	(void) printf(gettext("The '%s' locator is %s.\n"),
127 		locator_info->name, display_state);
128 	return (err);
129 }
130 
131 static int
locator_walker_func(picl_nodehdl_t nodeh,void * arg)132 locator_walker_func(picl_nodehdl_t nodeh, void *arg)
133 {
134 	locator_info_t	*locator_info = (locator_info_t *)arg;
135 	int		err;
136 	char		is_locator[PICL_PROPNAMELEN_MAX];
137 	char		name[PICL_PROPNAMELEN_MAX];
138 	char		locator_on[PICL_PROPNAMELEN_MAX];
139 	char		locator_off[PICL_PROPNAMELEN_MAX];
140 
141 	err = picl_get_propval_by_name(nodeh, "IsLocator", is_locator,
142 		sizeof (is_locator));
143 
144 	if (err != PICL_SUCCESS)
145 		return (PICL_WALK_CONTINUE);
146 
147 	if (strcmp(is_locator, "true") != 0)
148 		return (PICL_WALK_CONTINUE);
149 
150 	err = picl_get_propval_by_name(nodeh, "LocatorName", name,
151 		sizeof (name));
152 
153 	if (err == PICL_PROPNOTFOUND)
154 		err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, name,
155 			sizeof (name));
156 
157 	if (err != PICL_SUCCESS)
158 		return (err);
159 
160 	if (strcmp(name, locator_info->name) != 0)
161 		return (PICL_WALK_CONTINUE);
162 
163 	err = picl_get_propval_by_name(nodeh, "LocatorOn", locator_on,
164 		sizeof (locator_on));
165 
166 	if (err == PICL_SUCCESS) {
167 		locator_info->on = locator_on;
168 	} else if (err == PICL_PROPNOTFOUND) {
169 		locator_info->on = "ON";
170 	} else {
171 		return (err);
172 	}
173 
174 	err = picl_get_propval_by_name(nodeh, "LocatorOff", locator_off,
175 		sizeof (locator_off));
176 
177 	if (err == PICL_SUCCESS) {
178 		locator_info->off = locator_off;
179 	} else if (err == PICL_PROPNOTFOUND) {
180 		locator_info->off = "OFF";
181 	} else {
182 		return (err);
183 	}
184 
185 	locator_info->err = (locator_info->locator_func)(nodeh,
186 		locator_info);
187 	locator_info->found = 1;
188 
189 	return (PICL_WALK_TERMINATE);
190 }
191 
192 int
main(int argc,char ** argv)193 main(int argc, char **argv)
194 {
195 	locator_info_t	locator_info = {0, 0, 0, 0, 0};
196 	picl_nodehdl_t	rooth;
197 	int		err;
198 	int		c;
199 	int		on_flag = 0;
200 	int		off_flag = 0;
201 	char		*progname;
202 	char		*locator_name = DEFAULT_NAME;
203 
204 	(void) setlocale(LC_ALL, "");
205 	(void) textdomain(TEXT_DOMAIN);
206 
207 	if ((progname = strrchr(argv[0], '/')) == NULL)
208 		progname = argv[0];
209 	else
210 		progname++;
211 
212 	while ((c = getopt(argc, argv, "nf")) != EOF) {
213 		switch (c) {
214 		case 'n':
215 			on_flag++;
216 			break;
217 		case 'f':
218 			off_flag++;
219 			break;
220 		case '?':
221 			/*FALLTHROUGH*/
222 		default:
223 			usage(progname);
224 		}
225 	}
226 	if (argc != optind)
227 		usage(progname);
228 
229 	/* We only take one option */
230 	if (on_flag && off_flag)
231 		usage(progname);
232 
233 	err = picl_initialize();
234 	if (err != PICL_SUCCESS) {
235 		(void) fprintf(stderr, gettext("picl_initialize failed: %s\n"),
236 			picl_strerror(err));
237 		exit(2);
238 	}
239 
240 	err = picl_get_root(&rooth);
241 	if (err != PICL_SUCCESS) {
242 		(void) fprintf(stderr, gettext("picl_get_root failed: %s\n"),
243 			picl_strerror(err));
244 		err = 2;
245 		goto OUT;
246 	}
247 
248 	if (on_flag) {
249 		locator_info.locator_func = change_locator_state;
250 		locator_info.new_state = 1;
251 	} else if (off_flag) {
252 		locator_info.locator_func = change_locator_state;
253 		locator_info.new_state = 0;
254 	} else {
255 		locator_info.locator_func = display_locator_state;
256 	}
257 
258 	locator_info.name = locator_name;
259 
260 	err = picl_walk_tree_by_class(rooth, "led", &locator_info,
261 		locator_walker_func);
262 	if (err != PICL_SUCCESS) {
263 		(void) fprintf(stderr,
264 			gettext("picl_walk_tree_by_class failed: %s\n"),
265 			picl_strerror(err));
266 		err = 2;
267 		goto OUT;
268 	}
269 
270 	if (locator_info.found == 0) {
271 		(void) fprintf(stderr, gettext("'%s' locator not found\n"),
272 			locator_name);
273 		err = 2;
274 	}
275 	if (locator_info.err != PICL_SUCCESS)
276 		err = 2;
277 OUT:
278 	(void) picl_shutdown();
279 	return (err);
280 }
281