xref: /openbsd-src/usr.sbin/apm/apm.c (revision 3abecac13ee041aea096ce7171e4bd0dd60c1b0f)
1*3abecac1Smbuhl /*	$OpenBSD: apm.c,v 1.43 2022/11/09 18:48:11 mbuhl Exp $	*/
240bbec49Smillert 
3054c7b81Shvozda /*
4054c7b81Shvozda  *  Copyright (c) 1996 John T. Kohl
5054c7b81Shvozda  *  All rights reserved.
6054c7b81Shvozda  *
7054c7b81Shvozda  *  Redistribution and use in source and binary forms, with or without
8054c7b81Shvozda  *  modification, are permitted provided that the following conditions
9054c7b81Shvozda  *  are met:
10054c7b81Shvozda  *  1. Redistributions of source code must retain the above copyright
11054c7b81Shvozda  *     notice, this list of conditions and the following disclaimer.
12054c7b81Shvozda  *  2. Redistributions in binary form must reproduce the above copyright
13054c7b81Shvozda  *     notice, this list of conditions and the following disclaimer in the
14054c7b81Shvozda  *     documentation and/or other materials provided with the distribution.
15054c7b81Shvozda  *  3. The name of the author may not be used to endorse or promote products
16054c7b81Shvozda  *     derived from this software without specific prior written permission.
17054c7b81Shvozda  *
18054c7b81Shvozda  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19054c7b81Shvozda  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20054c7b81Shvozda  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21054c7b81Shvozda  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22054c7b81Shvozda  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23054c7b81Shvozda  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24054c7b81Shvozda  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25054c7b81Shvozda  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26054c7b81Shvozda  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27054c7b81Shvozda  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28054c7b81Shvozda  * POSSIBILITY OF SUCH DAMAGE.
29054c7b81Shvozda  *
30054c7b81Shvozda  */
31054c7b81Shvozda 
32b9fc9a72Sderaadt #include <sys/types.h>
33a2123b9aSderaadt #include <sys/sysctl.h>
34a2123b9aSderaadt #include <sys/socket.h>
35a2123b9aSderaadt #include <sys/un.h>
36a2123b9aSderaadt #include <sys/ioctl.h>
37a2123b9aSderaadt #include <machine/apmvar.h>
38054c7b81Shvozda #include <stdio.h>
39054c7b81Shvozda #include <stdlib.h>
40054c7b81Shvozda #include <unistd.h>
41054c7b81Shvozda #include <fcntl.h>
42d246eb98Smickey #include <errno.h>
43054c7b81Shvozda #include <err.h>
44054c7b81Shvozda #include <string.h>
45054c7b81Shvozda #include "pathnames.h"
46054c7b81Shvozda #include "apm-proto.h"
47054c7b81Shvozda 
48054c7b81Shvozda #define FALSE 0
49054c7b81Shvozda #define TRUE 1
50054c7b81Shvozda 
51054c7b81Shvozda extern char *__progname;
52054c7b81Shvozda 
53224a603cSanton static int		do_zzz(int, enum apm_action);
54224a603cSanton static int		open_socket(const char *);
55224a603cSanton static int		send_command(int, struct apm_command *,
56224a603cSanton 			    struct apm_reply *);
57224a603cSanton static __dead void	usage(void);
58224a603cSanton static __dead void	zzusage(void);
59054c7b81Shvozda 
60224a603cSanton static __dead void
usage(void)61054c7b81Shvozda usage(void)
62054c7b81Shvozda {
6388362101Sjmc 	fprintf(stderr,"usage: %s [-AabHLlmPSvZz] [-f sockname]\n",
64c16dfee5Sderaadt 	    __progname);
65054c7b81Shvozda 	exit(1);
66054c7b81Shvozda }
67054c7b81Shvozda 
68224a603cSanton static __dead void
zzusage(void)69054c7b81Shvozda zzusage(void)
70054c7b81Shvozda {
715e2f88c9Sjmc 	fprintf(stderr,"usage: %s [-SZz] [-f sockname]\n",
72054c7b81Shvozda 	    __progname);
73054c7b81Shvozda 	exit(1);
74054c7b81Shvozda }
75054c7b81Shvozda 
76224a603cSanton static int
send_command(int fd,struct apm_command * cmd,struct apm_reply * reply)774b6e8b27Sderaadt send_command(int fd, struct apm_command *cmd, struct apm_reply *reply)
78054c7b81Shvozda {
79054c7b81Shvozda 	/* send a command to the apm daemon */
80054c7b81Shvozda 	cmd->vno = APMD_VNO;
81054c7b81Shvozda 
82054c7b81Shvozda 	if (send(fd, cmd, sizeof(*cmd), 0) == sizeof(*cmd)) {
83054c7b81Shvozda 		if (recv(fd, reply, sizeof(*reply), 0) != sizeof(*reply)) {
8440bbec49Smillert 			warn("invalid reply from APM daemon");
856d78643eSderaadt 			return (1);
86054c7b81Shvozda 		}
87054c7b81Shvozda 	} else {
88054c7b81Shvozda 		warn("invalid send to APM daemon");
896d78643eSderaadt 		return (1);
90054c7b81Shvozda 	}
91c16dfee5Sderaadt 	return (0);
92054c7b81Shvozda }
93054c7b81Shvozda 
94224a603cSanton static int
do_zzz(int fd,enum apm_action action)95d246eb98Smickey do_zzz(int fd, enum apm_action action)
96054c7b81Shvozda {
97054c7b81Shvozda 	struct apm_command command;
98054c7b81Shvozda 	struct apm_reply reply;
99d48e549cSderaadt 	char *msg;
100c7cff24eSkn 	int ret;
101054c7b81Shvozda 
102*3abecac1Smbuhl 	bzero(&reply, sizeof reply);
103*3abecac1Smbuhl 
104054c7b81Shvozda 	switch (action) {
105054c7b81Shvozda 	case NONE:
106054c7b81Shvozda 	case SUSPEND:
107054c7b81Shvozda 		command.action = SUSPEND;
108d48e549cSderaadt 		msg = "Suspending system";
109054c7b81Shvozda 		break;
110054c7b81Shvozda 	case STANDBY:
111054c7b81Shvozda 		command.action = STANDBY;
112d48e549cSderaadt 		msg = "System standing by";
113054c7b81Shvozda 		break;
11429a085afSderaadt 	case HIBERNATE:
11529a085afSderaadt 		command.action = HIBERNATE;
116d48e549cSderaadt 		msg = "Hibernating system";
11729a085afSderaadt 		break;
118054c7b81Shvozda 	default:
119054c7b81Shvozda 		zzusage();
120054c7b81Shvozda 	}
121054c7b81Shvozda 
122d48e549cSderaadt 	printf("%s...\n", msg);
123c7cff24eSkn 	ret = send_command(fd, &command, &reply);
124*3abecac1Smbuhl 	if (ret == 0 && reply.error)
125c7cff24eSkn 		errx(1, "%s: %s", apm_state(reply.newstate), strerror(reply.error));
126c7cff24eSkn 	exit(ret);
127054c7b81Shvozda }
128054c7b81Shvozda 
129224a603cSanton static int
open_socket(const char * sockname)130054c7b81Shvozda open_socket(const char *sockname)
131054c7b81Shvozda {
132054c7b81Shvozda 	int sock, errr;
133054c7b81Shvozda 	struct sockaddr_un s_un;
134054c7b81Shvozda 
135054c7b81Shvozda 	sock = socket(AF_UNIX, SOCK_STREAM, 0);
136054c7b81Shvozda 	if (sock == -1)
137054c7b81Shvozda 		err(1, "cannot create local socket");
138054c7b81Shvozda 
139054c7b81Shvozda 	s_un.sun_family = AF_UNIX;
140e9bd1503Sguenther 	strlcpy(s_un.sun_path, sockname, sizeof(s_un.sun_path));
141e9bd1503Sguenther 	if (connect(sock, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
142054c7b81Shvozda 		errr = errno;
143054c7b81Shvozda 		close(sock);
144054c7b81Shvozda 		errno = errr;
145876a8cf6Smickey 		sock = -1;
146054c7b81Shvozda 	}
147c16dfee5Sderaadt 	return (sock);
148054c7b81Shvozda }
149054c7b81Shvozda 
150a7f3a53aSmickey int
main(int argc,char * argv[])151054c7b81Shvozda main(int argc, char *argv[])
152054c7b81Shvozda {
153d246eb98Smickey 	const char *sockname = _PATH_APM_SOCKET;
154054c7b81Shvozda 	int doac = FALSE;
155054c7b81Shvozda 	int dopct = FALSE;
156054c7b81Shvozda 	int dobstate = FALSE;
157a7f3a53aSmickey 	int domin = FALSE;
158f6da2e61Ssturm 	int doperf = FALSE;
159054c7b81Shvozda 	int verbose = FALSE;
160d246eb98Smickey 	int ch, fd, rval;
161054c7b81Shvozda 	enum apm_action action = NONE;
162054c7b81Shvozda 	struct apm_command command;
163054c7b81Shvozda 	struct apm_reply reply;
164a2123b9aSderaadt 	int cpuspeed_mib[] = { CTL_HW, HW_CPUSPEED }, cpuspeed;
165a2123b9aSderaadt 	size_t cpuspeed_sz = sizeof(cpuspeed);
166054c7b81Shvozda 
167df69c215Sderaadt 	if (sysctl(cpuspeed_mib, 2, &cpuspeed, &cpuspeed_sz, NULL, 0) == -1)
16873cd97e4Srobert 		cpuspeed = 0;
169372b8ca3Sderaadt 
17029a085afSderaadt 	while ((ch = getopt(argc, argv, "ACHLlmbvaPSzZf:")) != -1) {
171054c7b81Shvozda 		switch (ch) {
172054c7b81Shvozda 		case 'v':
173054c7b81Shvozda 			verbose = TRUE;
174054c7b81Shvozda 			break;
175054c7b81Shvozda 		case 'f':
176054c7b81Shvozda 			sockname = optarg;
177054c7b81Shvozda 			break;
178054c7b81Shvozda 		case 'z':
179054c7b81Shvozda 			if (action != NONE)
180054c7b81Shvozda 				usage();
181054c7b81Shvozda 			action = SUSPEND;
182054c7b81Shvozda 			break;
183054c7b81Shvozda 		case 'S':
184054c7b81Shvozda 			if (action != NONE)
185054c7b81Shvozda 				usage();
186054c7b81Shvozda 			action = STANDBY;
187054c7b81Shvozda 			break;
18829a085afSderaadt 		case 'Z':
18929a085afSderaadt 			if (action != NONE)
19029a085afSderaadt 				usage();
19129a085afSderaadt 			action = HIBERNATE;
19229a085afSderaadt 			break;
193f6da2e61Ssturm 		case 'A':
194ab844ba2Sbeck 		case 'C':
195ab844ba2Sbeck 			if (action != NONE)
196ab844ba2Sbeck 				usage();
19759f67d8dSjca 			action = SETPERF_AUTO;
198ab844ba2Sbeck 			break;
199f6da2e61Ssturm 		case 'H':
200f6da2e61Ssturm 			if (action != NONE)
201f6da2e61Ssturm 				usage();
202f6da2e61Ssturm 			action = SETPERF_HIGH;
203f6da2e61Ssturm 			break;
204f6da2e61Ssturm 		case 'L':
205f6da2e61Ssturm 			if (action != NONE)
206f6da2e61Ssturm 				usage();
207f6da2e61Ssturm 			action = SETPERF_LOW;
208f6da2e61Ssturm 			break;
209054c7b81Shvozda 		case 'b':
210054c7b81Shvozda 			if (action != NONE && action != GETSTATUS)
211054c7b81Shvozda 				usage();
212054c7b81Shvozda 			dobstate = TRUE;
213054c7b81Shvozda 			action = GETSTATUS;
214054c7b81Shvozda 			break;
215054c7b81Shvozda 		case 'l':
216054c7b81Shvozda 			if (action != NONE && action != GETSTATUS)
217054c7b81Shvozda 				usage();
218054c7b81Shvozda 			dopct = TRUE;
219054c7b81Shvozda 			action = GETSTATUS;
220054c7b81Shvozda 			break;
221a7f3a53aSmickey 		case 'm':
222a7f3a53aSmickey 			if (action != NONE && action != GETSTATUS)
223a7f3a53aSmickey 				usage();
224a7f3a53aSmickey 			domin = TRUE;
225a7f3a53aSmickey 			action = GETSTATUS;
226a7f3a53aSmickey 			break;
227054c7b81Shvozda 		case 'a':
228054c7b81Shvozda 			if (action != NONE && action != GETSTATUS)
229054c7b81Shvozda 				usage();
230054c7b81Shvozda 			doac = TRUE;
231054c7b81Shvozda 			action = GETSTATUS;
232054c7b81Shvozda 			break;
233f6da2e61Ssturm 		case 'P':
234f6da2e61Ssturm 			if (action != NONE && action != GETSTATUS)
235f6da2e61Ssturm 				usage();
236f6da2e61Ssturm 			doperf = TRUE;
237f6da2e61Ssturm 			action = GETSTATUS;
238f6da2e61Ssturm 			break;
239054c7b81Shvozda 		default:
240224a603cSanton 			if (!strcmp(__progname, "zzz") ||
241224a603cSanton 			    !strcmp(__progname, "ZZZ"))
242b2c4cc1eSsobrado 				zzusage();
243b2c4cc1eSsobrado 			else
244054c7b81Shvozda 				usage();
245054c7b81Shvozda 		}
2466d78643eSderaadt 	}
247b15928b2Stedu 	argc -= optind;
248b15928b2Stedu 	argv += optind;
249b15928b2Stedu 	if (argc)
250b15928b2Stedu 		usage();
251054c7b81Shvozda 
252054c7b81Shvozda 	fd = open_socket(sockname);
253054c7b81Shvozda 
254cef29278Sderaadt 	if (fd != -1) {
2551c33ef21Smestre 		if (pledge("stdio", NULL) == -1)
256cef29278Sderaadt 			err(1, "pledge");
257cef29278Sderaadt 	}
258cef29278Sderaadt 
259ef1540bfSmickey 	if (!strcmp(__progname, "zzz")) {
260ef1540bfSmickey 		if (fd < 0)
261ef1540bfSmickey 			err(1, "cannot connect to apmd");
262ef1540bfSmickey 		else
263d246eb98Smickey 			return (do_zzz(fd, action));
26429a085afSderaadt 	} else if (!strcmp(__progname, "ZZZ")) {
26529a085afSderaadt 		if (fd < 0)
26629a085afSderaadt 			err(1, "cannot connect to apmd");
26729a085afSderaadt 		else
26829a085afSderaadt 			return (do_zzz(fd, HIBERNATE));
269ef1540bfSmickey 	}
270d246eb98Smickey 
27129a085afSderaadt 
272a2123b9aSderaadt 	bzero(&reply, sizeof reply);
273a2123b9aSderaadt 	reply.batterystate.battery_state = APM_BATT_UNKNOWN;
274a2123b9aSderaadt 	reply.batterystate.ac_state = APM_AC_UNKNOWN;
275a2123b9aSderaadt 	reply.perfmode = PERF_MANUAL;
276a2123b9aSderaadt 	reply.cpuspeed = cpuspeed;
277a2123b9aSderaadt 
278054c7b81Shvozda 	switch (action) {
279a2123b9aSderaadt 	case SETPERF_LOW:
280a2123b9aSderaadt 	case SETPERF_HIGH:
281a2123b9aSderaadt 	case SETPERF_AUTO:
282a2123b9aSderaadt 		if (fd == -1)
28357bc3fecSsturm 			errx(1, "cannot connect to apmd, "
28457bc3fecSsturm 			    "not changing performance adjustment mode");
285a2123b9aSderaadt 		goto balony;
286054c7b81Shvozda 	case NONE:
287054c7b81Shvozda 		action = GETSTATUS;
288afc54a00Ssturm 		verbose = doac = dopct = dobstate = domin = doperf = TRUE;
289cc5d5fa6Ssturm 		/* FALLTHROUGH */
290054c7b81Shvozda 	case GETSTATUS:
291054c7b81Shvozda 		if (fd == -1) {
292054c7b81Shvozda 			/* open the device directly and get status */
293054c7b81Shvozda 			fd = open(_PATH_APM_NORMAL, O_RDONLY);
294d246eb98Smickey 			if (ioctl(fd, APM_IOC_GETPOWER,
2951c33ef21Smestre 			    &reply.batterystate) == 0) {
2961c33ef21Smestre 				if (pledge("stdio", NULL) == -1)
2971c33ef21Smestre 					err(1, "pledge");
2981c33ef21Smestre 
299054c7b81Shvozda 				goto printval;
300054c7b81Shvozda 			}
3011c33ef21Smestre 		}
302cc5d5fa6Ssturm 		/* FALLTHROUGH */
303a2123b9aSderaadt balony:
304054c7b81Shvozda 	case SUSPEND:
305054c7b81Shvozda 	case STANDBY:
30629a085afSderaadt 	case HIBERNATE:
307054c7b81Shvozda 		command.action = action;
308054c7b81Shvozda 		break;
309054c7b81Shvozda 	default:
310054c7b81Shvozda 		usage();
311054c7b81Shvozda 	}
312054c7b81Shvozda 
313a2123b9aSderaadt 	if (fd != -1 && (rval = send_command(fd, &command, &reply)) != 0)
3146d78643eSderaadt 		errx(rval, "cannot get reply from APM daemon");
3156d78643eSderaadt 
316054c7b81Shvozda 	switch (action) {
317054c7b81Shvozda 	case GETSTATUS:
318054c7b81Shvozda 	printval:
3196d78643eSderaadt 		if (!verbose) {
320054c7b81Shvozda 			if (dobstate)
321d246eb98Smickey 				printf("%d\n",
322d246eb98Smickey 				    reply.batterystate.battery_state);
323054c7b81Shvozda 			if (dopct)
324d246eb98Smickey 				printf("%d\n",
325d246eb98Smickey 				    reply.batterystate.battery_life);
326e4613c9eSmiod 			if (domin) {
327e4613c9eSmiod 				if (reply.batterystate.minutes_left ==
328e4613c9eSmiod 				    (u_int)-1)
329e4613c9eSmiod 					printf("unknown\n");
330e4613c9eSmiod 				else
331d246eb98Smickey 					printf("%d\n",
332d246eb98Smickey 					    reply.batterystate.minutes_left);
333e4613c9eSmiod 			}
334054c7b81Shvozda 			if (doac)
335d246eb98Smickey 				printf("%d\n",
336d246eb98Smickey 				    reply.batterystate.ac_state);
337f6da2e61Ssturm 			if (doperf)
338a99a7ef6Ssturm 				printf("%d\n", reply.perfmode);
3396d78643eSderaadt 			break;
340054c7b81Shvozda 		}
341afc54a00Ssturm 
342afc54a00Ssturm 		if (dobstate) {
343afc54a00Ssturm 			printf("Battery state: %s",
3446d78643eSderaadt 			    battstate(reply.batterystate.battery_state));
345afc54a00Ssturm 			if (!dopct && !domin)
346afc54a00Ssturm 				printf("\n");
347afc54a00Ssturm 		}
348afc54a00Ssturm 
349afc54a00Ssturm 		if (dopct && !dobstate)
350afc54a00Ssturm 			printf("Battery remaining: %d percent",
3516d78643eSderaadt 			    reply.batterystate.battery_life);
352afc54a00Ssturm 		else if (dopct)
353afc54a00Ssturm 			printf(", %d%% remaining",
354afc54a00Ssturm 			    reply.batterystate.battery_life);
355afc54a00Ssturm 		if (dopct && !domin)
356afc54a00Ssturm 			printf("\n");
357afc54a00Ssturm 
358afc54a00Ssturm 		if (domin && !dobstate && !dopct) {
3596d78643eSderaadt 			if (reply.batterystate.battery_state ==
3606d78643eSderaadt 			    APM_BATT_CHARGING)
3616d78643eSderaadt 				printf("Remaining battery recharge "
3626d78643eSderaadt 				    "time estimate: %d minutes\n",
3636d78643eSderaadt 				    reply.batterystate.minutes_left);
3646d78643eSderaadt 			else if (reply.batterystate.minutes_left == 0 &&
3656d78643eSderaadt 			    reply.batterystate.battery_life > 10)
3666d78643eSderaadt 				printf("Battery life estimate: "
3676d78643eSderaadt 				    "not available\n");
3686d78643eSderaadt 			else
369e4613c9eSmiod 			{
370e4613c9eSmiod 				printf("Battery life estimate: ");
371e4613c9eSmiod 				if (reply.batterystate.minutes_left ==
372e4613c9eSmiod 				    (u_int)-1)
373e4613c9eSmiod 					printf("unknown\n");
374e4613c9eSmiod 				else
375e4613c9eSmiod 					printf("%d minutes\n",
3766d78643eSderaadt 					    reply.batterystate.minutes_left);
3776d78643eSderaadt 			}
378afc54a00Ssturm 		} else if (domin) {
379afc54a00Ssturm 			if (reply.batterystate.battery_state ==
380afc54a00Ssturm 			    APM_BATT_CHARGING)
38106f42f13Ssdk 			{
38206f42f13Ssdk 				if (reply.batterystate.minutes_left ==
38306f42f13Ssdk 				    (u_int)-1)
38406f42f13Ssdk 					printf(", unknown");
38506f42f13Ssdk 				else
38606f42f13Ssdk 					printf(", %d minutes",
387afc54a00Ssturm 					    reply.batterystate.minutes_left);
38806f42f13Ssdk 				printf(" recharge time estimate\n");
38906f42f13Ssdk 			}
390afc54a00Ssturm 			else if (reply.batterystate.minutes_left == 0 &&
391afc54a00Ssturm 			    reply.batterystate.battery_life > 10)
392afc54a00Ssturm 				printf(", unknown life estimate\n");
393afc54a00Ssturm 			else
394afc54a00Ssturm 			{
395afc54a00Ssturm 				if (reply.batterystate.minutes_left ==
396afc54a00Ssturm 				    (u_int)-1)
397afc54a00Ssturm 					printf(", unknown");
398afc54a00Ssturm 				else
399afc54a00Ssturm 					printf(", %d minutes",
400afc54a00Ssturm 					    reply.batterystate.minutes_left);
401afc54a00Ssturm 				printf(" life estimate\n");
402e4613c9eSmiod 			}
403afc54a00Ssturm 		}
404afc54a00Ssturm 
4056d78643eSderaadt 		if (doac)
406ac50edb2Sjmc 			printf("AC adapter state: %s\n",
4076d78643eSderaadt 			    ac_state(reply.batterystate.ac_state));
408afc54a00Ssturm 
409f6da2e61Ssturm 		if (doperf)
410a99a7ef6Ssturm 			printf("Performance adjustment mode: %s (%d MHz)\n",
411a99a7ef6Ssturm 			    perf_mode(reply.perfmode), reply.cpuspeed);
412054c7b81Shvozda 		break;
413054c7b81Shvozda 	default:
414dc8cf138Sderaadt 		break;
415054c7b81Shvozda 	}
4166d78643eSderaadt 
417054c7b81Shvozda 	switch (reply.newstate) {
418054c7b81Shvozda 	case SUSPEND:
419054c7b81Shvozda 		printf("System will enter suspend mode momentarily.\n");
420054c7b81Shvozda 		break;
421054c7b81Shvozda 	case STANDBY:
422054c7b81Shvozda 		printf("System will enter standby mode momentarily.\n");
423054c7b81Shvozda 		break;
42429a085afSderaadt 	case HIBERNATE:
42529a085afSderaadt 		printf("System will enter hibernate mode momentarily.\n");
42629a085afSderaadt 		break;
427054c7b81Shvozda 	default:
428dc8cf138Sderaadt 		break;
429054c7b81Shvozda 	}
430c7cff24eSkn 	if (reply.error)
431c7cff24eSkn 		errx(1, "%s: %s", apm_state(reply.newstate), strerror(reply.error));
432a7f3a53aSmickey 	return (0);
433054c7b81Shvozda }
434