1 /* $NetBSD: apm.c,v 1.19 2008/04/28 20:24:15 martin Exp $ */
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
34 #include <sys/socket.h>
38 #include <machine/apmvar.h>
48 #include "pathnames.h"
49 #include "apm-proto.h"
56 int do_zzz(const char *, enum apm_action
);
57 int open_socket(const char *);
58 int send_command(int, struct apm_command
*, struct apm_reply
*);
64 fprintf(stderr
,"usage: %s [-v] [-z | -S] [-abdlms] [-f socket]\n",
73 fprintf(stderr
,"usage: %s [-z | -S] [-f socket]\n",
80 struct apm_command
*cmd
,
81 struct apm_reply
*reply
)
84 /* send a command to the apm daemon */
87 if (send(fd
, cmd
, sizeof(*cmd
), 0) == sizeof(*cmd
)) {
88 if (recv(fd
, reply
, sizeof(*reply
), 0) != sizeof(*reply
)) {
89 warn("invalid reply from APM daemon");
93 warn("invalid send to APM daemon");
100 do_zzz(const char *pn
, enum apm_action action
)
102 struct apm_command command
;
103 struct apm_reply reply
;
109 command
.action
= SUSPEND
;
112 command
.action
= STANDBY
;
118 fd
= open_socket(pn
);
120 err(1, "cannot open connection to APM daemon");
121 printf("Suspending system...\n");
122 exit(send_command(fd
, &command
, &reply
));
126 open_socket(const char *sockname
)
128 struct sockaddr_un s_un
;
131 sock
= socket(AF_LOCAL
, SOCK_STREAM
, 0);
133 err(1, "cannot create local socket");
135 s_un
.sun_family
= AF_LOCAL
;
136 strncpy(s_un
.sun_path
, sockname
, sizeof(s_un
.sun_path
));
137 s_un
.sun_len
= SUN_LEN(&s_un
);
138 if (connect(sock
, (struct sockaddr
*)&s_un
, s_un
.sun_len
) == -1) {
148 main(int argc
, char *argv
[])
150 struct apm_command command
;
151 struct apm_reply reply
;
152 struct apm_power_info
*api
= &reply
.batterystate
;
153 const char *sockname
= _PATH_APM_SOCKET
;
154 enum apm_action action
= NONE
;
155 int ch
, doac
, dobstate
, domin
, dopct
, dostatus
, fd
, nodaemon
,
158 doac
= dobstate
= domin
= dopct
= dostatus
= nodaemon
=
160 while ((ch
= getopt(argc
, argv
, "Sabdf:lmsvz")) != -1)
179 if (action
!= NONE
&& action
!= GETSTATUS
)
185 if (action
!= NONE
&& action
!= GETSTATUS
)
191 if (action
!= NONE
&& action
!= GETSTATUS
)
197 if (action
!= NONE
&& action
!= GETSTATUS
)
203 if (action
!= NONE
&& action
!= GETSTATUS
)
216 if (strcmp(getprogname(), "zzz") == 0)
217 exit(do_zzz(sockname
, action
));
222 fd
= open_socket(sockname
);
226 verbose
= doac
= dopct
= domin
= dobstate
= dostatus
= TRUE
;
231 /* open the device directly and get status */
232 fd
= open(_PATH_APM_NORMAL
, O_RDONLY
);
234 err(1, "cannot contact APM daemon and "
238 memset(&reply
, 0, sizeof(reply
));
239 if (ioctl(fd
, APM_IOC_GETPOWER
,
240 &reply
.batterystate
) == -1)
241 err(1, "ioctl(APM_IOC_GETPOWER)");
247 if (nodaemon
&& fd
== -1) {
248 fd
= open(_PATH_APM_CTLDEV
, O_RDWR
);
250 err(1, "cannot open APM control device "
255 if (ioctl(fd
, action
== SUSPEND
?
256 APM_IOC_SUSPEND
: APM_IOC_STANDBY
, 0) == -1)
257 err(1, "cannot enter requested power state");
258 printf("System will enter %s in a moment.\n",
259 action
== SUSPEND
? "suspend mode" :
263 err(1, "cannot contact APM daemon at socket "
265 command
.action
= action
;
271 if ((rval
= send_command(fd
, &command
, &reply
)) == 0) {
277 printf("Battery charge state: %s\n",
278 battstate(api
->battery_state
));
280 if (dopct
&& domin
&& api
->minutes_left
== 0)
283 if (dopct
|| domin
) {
284 printf("Battery remaining: ");
298 printf("A/C adapter state: %s\n",
299 ac_state(api
->ac_state
));
301 printf("Power management enabled\n");
303 printf("Number of batteries: %u\n",
308 printf("%d\n", api
->battery_state
);
310 printf("%d\n", api
->battery_life
);
312 printf("%d\n", api
->minutes_left
);
314 printf("%d\n", api
->ac_state
);
322 switch (reply
.newstate
) {
324 printf("System will enter suspend mode "
328 printf("System will enter standby mode "
335 errx(rval
, "cannot get reply from APM daemon");