File: | src/usr.sbin/apm/apm.c |
Warning: | line 246, column 2 Value stored to 'argv' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: apm.c,v 1.38 2021/04/06 20:30:32 kn Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 1996 John T. Kohl |
5 | * All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. The name of the author may not be used to endorse or promote products |
16 | * derived from this software without specific prior written permission. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
21 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, |
22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
27 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
28 | * POSSIBILITY OF SUCH DAMAGE. |
29 | * |
30 | */ |
31 | |
32 | #include <sys/types.h> |
33 | #include <sys/sysctl.h> |
34 | #include <sys/socket.h> |
35 | #include <sys/un.h> |
36 | #include <sys/ioctl.h> |
37 | #include <machine/apmvar.h> |
38 | #include <stdio.h> |
39 | #include <stdlib.h> |
40 | #include <unistd.h> |
41 | #include <fcntl.h> |
42 | #include <errno(*__errno()).h> |
43 | #include <err.h> |
44 | #include <string.h> |
45 | #include "pathnames.h" |
46 | #include "apm-proto.h" |
47 | |
48 | #define FALSE0 0 |
49 | #define TRUE1 1 |
50 | |
51 | extern char *__progname; |
52 | |
53 | static int do_zzz(int, enum apm_action); |
54 | static int open_socket(const char *); |
55 | static int send_command(int, struct apm_command *, |
56 | struct apm_reply *); |
57 | static __dead__attribute__((__noreturn__)) void usage(void); |
58 | static __dead__attribute__((__noreturn__)) void zzusage(void); |
59 | |
60 | static __dead__attribute__((__noreturn__)) void |
61 | usage(void) |
62 | { |
63 | fprintf(stderr(&__sF[2]),"usage: %s [-AabHLlmPSvZz] [-f sockname]\n", |
64 | __progname); |
65 | exit(1); |
66 | } |
67 | |
68 | static __dead__attribute__((__noreturn__)) void |
69 | zzusage(void) |
70 | { |
71 | fprintf(stderr(&__sF[2]),"usage: %s [-SZz] [-f sockname]\n", |
72 | __progname); |
73 | exit(1); |
74 | } |
75 | |
76 | static int |
77 | send_command(int fd, struct apm_command *cmd, struct apm_reply *reply) |
78 | { |
79 | /* send a command to the apm daemon */ |
80 | cmd->vno = APMD_VNO4; |
81 | |
82 | if (send(fd, cmd, sizeof(*cmd), 0) == sizeof(*cmd)) { |
83 | if (recv(fd, reply, sizeof(*reply), 0) != sizeof(*reply)) { |
84 | warn("invalid reply from APM daemon"); |
85 | return (1); |
86 | } |
87 | } else { |
88 | warn("invalid send to APM daemon"); |
89 | return (1); |
90 | } |
91 | return (0); |
92 | } |
93 | |
94 | static int |
95 | do_zzz(int fd, enum apm_action action) |
96 | { |
97 | struct apm_command command; |
98 | struct apm_reply reply; |
99 | char *msg; |
100 | int ret; |
101 | |
102 | switch (action) { |
103 | case NONE: |
104 | case SUSPEND: |
105 | command.action = SUSPEND; |
106 | msg = "Suspending system"; |
107 | break; |
108 | case STANDBY: |
109 | command.action = STANDBY; |
110 | msg = "System standing by"; |
111 | break; |
112 | case HIBERNATE: |
113 | command.action = HIBERNATE; |
114 | msg = "Hibernating system"; |
115 | break; |
116 | default: |
117 | zzusage(); |
118 | } |
119 | |
120 | printf("%s...\n", msg); |
121 | ret = send_command(fd, &command, &reply); |
122 | if (reply.error) |
123 | errx(1, "%s: %s", apm_state(reply.newstate), strerror(reply.error)); |
124 | exit(ret); |
125 | } |
126 | |
127 | static int |
128 | open_socket(const char *sockname) |
129 | { |
130 | int sock, errr; |
131 | struct sockaddr_un s_un; |
132 | |
133 | sock = socket(AF_UNIX1, SOCK_STREAM1, 0); |
134 | if (sock == -1) |
135 | err(1, "cannot create local socket"); |
136 | |
137 | s_un.sun_family = AF_UNIX1; |
138 | strlcpy(s_un.sun_path, sockname, sizeof(s_un.sun_path)); |
139 | if (connect(sock, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) { |
140 | errr = errno(*__errno()); |
141 | close(sock); |
142 | errno(*__errno()) = errr; |
143 | sock = -1; |
144 | } |
145 | return (sock); |
146 | } |
147 | |
148 | int |
149 | main(int argc, char *argv[]) |
150 | { |
151 | const char *sockname = _PATH_APM_SOCKET"/var/run/apmdev"; |
152 | int doac = FALSE0; |
153 | int dopct = FALSE0; |
154 | int dobstate = FALSE0; |
155 | int domin = FALSE0; |
156 | int doperf = FALSE0; |
157 | int verbose = FALSE0; |
158 | int ch, fd, rval; |
159 | enum apm_action action = NONE; |
160 | struct apm_command command; |
161 | struct apm_reply reply; |
162 | int cpuspeed_mib[] = { CTL_HW6, HW_CPUSPEED12 }, cpuspeed; |
163 | size_t cpuspeed_sz = sizeof(cpuspeed); |
164 | |
165 | if (sysctl(cpuspeed_mib, 2, &cpuspeed, &cpuspeed_sz, NULL((void *)0), 0) == -1) |
166 | err(1, "sysctl hw.cpuspeed"); |
167 | |
168 | while ((ch = getopt(argc, argv, "ACHLlmbvaPSzZf:")) != -1) { |
169 | switch (ch) { |
170 | case 'v': |
171 | verbose = TRUE1; |
172 | break; |
173 | case 'f': |
174 | sockname = optarg; |
175 | break; |
176 | case 'z': |
177 | if (action != NONE) |
178 | usage(); |
179 | action = SUSPEND; |
180 | break; |
181 | case 'S': |
182 | if (action != NONE) |
183 | usage(); |
184 | action = STANDBY; |
185 | break; |
186 | case 'Z': |
187 | if (action != NONE) |
188 | usage(); |
189 | action = HIBERNATE; |
190 | break; |
191 | case 'A': |
192 | case 'C': |
193 | if (action != NONE) |
194 | usage(); |
195 | action = SETPERF_AUTO; |
196 | break; |
197 | case 'H': |
198 | if (action != NONE) |
199 | usage(); |
200 | action = SETPERF_HIGH; |
201 | break; |
202 | case 'L': |
203 | if (action != NONE) |
204 | usage(); |
205 | action = SETPERF_LOW; |
206 | break; |
207 | case 'b': |
208 | if (action != NONE && action != GETSTATUS) |
209 | usage(); |
210 | dobstate = TRUE1; |
211 | action = GETSTATUS; |
212 | break; |
213 | case 'l': |
214 | if (action != NONE && action != GETSTATUS) |
215 | usage(); |
216 | dopct = TRUE1; |
217 | action = GETSTATUS; |
218 | break; |
219 | case 'm': |
220 | if (action != NONE && action != GETSTATUS) |
221 | usage(); |
222 | domin = TRUE1; |
223 | action = GETSTATUS; |
224 | break; |
225 | case 'a': |
226 | if (action != NONE && action != GETSTATUS) |
227 | usage(); |
228 | doac = TRUE1; |
229 | action = GETSTATUS; |
230 | break; |
231 | case 'P': |
232 | if (action != NONE && action != GETSTATUS) |
233 | usage(); |
234 | doperf = TRUE1; |
235 | action = GETSTATUS; |
236 | break; |
237 | default: |
238 | if (!strcmp(__progname, "zzz") || |
239 | !strcmp(__progname, "ZZZ")) |
240 | zzusage(); |
241 | else |
242 | usage(); |
243 | } |
244 | } |
245 | argc -= optind; |
246 | argv += optind; |
Value stored to 'argv' is never read | |
247 | if (argc) |
248 | usage(); |
249 | |
250 | fd = open_socket(sockname); |
251 | |
252 | if (fd != -1) { |
253 | if (pledge("stdio", NULL((void *)0)) == -1) |
254 | err(1, "pledge"); |
255 | } |
256 | |
257 | if (!strcmp(__progname, "zzz")) { |
258 | if (fd < 0) |
259 | err(1, "cannot connect to apmd"); |
260 | else |
261 | return (do_zzz(fd, action)); |
262 | } else if (!strcmp(__progname, "ZZZ")) { |
263 | if (fd < 0) |
264 | err(1, "cannot connect to apmd"); |
265 | else |
266 | return (do_zzz(fd, HIBERNATE)); |
267 | } |
268 | |
269 | |
270 | bzero(&reply, sizeof reply); |
271 | reply.batterystate.battery_state = APM_BATT_UNKNOWN0xff; |
272 | reply.batterystate.ac_state = APM_AC_UNKNOWN0xff; |
273 | reply.perfmode = PERF_MANUAL; |
274 | reply.cpuspeed = cpuspeed; |
275 | |
276 | switch (action) { |
277 | case SETPERF_LOW: |
278 | case SETPERF_HIGH: |
279 | case SETPERF_AUTO: |
280 | if (fd == -1) |
281 | errx(1, "cannot connect to apmd, " |
282 | "not changing performance adjustment mode"); |
283 | goto balony; |
284 | case NONE: |
285 | action = GETSTATUS; |
286 | verbose = doac = dopct = dobstate = domin = doperf = TRUE1; |
287 | /* FALLTHROUGH */ |
288 | case GETSTATUS: |
289 | if (fd == -1) { |
290 | /* open the device directly and get status */ |
291 | fd = open(_PATH_APM_NORMAL"/dev/apm", O_RDONLY0x0000); |
292 | if (ioctl(fd, APM_IOC_GETPOWER((unsigned long)0x40000000 | ((sizeof(struct apm_power_info) & 0x1fff) << 16) | ((('A')) << 8) | ((3))), |
293 | &reply.batterystate) == 0) { |
294 | if (pledge("stdio", NULL((void *)0)) == -1) |
295 | err(1, "pledge"); |
296 | |
297 | goto printval; |
298 | } |
299 | } |
300 | /* FALLTHROUGH */ |
301 | balony: |
302 | case SUSPEND: |
303 | case STANDBY: |
304 | case HIBERNATE: |
305 | command.action = action; |
306 | break; |
307 | default: |
308 | usage(); |
309 | } |
310 | |
311 | if (fd != -1 && (rval = send_command(fd, &command, &reply)) != 0) |
312 | errx(rval, "cannot get reply from APM daemon"); |
313 | |
314 | switch (action) { |
315 | case GETSTATUS: |
316 | printval: |
317 | if (!verbose) { |
318 | if (dobstate) |
319 | printf("%d\n", |
320 | reply.batterystate.battery_state); |
321 | if (dopct) |
322 | printf("%d\n", |
323 | reply.batterystate.battery_life); |
324 | if (domin) { |
325 | if (reply.batterystate.minutes_left == |
326 | (u_int)-1) |
327 | printf("unknown\n"); |
328 | else |
329 | printf("%d\n", |
330 | reply.batterystate.minutes_left); |
331 | } |
332 | if (doac) |
333 | printf("%d\n", |
334 | reply.batterystate.ac_state); |
335 | if (doperf) |
336 | printf("%d\n", reply.perfmode); |
337 | break; |
338 | } |
339 | |
340 | if (dobstate) { |
341 | printf("Battery state: %s", |
342 | battstate(reply.batterystate.battery_state)); |
343 | if (!dopct && !domin) |
344 | printf("\n"); |
345 | } |
346 | |
347 | if (dopct && !dobstate) |
348 | printf("Battery remaining: %d percent", |
349 | reply.batterystate.battery_life); |
350 | else if (dopct) |
351 | printf(", %d%% remaining", |
352 | reply.batterystate.battery_life); |
353 | if (dopct && !domin) |
354 | printf("\n"); |
355 | |
356 | if (domin && !dobstate && !dopct) { |
357 | #ifdef __powerpc__ |
358 | if (reply.batterystate.battery_state == |
359 | APM_BATT_CHARGING0x03) |
360 | printf("Remaining battery recharge " |
361 | "time estimate: %d minutes\n", |
362 | reply.batterystate.minutes_left); |
363 | else if (reply.batterystate.minutes_left == 0 && |
364 | reply.batterystate.battery_life > 10) |
365 | printf("Battery life estimate: " |
366 | "not available\n"); |
367 | else |
368 | #endif |
369 | { |
370 | printf("Battery life estimate: "); |
371 | if (reply.batterystate.minutes_left == |
372 | (u_int)-1) |
373 | printf("unknown\n"); |
374 | else |
375 | printf("%d minutes\n", |
376 | reply.batterystate.minutes_left); |
377 | } |
378 | } else if (domin) { |
379 | #ifdef __powerpc__ |
380 | if (reply.batterystate.battery_state == |
381 | APM_BATT_CHARGING0x03) |
382 | printf(", %d minutes recharge time estimate\n", |
383 | reply.batterystate.minutes_left); |
384 | else if (reply.batterystate.minutes_left == 0 && |
385 | reply.batterystate.battery_life > 10) |
386 | printf(", unknown life estimate\n"); |
387 | else |
388 | #endif |
389 | { |
390 | if (reply.batterystate.minutes_left == |
391 | (u_int)-1) |
392 | printf(", unknown"); |
393 | else |
394 | printf(", %d minutes", |
395 | reply.batterystate.minutes_left); |
396 | printf(" life estimate\n"); |
397 | } |
398 | } |
399 | |
400 | if (doac) |
401 | printf("A/C adapter state: %s\n", |
402 | ac_state(reply.batterystate.ac_state)); |
403 | |
404 | if (doperf) |
405 | printf("Performance adjustment mode: %s (%d MHz)\n", |
406 | perf_mode(reply.perfmode), reply.cpuspeed); |
407 | break; |
408 | default: |
409 | break; |
410 | } |
411 | |
412 | switch (reply.newstate) { |
413 | case SUSPEND: |
414 | printf("System will enter suspend mode momentarily.\n"); |
415 | break; |
416 | case STANDBY: |
417 | printf("System will enter standby mode momentarily.\n"); |
418 | break; |
419 | case HIBERNATE: |
420 | printf("System will enter hibernate mode momentarily.\n"); |
421 | break; |
422 | default: |
423 | break; |
424 | } |
425 | if (reply.error) |
426 | errx(1, "%s: %s", apm_state(reply.newstate), strerror(reply.error)); |
427 | return (0); |
428 | } |