acpid: new applet by Vladimir. +737 bytes
This commit is contained in:
parent
f7d87f9b18
commit
d16950ded9
@ -32,8 +32,8 @@
|
|||||||
<a href="http://busybox.net/downloads/fixes-1.12.3/">patches</a>,
|
<a href="http://busybox.net/downloads/fixes-1.12.3/">patches</a>,
|
||||||
<a href="http://busybox.net/fix.html">how to add a patch</a>)</p>
|
<a href="http://busybox.net/fix.html">how to add a patch</a>)</p>
|
||||||
|
|
||||||
<p>Bug-fix releases. 1.13.1 has fixes for ash, option parsing, id, init,
|
<p>Bug fix releases. 1.13.1 has fixes for ash, option parsing, id, init,
|
||||||
inotify, klogd, line editing and modprobe. 1.12.3 has fixes
|
inotifyd, klogd, line editing and modprobe. 1.12.3 has fixes
|
||||||
for option parsing and line editing.
|
for option parsing and line editing.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
@ -69,6 +69,7 @@ s - suid type:
|
|||||||
|
|
||||||
USE_TEST(APPLET_NOFORK([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test))
|
USE_TEST(APPLET_NOFORK([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test))
|
||||||
USE_TEST(APPLET_NOFORK([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test))
|
USE_TEST(APPLET_NOFORK([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test))
|
||||||
|
USE_ACPID(APPLET(acpid, _BB_DIR_SBIN, _BB_SUID_NEVER))
|
||||||
USE_ADDGROUP(APPLET(addgroup, _BB_DIR_BIN, _BB_SUID_NEVER))
|
USE_ADDGROUP(APPLET(addgroup, _BB_DIR_BIN, _BB_SUID_NEVER))
|
||||||
USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER))
|
USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER))
|
||||||
USE_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _BB_SUID_NEVER))
|
USE_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _BB_SUID_NEVER))
|
||||||
|
@ -16,6 +16,23 @@
|
|||||||
|
|
||||||
#define NOUSAGE_STR "\b"
|
#define NOUSAGE_STR "\b"
|
||||||
|
|
||||||
|
#define acpid_trivial_usage \
|
||||||
|
"[-d] [-c CONFDIR] [-l LOGFILE] [-e PROC_EVENT_FILE] [EVDEV_EVENT_FILE...]"
|
||||||
|
|
||||||
|
#define acpid_full_usage "\n\n" \
|
||||||
|
"Listen to ACPI events and spawn specific helpers on event arrival\n" \
|
||||||
|
"\nOptions:" \
|
||||||
|
"\n -d Do not daemonize and log to stderr" \
|
||||||
|
"\n -c DIR Config directory [/etc/acpi]" \
|
||||||
|
"\n -e FILE /proc event file [/proc/acpi/event]" \
|
||||||
|
"\n -l FILE Log file [/var/log/acpid]" \
|
||||||
|
USE_FEATURE_ACPID_COMPAT( \
|
||||||
|
"\n\nAccept and ignore compatibility options -g -m -s -S -v" \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define acpid_example_usage \
|
||||||
|
"# acpid -l /var/log/my-acpi-log\n" \
|
||||||
|
"# acpid -d /dev/input/event*\n"
|
||||||
|
|
||||||
#define addgroup_trivial_usage \
|
#define addgroup_trivial_usage \
|
||||||
"[-g GID] " USE_FEATURE_ADDUSER_TO_GROUP("[user_name] ") "group_name"
|
"[-g GID] " USE_FEATURE_ADDUSER_TO_GROUP("[user_name] ") "group_name"
|
||||||
|
@ -5,6 +5,28 @@
|
|||||||
|
|
||||||
menu "Linux System Utilities"
|
menu "Linux System Utilities"
|
||||||
|
|
||||||
|
config ACPID
|
||||||
|
bool "acpid"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
acpid listens to ACPI events coming either in textual form from
|
||||||
|
/proc/acpi/event (though it is marked deprecated it is still widely
|
||||||
|
used and _is_ a standard) or in binary form from specified evdevs
|
||||||
|
(just use /dev/input/event*).
|
||||||
|
|
||||||
|
It parses the event to retrieve ACTION and a possible PARAMETER.
|
||||||
|
It then spawns /etc/acpi/<ACTION>[/<PARAMETER>] either via run-parts
|
||||||
|
(if the resulting path is a directory) or directly as an executable.
|
||||||
|
|
||||||
|
N.B. acpid relies on run-parts so have the latter installed.
|
||||||
|
|
||||||
|
config FEATURE_ACPID_COMPAT
|
||||||
|
bool "Accept and ignore redundant options"
|
||||||
|
default n
|
||||||
|
depends on ACPID
|
||||||
|
help
|
||||||
|
Accept and ignore compatibility options -g -m -s -S -v.
|
||||||
|
|
||||||
config BLKID
|
config BLKID
|
||||||
bool "blkid"
|
bool "blkid"
|
||||||
default n
|
default n
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
# Licensed under the GPL v2, see the file LICENSE in this tarball.
|
# Licensed under the GPL v2, see the file LICENSE in this tarball.
|
||||||
|
|
||||||
lib-y:=
|
lib-y:=
|
||||||
|
lib-$(CONFIG_ACPID) += acpid.o
|
||||||
lib-$(CONFIG_BLKID) += blkid.o
|
lib-$(CONFIG_BLKID) += blkid.o
|
||||||
lib-$(CONFIG_DMESG) += dmesg.o
|
lib-$(CONFIG_DMESG) += dmesg.o
|
||||||
lib-$(CONFIG_FBSET) += fbset.o
|
lib-$(CONFIG_FBSET) += fbset.o
|
||||||
|
167
util-linux/acpid.c
Normal file
167
util-linux/acpid.c
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* simple ACPI events listener
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2, see file LICENSE in this tarball for details.
|
||||||
|
*/
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#ifndef SW_RFKILL_ALL
|
||||||
|
# define SW_RFKILL_ALL 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* acpid listens to ACPI events coming either in textual form
|
||||||
|
* from /proc/acpi/event (though it is marked deprecated,
|
||||||
|
* it is still widely used and _is_ a standard) or in binary form
|
||||||
|
* from specified evdevs (just use /dev/input/event*).
|
||||||
|
* It parses the event to retrieve ACTION and a possible PARAMETER.
|
||||||
|
* It then spawns /etc/acpi/<ACTION>[/<PARAMETER>] either via run-parts
|
||||||
|
* (if the resulting path is a directory) or directly.
|
||||||
|
* If the resulting path does not exist it logs it via perror
|
||||||
|
* and continues listening.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void process_event(const char *event)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
char *handler = xasprintf("./%s", event);
|
||||||
|
const char *args[] = { "run-parts", handler, NULL };
|
||||||
|
|
||||||
|
// debug info
|
||||||
|
if (option_mask32 & 8) { // -d
|
||||||
|
bb_error_msg("%s", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawn handler
|
||||||
|
// N.B. run-parts would require scripts to have #!/bin/sh
|
||||||
|
// handler is directory? -> use run-parts
|
||||||
|
// handler is file? -> run it directly
|
||||||
|
if (0 == stat(event, &st))
|
||||||
|
spawn((char **)args + (0==(st.st_mode & S_IFDIR)));
|
||||||
|
else
|
||||||
|
bb_simple_perror_msg(event);
|
||||||
|
free(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* acpid [-c conf_dir] [-l log_file] [-e proc_event_file] [evdev_event_file...]
|
||||||
|
*/
|
||||||
|
|
||||||
|
int acpid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
|
int acpid_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct pollfd *pfd;
|
||||||
|
int i, nfd;
|
||||||
|
const char *opt_conf = "/etc/acpi";
|
||||||
|
const char *opt_input = "/proc/acpi/event";
|
||||||
|
const char *opt_logfile = "/var/log/acpid.log";
|
||||||
|
|
||||||
|
getopt32(argv, "c:e:l:d"
|
||||||
|
USE_FEATURE_ACPID_COMPAT("g:m:s:S:v"),
|
||||||
|
&opt_conf, &opt_input, &opt_logfile
|
||||||
|
USE_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL, NULL)
|
||||||
|
);
|
||||||
|
|
||||||
|
// daemonize unless -d given
|
||||||
|
if (!(option_mask32 & 8)) { // ! -d
|
||||||
|
bb_daemonize_or_rexec(0, argv);
|
||||||
|
close(2);
|
||||||
|
xopen(opt_logfile, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
// goto configuration directory
|
||||||
|
xchdir(opt_conf);
|
||||||
|
|
||||||
|
// // setup signals
|
||||||
|
// bb_signals(BB_FATAL_SIGS, record_signo);
|
||||||
|
|
||||||
|
// no explicit evdev files given? -> use proc event interface
|
||||||
|
if (!*argv) {
|
||||||
|
// proc_event file is just a "config" :)
|
||||||
|
char *token[4];
|
||||||
|
parser_t *parser = config_open(opt_input);
|
||||||
|
|
||||||
|
// dispatch events
|
||||||
|
while (config_read(parser, token, 4, 4, "\0 ", PARSE_NORMAL)) {
|
||||||
|
char *event = xasprintf("%s/%s", token[1], token[2]);
|
||||||
|
process_event(event);
|
||||||
|
free(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
|
config_close(parser);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// evdev files given, use evdev interface
|
||||||
|
|
||||||
|
// open event devices
|
||||||
|
pfd = xzalloc(sizeof(*pfd) * (argc - optind));
|
||||||
|
nfd = 0;
|
||||||
|
while (*argv) {
|
||||||
|
pfd[nfd].fd = open_or_warn(*argv++, O_RDONLY | O_NONBLOCK);
|
||||||
|
if (pfd[nfd].fd >= 0)
|
||||||
|
pfd[nfd++].events = POLLIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispatch events
|
||||||
|
while (/* !bb_got_signal && */ poll(pfd, nfd, -1) > 0) {
|
||||||
|
for (i = 0; i < nfd; i++) {
|
||||||
|
const char *event;
|
||||||
|
struct input_event ev;
|
||||||
|
|
||||||
|
if (!(pfd[i].revents & POLLIN))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sizeof(ev) != full_read(pfd[i].fd, &ev, sizeof(ev)))
|
||||||
|
continue;
|
||||||
|
//bb_info_msg("%d: %d %d %4d", i, ev.type, ev.code, ev.value);
|
||||||
|
|
||||||
|
// filter out unneeded events
|
||||||
|
if (ev.value != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
event = NULL;
|
||||||
|
|
||||||
|
// N.B. we will conform to /proc/acpi/event
|
||||||
|
// naming convention when assigning event names
|
||||||
|
|
||||||
|
// TODO: do we want other events?
|
||||||
|
|
||||||
|
// power and sleep buttons delivered as keys pressed
|
||||||
|
if (EV_KEY == ev.type) {
|
||||||
|
if (KEY_POWER == ev.code)
|
||||||
|
event = "PWRF/00000080";
|
||||||
|
else if (KEY_SLEEP == ev.code)
|
||||||
|
event = "SLPB/00000080";
|
||||||
|
}
|
||||||
|
// switches
|
||||||
|
else if (EV_SW == ev.type) {
|
||||||
|
if (SW_LID == ev.code)
|
||||||
|
event = "LID/00000080";
|
||||||
|
else if (SW_RFKILL_ALL == ev.code)
|
||||||
|
event = "RFKILL";
|
||||||
|
}
|
||||||
|
// filter out unneeded events
|
||||||
|
if (!event)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// spawn event handler
|
||||||
|
process_event(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ENABLE_FEATURE_CLEAN_UP) {
|
||||||
|
for (i = 0; i < nfd; i++)
|
||||||
|
close(pfd[i].fd);
|
||||||
|
free(pfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user