1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
/* acpi.c - show power state
*
* Written by Isaac Dunham, 2013
*
* No standard.
USE_ACPI(NEWTOY(acpi, "ab", TOYFLAG_USR|TOYFLAG_BIN))
config ACPI
bool "acpi"
default y
help
usage: acpi [-ab]
Show status of power sources.
-a show power adapters
-b show batteries
*/
#define FOR_acpi
#include "toys.h"
GLOBALS(
int ac;
int bat;
)
int read_int_at(int dirfd, char *name)
{
int fd, ret=0;
FILE *fil;
if ((fd = openat(dirfd, name, O_RDONLY)) < 0) return -1;
fscanf(fil = xfdopen(fd, "r"), "%d", &ret);
fclose(fil);
return ret;
}
int acpi_callback(struct dirtree *tree)
{
int dfd;
errno = 0;
if (tree->name[0]=='.') return 0;
if (strlen(dirtree_path(tree, NULL)) < 26)
return DIRTREE_RECURSE | DIRTREE_SYMFOLLOW;
if (0 <= (dfd = open(dirtree_path(tree, NULL), O_RDONLY))) {
int fd, len;
if ((fd = openat(dfd, "type", O_RDONLY)) < 0) goto done;
len = readall(fd, toybuf, sizeof(toybuf));
close(fd);
if (len < 1) goto done;
if (!strncmp(toybuf, "Battery", 7)) {
if ((toys.optflags & FLAG_b) || (!toys.optflags)) {
int cap = 0, curr = 0, max = 0;
if ((cap = read_int_at(dfd, "capacity")) < 0) {
if ((max = read_int_at(dfd, "charge_full")) > 0)
curr = read_int_at(dfd, "charge_now");
else if ((max = read_int_at(dfd, "energy_full")) > 0)
curr = read_int_at(dfd, "energy_now");
if (max > 0 && curr >= 0) cap = 100 * curr / max;
}
if (cap >= 0) printf("Battery %d: %d%%\n", TT.bat++, cap);
}
} else if (toys.optflags & FLAG_a) {
int on;
if ((on = read_int_at(dfd, "online")) >= 0)
printf("Adapter %d: %s-line\n", TT.ac++, (on ? "on" : "off"));
}
done:
close(dfd);
}
return 0;
}
void acpi_main(void)
{
dirtree_read("/sys/class/power_supply", acpi_callback);
}
|