aboutsummaryrefslogtreecommitdiff
path: root/util-linux
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-11-29 09:05:50 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-11-29 09:05:50 +0000
commitd16950ded91446a23a6ceef35fb3e100400301d9 (patch)
tree038faff9ea801e5d7f022b75256fc52e66186b75 /util-linux
parentf7d87f9b183aa28777ce09d40222fbe221d15c91 (diff)
downloadbusybox-w32-d16950ded91446a23a6ceef35fb3e100400301d9.tar.gz
busybox-w32-d16950ded91446a23a6ceef35fb3e100400301d9.tar.bz2
busybox-w32-d16950ded91446a23a6ceef35fb3e100400301d9.zip
acpid: new applet by Vladimir. +737 bytes
Diffstat (limited to 'util-linux')
-rw-r--r--util-linux/Config.in22
-rw-r--r--util-linux/Kbuild1
-rw-r--r--util-linux/acpid.c167
3 files changed, 190 insertions, 0 deletions
diff --git a/util-linux/Config.in b/util-linux/Config.in
index 976507b68..3bba2e26d 100644
--- a/util-linux/Config.in
+++ b/util-linux/Config.in
@@ -5,6 +5,28 @@
5 5
6menu "Linux System Utilities" 6menu "Linux System Utilities"
7 7
8config ACPID
9 bool "acpid"
10 default n
11 help
12 acpid listens to ACPI events coming either in textual form from
13 /proc/acpi/event (though it is marked deprecated it is still widely
14 used and _is_ a standard) or in binary form from specified evdevs
15 (just use /dev/input/event*).
16
17 It parses the event to retrieve ACTION and a possible PARAMETER.
18 It then spawns /etc/acpi/<ACTION>[/<PARAMETER>] either via run-parts
19 (if the resulting path is a directory) or directly as an executable.
20
21 N.B. acpid relies on run-parts so have the latter installed.
22
23config FEATURE_ACPID_COMPAT
24 bool "Accept and ignore redundant options"
25 default n
26 depends on ACPID
27 help
28 Accept and ignore compatibility options -g -m -s -S -v.
29
8config BLKID 30config BLKID
9 bool "blkid" 31 bool "blkid"
10 default n 32 default n
diff --git a/util-linux/Kbuild b/util-linux/Kbuild
index 2d0fc4928..842afb756 100644
--- a/util-linux/Kbuild
+++ b/util-linux/Kbuild
@@ -5,6 +5,7 @@
5# Licensed under the GPL v2, see the file LICENSE in this tarball. 5# Licensed under the GPL v2, see the file LICENSE in this tarball.
6 6
7lib-y:= 7lib-y:=
8lib-$(CONFIG_ACPID) += acpid.o
8lib-$(CONFIG_BLKID) += blkid.o 9lib-$(CONFIG_BLKID) += blkid.o
9lib-$(CONFIG_DMESG) += dmesg.o 10lib-$(CONFIG_DMESG) += dmesg.o
10lib-$(CONFIG_FBSET) += fbset.o 11lib-$(CONFIG_FBSET) += fbset.o
diff --git a/util-linux/acpid.c b/util-linux/acpid.c
new file mode 100644
index 000000000..ef4e54d5d
--- /dev/null
+++ b/util-linux/acpid.c
@@ -0,0 +1,167 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * simple ACPI events listener
4 *
5 * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
6 *
7 * Licensed under GPLv2, see file LICENSE in this tarball for details.
8 */
9#include "libbb.h"
10
11#include <linux/input.h>
12#ifndef SW_RFKILL_ALL
13# define SW_RFKILL_ALL 3
14#endif
15
16/*
17 * acpid listens to ACPI events coming either in textual form
18 * from /proc/acpi/event (though it is marked deprecated,
19 * it is still widely used and _is_ a standard) or in binary form
20 * from specified evdevs (just use /dev/input/event*).
21 * It parses the event to retrieve ACTION and a possible PARAMETER.
22 * It then spawns /etc/acpi/<ACTION>[/<PARAMETER>] either via run-parts
23 * (if the resulting path is a directory) or directly.
24 * If the resulting path does not exist it logs it via perror
25 * and continues listening.
26 */
27
28static void process_event(const char *event)
29{
30 struct stat st;
31 char *handler = xasprintf("./%s", event);
32 const char *args[] = { "run-parts", handler, NULL };
33
34 // debug info
35 if (option_mask32 & 8) { // -d
36 bb_error_msg("%s", event);
37 }
38
39 // spawn handler
40 // N.B. run-parts would require scripts to have #!/bin/sh
41 // handler is directory? -> use run-parts
42 // handler is file? -> run it directly
43 if (0 == stat(event, &st))
44 spawn((char **)args + (0==(st.st_mode & S_IFDIR)));
45 else
46 bb_simple_perror_msg(event);
47 free(handler);
48}
49
50/*
51 * acpid [-c conf_dir] [-l log_file] [-e proc_event_file] [evdev_event_file...]
52*/
53
54int acpid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
55int acpid_main(int argc, char **argv)
56{
57 struct pollfd *pfd;
58 int i, nfd;
59 const char *opt_conf = "/etc/acpi";
60 const char *opt_input = "/proc/acpi/event";
61 const char *opt_logfile = "/var/log/acpid.log";
62
63 getopt32(argv, "c:e:l:d"
64 USE_FEATURE_ACPID_COMPAT("g:m:s:S:v"),
65 &opt_conf, &opt_input, &opt_logfile
66 USE_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL, NULL)
67 );
68
69 // daemonize unless -d given
70 if (!(option_mask32 & 8)) { // ! -d
71 bb_daemonize_or_rexec(0, argv);
72 close(2);
73 xopen(opt_logfile, O_WRONLY | O_CREAT | O_TRUNC);
74 }
75
76 argv += optind;
77
78 // goto configuration directory
79 xchdir(opt_conf);
80
81// // setup signals
82// bb_signals(BB_FATAL_SIGS, record_signo);
83
84 // no explicit evdev files given? -> use proc event interface
85 if (!*argv) {
86 // proc_event file is just a "config" :)
87 char *token[4];
88 parser_t *parser = config_open(opt_input);
89
90 // dispatch events
91 while (config_read(parser, token, 4, 4, "\0 ", PARSE_NORMAL)) {
92 char *event = xasprintf("%s/%s", token[1], token[2]);
93 process_event(event);
94 free(event);
95 }
96
97 if (ENABLE_FEATURE_CLEAN_UP)
98 config_close(parser);
99 return EXIT_SUCCESS;
100 }
101
102 // evdev files given, use evdev interface
103
104 // open event devices
105 pfd = xzalloc(sizeof(*pfd) * (argc - optind));
106 nfd = 0;
107 while (*argv) {
108 pfd[nfd].fd = open_or_warn(*argv++, O_RDONLY | O_NONBLOCK);
109 if (pfd[nfd].fd >= 0)
110 pfd[nfd++].events = POLLIN;
111 }
112
113 // dispatch events
114 while (/* !bb_got_signal && */ poll(pfd, nfd, -1) > 0) {
115 for (i = 0; i < nfd; i++) {
116 const char *event;
117 struct input_event ev;
118
119 if (!(pfd[i].revents & POLLIN))
120 continue;
121
122 if (sizeof(ev) != full_read(pfd[i].fd, &ev, sizeof(ev)))
123 continue;
124//bb_info_msg("%d: %d %d %4d", i, ev.type, ev.code, ev.value);
125
126 // filter out unneeded events
127 if (ev.value != 1)
128 continue;
129
130 event = NULL;
131
132 // N.B. we will conform to /proc/acpi/event
133 // naming convention when assigning event names
134
135 // TODO: do we want other events?
136
137 // power and sleep buttons delivered as keys pressed
138 if (EV_KEY == ev.type) {
139 if (KEY_POWER == ev.code)
140 event = "PWRF/00000080";
141 else if (KEY_SLEEP == ev.code)
142 event = "SLPB/00000080";
143 }
144 // switches
145 else if (EV_SW == ev.type) {
146 if (SW_LID == ev.code)
147 event = "LID/00000080";
148 else if (SW_RFKILL_ALL == ev.code)
149 event = "RFKILL";
150 }
151 // filter out unneeded events
152 if (!event)
153 continue;
154
155 // spawn event handler
156 process_event(event);
157 }
158 }
159
160 if (ENABLE_FEATURE_CLEAN_UP) {
161 for (i = 0; i < nfd; i++)
162 close(pfd[i].fd);
163 free(pfd);
164 }
165
166 return EXIT_SUCCESS;
167}