diff options
| author | Khem Raj <raj.khem@gmail.com> | 2009-10-14 15:04:39 -0700 |
|---|---|---|
| committer | Khem Raj <raj.khem@gmail.com> | 2009-10-14 15:06:01 -0700 |
| commit | 9e54aa00b3de07933fabf5f6193a4f40af3b54f9 (patch) | |
| tree | 5a3a474b492614ce6a5786bcd324e216411cc96c | |
| parent | 98f5b4a634bc24e418b23e23a51037a89566c339 (diff) | |
acpid-1.0.10: Add recipe and patches for version 1.0.10
Signed-off-by: Khem Raj <raj.khem@gmail.com>
| -rw-r--r-- | conf/checksums.ini | 4 | ||||
| -rw-r--r-- | recipes/acpid/acpid-1.0.10/event.c.diff | 43 | ||||
| -rw-r--r-- | recipes/acpid/acpid-1.0.10/gcc44.diff | 71 | ||||
| -rw-r--r-- | recipes/acpid/acpid-1.0.10/netlink.diff | 2964 | ||||
| -rw-r--r-- | recipes/acpid/acpid_1.0.10.bb | 7 |
5 files changed, 3089 insertions, 0 deletions
diff --git a/conf/checksums.ini b/conf/checksums.ini index e8a5c8158b..6739d61760 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -1390,6 +1390,10 @@ sha256=bda8a3c42733853444e1d4bee16e85990b78c2eaafc4b26e0769be2e14dab931 md5=9703f591801c5bbded35c9739d04f81c sha256=68b1d0acd1a6e17d91412635cd4f65ba58d293e62a01475a43f3712c49a46e7d +[http://downloads.sourceforge.net/acpid/acpid-1.0.10.tar.gz] +md5=61156ef32015c56dc0f2e3317f4ae09e +sha256=22703ce0dd7305aca01bc9ac741659c32b1593f1d6fde492df7f01067a534760 + [http://downloads.sourceforge.net/acpid/acpid-1.0.2.tar.gz] md5=15884aaf0b82717954f9366b5c00808b sha256=7347042a5328b22965256d98462e8dd8f1cad37de992b135912f32c70163ae71 diff --git a/recipes/acpid/acpid-1.0.10/event.c.diff b/recipes/acpid/acpid-1.0.10/event.c.diff new file mode 100644 index 0000000000..ef616a7eb1 --- /dev/null +++ b/recipes/acpid/acpid-1.0.10/event.c.diff @@ -0,0 +1,43 @@ +--- acpid-1.0.8.orig/event.c ++++ acpid-1.0.8/event.c +@@ -23,6 +23,7 @@ + #include <sys/types.h> + #include <sys/stat.h> + #include <sys/wait.h> ++#include <libgen.h> + #include <sys/poll.h> + #include <fcntl.h> + #include <unistd.h> +@@ -92,6 +93,8 @@ + struct dirent *dirent; + char *file = NULL; + int nrules = 0; ++ char *basen = NULL; ++ regex_t preg; + + lock_rules(); + +@@ -141,10 +144,19 @@ + continue; /* skip non-regular files */ + } + +- r = parse_file(file); +- if (r) { +- enlist_rule(&cmd_list, r); +- nrules++; ++ /* check for run-parts style filename */ ++ basen = basename(file); ++ if (regcomp(&preg, "^[a-zA-Z0-9_-]+$", RULE_REGEX_FLAGS) == 0){ ++ if (regexec(&preg, basen, 0, NULL, 0) == 0){ ++ r = parse_file(file); ++ if (r) { ++ enlist_rule(&cmd_list, r); ++ nrules++; ++ } ++ } else { ++ acpid_log(LOG_DEBUG, "ignoring conf file %s\n", file); ++ } ++ + } + free(file); + } diff --git a/recipes/acpid/acpid-1.0.10/gcc44.diff b/recipes/acpid/acpid-1.0.10/gcc44.diff new file mode 100644 index 0000000000..66b8e9beaa --- /dev/null +++ b/recipes/acpid/acpid-1.0.10/gcc44.diff @@ -0,0 +1,71 @@ +--- acpid-1.0.10/acpi_ids.c.orig 2009-05-04 14:39:40.000000000 +0200 ++++ acpid-1.0.10/acpi_ids.c 2009-05-04 15:28:49.000000000 +0200 +@@ -91,13 +91,15 @@ + * routing. + */ + struct rtattr *tb[CTRL_ATTR_MAX + 1]; +- /* pointer to the generic netlink header in the incoming message */ +- struct genlmsghdr *ghdr = NLMSG_DATA(n); ++ /* place for the generic netlink header in the incoming message */ ++ struct genlmsghdr ghdr; + /* length of the attribute and payload */ + int len = n->nlmsg_len - NLMSG_LENGTH(GENL_HDRLEN); + /* Pointer to the attribute portion of the message */ + struct rtattr *attrs; + ++ /* copy generic netlink header into structure */ ++ memcpy(&ghdr, NLMSG_DATA(n), GENL_HDRLEN); + if (len < 0) { + fprintf(stderr, "%s: netlink CTRL_CMD_GETFAMILY response, " + "wrong controller message len: %d\n", progname, len); +@@ -111,18 +113,18 @@ + return 0; + } + +- if (ghdr->cmd != CTRL_CMD_GETFAMILY && +- ghdr->cmd != CTRL_CMD_DELFAMILY && +- ghdr->cmd != CTRL_CMD_NEWFAMILY && +- ghdr->cmd != CTRL_CMD_NEWMCAST_GRP && +- ghdr->cmd != CTRL_CMD_DELMCAST_GRP) { ++ if (ghdr.cmd != CTRL_CMD_GETFAMILY && ++ ghdr.cmd != CTRL_CMD_DELFAMILY && ++ ghdr.cmd != CTRL_CMD_NEWFAMILY && ++ ghdr.cmd != CTRL_CMD_NEWMCAST_GRP && ++ ghdr.cmd != CTRL_CMD_DELMCAST_GRP) { + fprintf(stderr, "%s: unknown netlink controller command %d\n", +- progname, ghdr->cmd); ++ progname, ghdr.cmd); + return 0; + } + + /* set attrs to point to the attribute */ +- attrs = (struct rtattr *)((char *)ghdr + GENL_HDRLEN); ++ attrs = (struct rtattr *)(NLMSG_DATA(n) + GENL_HDRLEN); + /* Read the table from the message into "tb". This actually just */ + /* places pointers into the message into tb[]. */ + parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len); +@@ -167,8 +169,8 @@ + } req; + /* pointer to the nlmsghdr in req */ + struct nlmsghdr *nlh; +- /* pointer to the generic netlink header in req */ +- struct genlmsghdr *ghdr; ++ /* place for the generic netlink header before copied into req */ ++ struct genlmsghdr ghdr; + /* return value */ + int ret = -1; + +@@ -182,10 +184,10 @@ + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + nlh->nlmsg_type = GENL_ID_CTRL; + +- /* set up ghdr to point to the generic netlink header */ +- ghdr = NLMSG_DATA(&req.n); + /* set the command we want to run: "GETFAMILY" */ +- ghdr->cmd = CTRL_CMD_GETFAMILY; ++ ghdr.cmd = CTRL_CMD_GETFAMILY; ++ /* copy it into req */ ++ memcpy(NLMSG_DATA(&req.n), &ghdr, GENL_HDRLEN); + + /* the message payload is the family name */ + addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, diff --git a/recipes/acpid/acpid-1.0.10/netlink.diff b/recipes/acpid/acpid-1.0.10/netlink.diff new file mode 100644 index 0000000000..635c550853 --- /dev/null +++ b/recipes/acpid/acpid-1.0.10/netlink.diff @@ -0,0 +1,2964 @@ +Binärdateien acpid-1.0.10/acpid and acpid-1.0.10-netlink2/acpid sind verschieden. +diff -ruN acpid-1.0.10/acpid.8 acpid-1.0.10-netlink2/acpid.8 +--- acpid-1.0.10/acpid.8 2009-04-28 09:23:21.000000000 +0200 ++++ acpid-1.0.10-netlink2/acpid.8 2009-04-29 16:37:13.000000000 +0200 +@@ -10,11 +10,13 @@ + \fBacpid\fP is designed to notify user-space programs of ACPI events. + \fBacpid\fP should be started during the system boot, and will run as a + background process, by default. It will open an events file +-(\fI/proc/acpi/event\fP by default) and attempt to read whole lines. When +-a line is received (an \fIevent\fP), \fBacpid\fP will examine a list of rules, +-and execute the rules that match the event. +-\fBacpid\fP will ignore all incoming ACPI events if a lock file exists +-(\fI/var/lock/acpid\fP by default). ++(\fI/proc/acpi/event\fP by default) and attempt to read whole lines which ++represent ACPI events. If the events file does not exist, \fBacpid\fP will ++attempt to connect to the Linux kernel via the input layer and netlink. When an ++ACPI event is received from one of these sources, \fBacpid\fP will examine a ++list of rules, and execute the rules that match the event. \fBacpid\fP will ++ignore all incoming ACPI events if a lock file exists (\fI/var/lock/acpid\fP by ++default). + .PP + \fIRules\fP are defined by simple configuration files. \fBacpid\fP + will look in a configuration directory (\fI/etc/acpi/events\fP by default), +@@ -73,6 +75,9 @@ + This option changes the event file from which \fBacpid\fP reads events. + Default is \fI/proc/acpi/event\fP. + .TP ++.BI \-n "\fR, \fP" \--netlink ++This option forces \fBacpid\fP to use the Linux kernel input layer and netlink interface for ACPI events. ++.TP + .BI \-f "\fR, \fP" \--foreground + This option keeps \fBacpid\fP in the foreground by not forking at startup. + .TP +@@ -126,6 +131,8 @@ + .PD 0 + .B /proc/acpi/event + .br ++.B /dev/input/event* ++.br + .B /etc/acpi/ + .br + .B /var/run/acpid.socket +diff -ruN acpid-1.0.10/acpid.c acpid-1.0.10-netlink2/acpid.c +--- acpid-1.0.10/acpid.c 2009-04-28 09:23:21.000000000 +0200 ++++ acpid-1.0.10-netlink2/acpid.c 2009-05-02 04:22:00.000000000 +0200 +@@ -20,23 +20,23 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +-#include <sys/types.h> +-#include <sys/stat.h> ++#include <unistd.h> + #include <fcntl.h> + #include <signal.h> +-#include <unistd.h> ++#include <string.h> + #include <stdio.h> + #include <stdlib.h> +-#include <string.h> + #include <errno.h> + #include <getopt.h> +-#include <time.h> +-#include <sys/poll.h> +-#include <grp.h> +-#include <syslog.h> ++#include <stdarg.h> + + #include "acpid.h" +-#include "ud_socket.h" ++#include "event.h" ++#include "connection_list.h" ++#include "proc.h" ++#include "sock.h" ++#include "input_layer.h" ++#include "netlink.h" + + static int handle_cmdline(int *argc, char ***argv); + static void close_fds(void); +@@ -44,9 +44,7 @@ + static int open_log(void); + static int create_pidfile(void); + static void clean_exit(int sig); +-static void clean_exit_with_status(int status); + static void reload_conf(int sig); +-static char *read_line(int fd); + + /* global debug level */ + int acpid_debug; +@@ -54,27 +52,17 @@ + /* do we log event info? */ + int logevents; + +-/* the number of non-root clients that are connected */ +-int non_root_clients; +- +-static const char *progname; ++const char *progname; + static const char *confdir = ACPID_CONFDIR; +-static const char *eventfile = ACPID_EVENTFILE; +-static const char *socketfile = ACPID_SOCKETFILE; + static const char *lockfile = ACPID_LOCKFILE; + static int nosocket; +-static const char *socketgroup; +-static mode_t socketmode = ACPID_SOCKETMODE; + static int foreground; + static const char *pidfile = ACPID_PIDFILE; +-static int clientmax = ACPID_CLIENTMAX; ++static int netlink; + + int + main(int argc, char **argv) + { +- int event_fd; +- int sock_fd = -1; /* init to avoid a compiler warning */ +- + /* learn who we really are */ + progname = (const char *)strrchr(argv[0], '/'); + progname = progname ? (progname + 1) : argv[0]; +@@ -85,14 +73,22 @@ + /* close any extra file descriptors */ + close_fds(); + +- /* actually open the event file */ +- event_fd = open(eventfile, O_RDONLY); +- if (event_fd < 0) { +- fprintf(stderr, "%s: can't open %s: %s\n", progname, +- eventfile, strerror(errno)); +- exit(EXIT_FAILURE); ++ if (!netlink) ++ { ++ /* open the acpi event file in the proc fs */ ++ /* if the open fails, try netlink */ ++ if (open_proc()) ++ netlink = 1; ++ } ++ ++ if (netlink) ++ { ++ /* open the input layer */ ++ open_input(); ++ ++ /* open netlink */ ++ open_netlink(); + } +- fcntl(event_fd, F_SETFD, FD_CLOEXEC); + + /* + * if there is data, and the kernel is NOT broken, this eats 1 byte. We +@@ -129,34 +125,7 @@ + + /* open our socket */ + if (!nosocket) { +- sock_fd = ud_create_socket(socketfile); +- if (sock_fd < 0) { +- fprintf(stderr, "%s: can't open socket %s: %s\n", +- progname, socketfile, strerror(errno)); +- exit(EXIT_FAILURE); +- } +- fcntl(sock_fd, F_SETFD, FD_CLOEXEC); +- chmod(socketfile, socketmode); +- if (socketgroup) { +- struct group *gr; +- struct stat buf; +- gr = getgrnam(socketgroup); +- if (!gr) { +- fprintf(stderr, "%s: group %s does not exist\n", +- progname, socketgroup); +- exit(EXIT_FAILURE); +- } +- if (stat(socketfile, &buf) < 0) { +- fprintf(stderr, "%s: can't stat %s\n", +- progname, socketfile); +- exit(EXIT_FAILURE); +- } +- if (chown(socketfile, buf.st_uid, gr->gr_gid) < 0) { +- fprintf(stderr, "%s: chown(): %s\n", +- progname, strerror(errno)); +- exit(EXIT_FAILURE); +- } +- } ++ open_sock(); + } + + /* if we're running in foreground, we don't daemonize */ +@@ -169,7 +138,8 @@ + if (open_log() < 0) { + exit(EXIT_FAILURE); + } +- acpid_log(LOG_INFO, "starting up\n"); ++ acpid_log(LOG_INFO, "starting up with %s\n", ++ netlink ? "netlink and the input layer" : "proc fs"); + + /* trap key signals */ + signal(SIGHUP, reload_conf); +@@ -188,128 +158,53 @@ + exit(EXIT_FAILURE); + } + +- /* main loop */ + acpid_log(LOG_INFO, "waiting for events: event logging is %s\n", + logevents ? "on" : "off"); +- while (1) { +- struct pollfd ar[2]; +- int r; +- int fds = 0; +- +- /* poll for the socket and the event file */ +- ar[0].fd = event_fd; ar[0].events = POLLIN; fds++; +- if (!nosocket) { +- ar[1].fd = sock_fd; ar[1].events = POLLIN; fds++; +- } +- r = poll(ar, fds, -1); + +- if (r < 0 && errno == EINTR) { ++ /* main loop */ ++ while (1) ++ { ++ fd_set readfds; ++ int nready; ++ int i; ++ struct connection *p; ++ ++ /* it's going to get clobbered, so use a copy */ ++ readfds = *get_fdset(); ++ ++ /* wait on data */ ++ nready = select(get_highestfd() + 1, &readfds, NULL, NULL, NULL); ++ ++ if (nready < 0 && errno == EINTR) { + continue; +- } else if (r < 0) { +- acpid_log(LOG_ERR, "poll(): %s\n", strerror(errno)); ++ } else if (nready < 0) { ++ acpid_log(LOG_ERR, "select(): %s\n", strerror(errno)); + continue; + } + + /* house keeping */ + acpid_close_dead_clients(); + +- /* was it an event? */ +- if (ar[0].revents) { +- char *event; +- struct stat trash; +- int fexists; +- +- /* check for existence of a lockfile */ +- fexists = (stat(lockfile, &trash) == 0); +- +- /* this shouldn't happen */ +- if (!ar[0].revents & POLLIN) { +- acpid_log(LOG_DEBUG, +- "odd, poll set flags 0x%x\n", +- ar[0].revents); +- continue; +- } +- +- /* read an event */ +- event = read_line(event_fd); ++ /* for each connection */ ++ for (i = 0; i <= get_number_of_connections(); ++i) ++ { ++ int fd; + +- /* if we're locked, don't process the event */ +- if (fexists) { +- if (logevents) { +- acpid_log(LOG_INFO, +- "lockfile present, not processing " +- "event \"%s\"\n", event); +- } +- continue; +- } ++ p = get_connection(i); + +- /* handle the event */ +- if (event) { +- if (logevents) { +- acpid_log(LOG_INFO, +- "received event \"%s\"\n", event); +- } +- acpid_handle_event(event); +- if (logevents) { +- acpid_log(LOG_INFO, +- "completed event \"%s\"\n", event); +- } +- } else if (errno == EPIPE) { +- acpid_log(LOG_WARNING, +- "events file connection closed\n"); ++ /* if this connection is invalid, bail */ ++ if (!p) + break; +- } else { +- static int nerrs; +- if (++nerrs >= ACPID_MAX_ERRS) { +- acpid_log(LOG_ERR, +- "too many errors reading " +- "events file - aborting\n"); +- break; +- } +- } +- } + +- /* was it a new connection? */ +- if (!nosocket && ar[1].revents) { +- int cli_fd; +- struct ucred creds; +- char buf[32]; +- static int accept_errors; +- +- /* this shouldn't happen */ +- if (!ar[1].revents & POLLIN) { +- acpid_log(LOG_DEBUG, +- "odd, poll set flags 0x%x\n", +- ar[1].revents); +- continue; +- } ++ /* get the file descriptor */ ++ fd = p->fd; + +- /* accept and add to our lists */ +- cli_fd = ud_accept(sock_fd, &creds); +- if (cli_fd < 0) { +- acpid_log(LOG_ERR, "can't accept client: %s\n", +- strerror(errno)); +- accept_errors++; +- if (accept_errors >= 5) { +- acpid_log(LOG_ERR, "giving up\n"); +- clean_exit_with_status(EXIT_FAILURE); +- } +- continue; +- } +- accept_errors = 0; +- if (creds.uid != 0 && non_root_clients >= clientmax) { +- close(cli_fd); +- acpid_log(LOG_ERR, +- "too many non-root clients\n"); +- continue; +- } +- if (creds.uid != 0) { +- non_root_clients++; ++ /* if this file descriptor has data waiting */ ++ if (FD_ISSET(fd, &readfds)) ++ { ++ /* delegate to this connection's process function */ ++ p->process(fd); + } +- fcntl(cli_fd, F_SETFD, FD_CLOEXEC); +- snprintf(buf, sizeof(buf)-1, "%d[%d:%d]", +- creds.pid, creds.uid, creds.gid); +- acpid_add_client(cli_fd, buf); + } + } + +@@ -337,6 +232,7 @@ + {"nosocket", 1, 0, 'S'}, + {"pidfile", 1, 0, 'p'}, + {"lockfile", 1, 0, 'L'}, ++ {"netlink", 0, 0, 'n'}, + {"version", 0, 0, 'v'}, + {"help", 0, 0, 'h'}, + {NULL, 0, 0, 0}, +@@ -353,7 +249,8 @@ + "Use the specified socket file.", /* socketfile */ + "Do not listen on a UNIX socket (overrides -s).",/* nosocket */ + "Use the specified PID file.", /* pidfile */ +- "Use the specified lockfile to stop processing.", /* pidfile */ ++ "Use the specified lockfile to stop processing.", /* lockfile */ ++ "Force netlink/input layer mode. (overrides -e)", /* netlink */ + "Print version information.", /* version */ + "Print this message.", /* help */ + }; +@@ -364,7 +261,7 @@ + for (;;) { + int i; + i = getopt_long(*argc, *argv, +- "c:C:de:flg:m:s:Sp:L:vh", opts, NULL); ++ "c:C:de:flg:m:s:Sp:L:nvh", opts, NULL); + if (i == -1) { + break; + } +@@ -406,6 +303,9 @@ + case 'L': + lockfile = optarg; + break; ++ case 'n': ++ netlink = 1; ++ break; + case 'v': + printf(PACKAGE "-" VERSION "\n"); + exit(EXIT_SUCCESS); +@@ -547,7 +447,7 @@ + return -1; + } + +-static void ++void + clean_exit_with_status(int status) + { + acpid_cleanup_rules(1); +@@ -585,54 +485,11 @@ + return 0; + } + +-/* +- * This depends on fixes in linux ACPI after 2.4.8 +- */ +-#define MAX_BUFLEN 1024 +-static char * +-read_line(int fd) +-{ +- static char *buf; +- int buflen = 64; +- int i = 0; +- int r; +- int searching = 1; +- +- while (searching) { +- buf = realloc(buf, buflen); +- if (!buf) { +- acpid_log(LOG_ERR, "malloc(%d): %s\n", +- buflen, strerror(errno)); +- return NULL; +- } +- memset(buf+i, 0, buflen-i); +- +- while (i < buflen) { +- r = read(fd, buf+i, 1); +- if (r < 0 && errno != EINTR) { +- /* we should do something with the data */ +- acpid_log(LOG_ERR, "read(): %s\n", +- strerror(errno)); +- return NULL; +- } else if (r == 0) { +- /* signal this in an almost standard way */ +- errno = EPIPE; +- return NULL; +- } else if (r == 1) { +- /* scan for a newline */ +- if (buf[i] == '\n') { +- searching = 0; +- buf[i] = '\0'; +- break; +- } +- i++; +- } +- } +- if (buflen >= MAX_BUFLEN) { +- break; +- } +- buflen *= 2; +- } ++int ++locked() ++{ ++ struct stat trash; + +- return buf; ++ /* check for existence of a lockfile */ ++ return (stat(lockfile, &trash) == 0); + } +diff -ruN acpid-1.0.10/acpid.h acpid-1.0.10-netlink2/acpid.h +--- acpid-1.0.10/acpid.h 2009-04-28 09:23:21.000000000 +0200 ++++ acpid-1.0.10-netlink2/acpid.h 2009-05-02 04:19:54.000000000 +0200 +@@ -23,11 +23,7 @@ + #ifndef ACPID_H__ + #define ACPID_H__ + +-#include <unistd.h> + #include <syslog.h> +-#include <stdarg.h> +-#include <sys/types.h> +-#include <sys/stat.h> + + #define ACPI_PROCDIR "/proc/acpi" + #define ACPID_EVENTFILE ACPI_PROCDIR "/event" +@@ -46,16 +42,12 @@ + */ + extern int acpid_debug; + extern int logevents; +-extern int non_root_clients; ++extern const char *progname; ++ + extern int acpid_log(int level, const char *fmt, ...); + +-/* +- * event.c +- */ +-extern int acpid_read_conf(const char *confdir); +-extern int acpid_add_client(int client, const char *origin); +-extern int acpid_cleanup_rules(int do_detach); +-extern int acpid_handle_event(const char *event); +-extern void acpid_close_dead_clients(void); ++extern int locked(); ++ ++extern void clean_exit_with_status(int status); + + #endif /* ACPID_H__ */ +diff -ruN acpid-1.0.10/acpi_genetlink.h acpid-1.0.10-netlink2/acpi_genetlink.h +--- acpid-1.0.10/acpi_genetlink.h 1970-01-01 01:00:00.000000000 +0100 ++++ acpid-1.0.10-netlink2/acpi_genetlink.h 2009-04-29 16:37:13.000000000 +0200 +@@ -0,0 +1,33 @@ ++#ifndef __ACPI_GENETLINK_H__ ++#define __ACPI_GENETLINK_H__ 1 ++ ++#include <linux/types.h> ++ ++struct acpi_genl_event { ++ char device_class[20]; ++ char bus_id[15]; ++ __u32 type; ++ __u32 data; ++}; ++ ++/* attributes of acpi_genl_family */ ++enum { ++ ACPI_GENL_ATTR_UNSPEC, ++ ACPI_GENL_ATTR_EVENT, /* ACPI event info needed by user space */ ++ __ACPI_GENL_ATTR_MAX, ++}; ++#define ACPI_GENL_ATTR_MAX (__ACPI_GENL_ATTR_MAX - 1) ++ ++/* commands supported by the acpi_genl_family */ ++enum { ++ ACPI_GENL_CMD_UNSPEC, ++ ACPI_GENL_CMD_EVENT, /* kernel->user notifications for ACPI events */ __ACPI_GENL_CMD_MAX, ++}; ++#define ACPI_GENL_CMD_MAX (__ACPI_GENL_CMD_MAX - 1) ++#define GENL_MAX_FAM_OPS 256 ++#define GENL_MAX_FAM_GRPS 256 ++ ++#define ACPI_EVENT_FAMILY_NAME "acpi_event" ++#define ACPI_EVENT_MCAST_GROUP_NAME "acpi_mc_group" ++ ++#endif +diff -ruN acpid-1.0.10/acpi_ids.c acpid-1.0.10-netlink2/acpi_ids.c +--- acpid-1.0.10/acpi_ids.c 1970-01-01 01:00:00.000000000 +0100 ++++ acpid-1.0.10-netlink2/acpi_ids.c 2009-04-29 16:37:13.000000000 +0200 +@@ -0,0 +1,254 @@ ++/* ++ * acpi_ids.c - ACPI Netlink Group and Family IDs ++ * ++ * Copyright (C) 2008 Ted Felix (www.tedfelix.com) ++ * Portions from acpi_genl Copyright (C) Zhang Rui <rui.zhang@intel.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include <stdio.h> ++/* needed by netlink.h, should be in there */ ++#include <arpa/inet.h> ++#include <linux/types.h> ++#include <string.h> ++ ++#include "genetlink.h" ++#include "libnetlink.h" ++ ++#include "acpid.h" ++ ++#define GENL_MAX_FAM_GRPS 256 ++#define ACPI_EVENT_FAMILY_NAME "acpi_event" ++#define ACPI_EVENT_MCAST_GROUP_NAME "acpi_mc_group" ++ ++static int initialized = 0; ++static __u16 acpi_event_family_id = 0; ++static __u32 acpi_event_mcast_group_id = 0; ++ ++/* ++ * A CTRL_CMD_GETFAMILY message returns an attribute table that looks ++ * like this: ++ * ++ * CTRL_ATTR_FAMILY_ID Use this to make sure we get the proper msgs ++ * CTRL_ATTR_MCAST_GROUPS ++ * CTRL_ATTR_MCAST_GRP_NAME ++ * CTRL_ATTR_MCAST_GRP_ID Need this for the group mask ++ * ... ++ */ ++ ++static int ++get_ctrl_grp_id(struct rtattr *arg) ++{ ++ struct rtattr *tb[CTRL_ATTR_MCAST_GRP_MAX + 1]; ++ char *name; ++ ++ if (arg == NULL) ++ return -1; ++ ++ /* nested within the CTRL_ATTR_MCAST_GROUPS attribute are the */ ++ /* group name and ID */ ++ parse_rtattr_nested(tb, CTRL_ATTR_MCAST_GRP_MAX, arg); ++ ++ /* if either of the entries needed cannot be found, bail */ ++ if (!tb[CTRL_ATTR_MCAST_GRP_NAME] || !tb[CTRL_ATTR_MCAST_GRP_ID]) ++ return -1; ++ ++ /* get the name of this multicast group we've found */ ++ name = RTA_DATA(tb[CTRL_ATTR_MCAST_GRP_NAME]); ++ ++ /* if it does not match the ACPI event multicast group name, bail */ ++ if (strcmp(name, ACPI_EVENT_MCAST_GROUP_NAME)) ++ return -1; ++ ++ /* At this point, we've found what we were looking for. We now */ ++ /* have the multicast group ID for ACPI events over generic netlink. */ ++ acpi_event_mcast_group_id = ++ *((__u32 *)RTA_DATA(tb[CTRL_ATTR_MCAST_GRP_ID])); ++ ++ return 0; ++} ++ ++/* n = the response to a CTRL_CMD_GETFAMILY message */ ++static int ++genl_get_mcast_group_id(struct nlmsghdr *n) ++{ ++ /* ++ * Attribute table. Note the type name "rtattr" which means "route ++ * attribute". This is a vestige of one of netlink's main uses: ++ * routing. ++ */ ++ struct rtattr *tb[CTRL_ATTR_MAX + 1]; ++ /* pointer to the generic netlink header in the incoming message */ ++ struct genlmsghdr *ghdr = NLMSG_DATA(n); ++ /* length of the attribute and payload */ ++ int len = n->nlmsg_len - NLMSG_LENGTH(GENL_HDRLEN); ++ /* Pointer to the attribute portion of the message */ ++ struct rtattr *attrs; ++ ++ if (len < 0) { ++ fprintf(stderr, "%s: netlink CTRL_CMD_GETFAMILY response, " ++ "wrong controller message len: %d\n", progname, len); ++ return -1; ++ } ++ ++ if (n->nlmsg_type != GENL_ID_CTRL) { ++ fprintf(stderr, "%s: not a netlink controller message, " ++ "nlmsg_len=%d nlmsg_type=0x%x\n", ++ progname, n->nlmsg_len, n->nlmsg_type); ++ return 0; ++ } ++ ++ if (ghdr->cmd != CTRL_CMD_GETFAMILY && ++ ghdr->cmd != CTRL_CMD_DELFAMILY && ++ ghdr->cmd != CTRL_CMD_NEWFAMILY && ++ ghdr->cmd != CTRL_CMD_NEWMCAST_GRP && ++ ghdr->cmd != CTRL_CMD_DELMCAST_GRP) { ++ fprintf(stderr, "%s: unknown netlink controller command %d\n", ++ progname, ghdr->cmd); ++ return 0; ++ } ++ ++ /* set attrs to point to the attribute */ ++ attrs = (struct rtattr *)((char *)ghdr + GENL_HDRLEN); ++ /* Read the table from the message into "tb". This actually just */ ++ /* places pointers into the message into tb[]. */ ++ parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len); ++ ++ /* if a family ID attribute is present, get it */ ++ if (tb[CTRL_ATTR_FAMILY_ID]) ++ { ++ acpi_event_family_id = ++ *((__u32 *)RTA_DATA(tb[CTRL_ATTR_FAMILY_ID])); ++ } ++ ++ /* if a "multicast groups" attribute is present... */ ++ if (tb[CTRL_ATTR_MCAST_GROUPS]) { ++ struct rtattr *tb2[GENL_MAX_FAM_GRPS + 1]; ++ int i; ++ ++ /* get the group table within this attribute */ ++ parse_rtattr_nested(tb2, GENL_MAX_FAM_GRPS, ++ tb[CTRL_ATTR_MCAST_GROUPS]); ++ ++ /* for each group */ ++ for (i = 0; i < GENL_MAX_FAM_GRPS; i++) ++ /* if this group is valid */ ++ if (tb2[i]) ++ /* Parse the ID. If successful, we're done. */ ++ if (!get_ctrl_grp_id(tb2[i])) ++ return 0; ++ } ++ ++ return -1; ++} ++ ++static int ++genl_get_ids(char *family_name) ++{ ++ /* handle to the netlink connection */ ++ struct rtnl_handle rth; ++ /* holds the request we are going to send and the reply */ ++ struct { ++ struct nlmsghdr n; ++ char buf[4096]; /* ??? Is this big enough for all cases? */ ++ } req; ++ /* pointer to the nlmsghdr in req */ ++ struct nlmsghdr *nlh; ++ /* pointer to the generic netlink header in req */ ++ struct genlmsghdr *ghdr; ++ /* return value */ ++ int ret = -1; ++ ++ /* clear out the request */ ++ memset(&req, 0, sizeof(req)); ++ ++ /* set up nlh to point to the netlink header in req */ ++ nlh = &req.n; ++ /* set up the netlink header */ ++ nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); ++ nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; ++ nlh->nlmsg_type = GENL_ID_CTRL; ++ ++ /* set up ghdr to point to the generic netlink header */ ++ ghdr = NLMSG_DATA(&req.n); ++ /* set the command we want to run: "GETFAMILY" */ ++ ghdr->cmd = CTRL_CMD_GETFAMILY; ++ ++ /* the message payload is the family name */ ++ addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, ++ family_name, strlen(family_name) + 1); ++ ++ /* open a generic netlink connection */ ++ if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) { ++ fprintf(stderr, "%s: cannot open generic netlink socket\n", ++ progname); ++ return -1; ++ } ++ ++ /* ++ * Send CTRL_CMD_GETFAMILY message (in nlh) to the generic ++ * netlink controller. Reply will be in nlh upon return. ++ */ ++ if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL) < 0) { ++ fprintf(stderr, "%s: error talking to the kernel via netlink\n", ++ progname); ++ goto ctrl_done; ++ } ++ ++ /* process the response */ ++ if (genl_get_mcast_group_id(nlh) < 0) { ++ fprintf(stderr, "%s: failed to get acpi_event netlink " ++ "multicast group\n", progname); ++ goto ctrl_done; ++ } ++ ++ ret = 0; ++ ++ctrl_done: ++ rtnl_close(&rth); ++ return ret; ++} ++ ++/* initialize the ACPI IDs */ ++static void ++acpi_ids_init() ++{ ++ genl_get_ids(ACPI_EVENT_FAMILY_NAME); ++ ++ initialized = 1; ++} ++ ++/* returns the netlink family ID for ACPI event messages */ ++__u16 ++acpi_ids_getfamily() ++{ ++ /* if the IDs haven't been initialized, initialize them */ ++ if (initialized == 0) ++ acpi_ids_init(); ++ ++ return acpi_event_family_id; ++} ++ ++/* returns the netlink multicast group ID for ACPI event messages */ ++__u32 ++acpi_ids_getgroup() ++{ ++ /* if the IDs haven't been initialized, initialize them */ ++ if (initialized == 0) ++ acpi_ids_init(); ++ ++ return acpi_event_mcast_group_id; ++} +diff -ruN acpid-1.0.10/acpi_ids.h acpid-1.0.10-netlink2/acpi_ids.h +--- acpid-1.0.10/acpi_ids.h 1970-01-01 01:00:00.000000000 +0100 ++++ acpid-1.0.10-netlink2/acpi_ids.h 2009-04-29 16:37:13.000000000 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * acpi_ids.h - ACPI Netlink Group and Family IDs ++ * ++ * Copyright (C) 2008 Ted Felix (www.tedfelix.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef ACPI_IDS_H__ ++#define ACPI_IDS_H__ ++ ++/* returns the netlink family ID for ACPI event messages */ ++extern __u16 acpi_ids_getfamily(); ++ ++/* returns the netlink multicast group ID for ACPI event messages */ ++extern __u32 acpi_ids_getgroup(); ++ ++#endif /* ACPI_IDS_H__ */ +Binärdateien acpid-1.0.10/acpi_listen and acpid-1.0.10-netlink2/acpi_listen sind verschieden. +diff -ruN acpid-1.0.10/acpi_listen.c acpid-1.0.10-netlink2/acpi_listen.c +--- acpid-1.0.10/acpi_listen.c 2009-04-28 09:23:21.000000000 +0200 ++++ acpid-1.0.10-netlink2/acpi_listen.c 2009-04-29 16:37:13.000000000 +0200 +@@ -42,8 +42,8 @@ + static int handle_cmdline(int *argc, char ***argv); + static char *read_line(int fd); + +-static const char *progname; +-static const char *socketfile = ACPID_SOCKETFILE; ++const char *progname; ++const char *socketfile = ACPID_SOCKETFILE; + static int max_events; + + static void +diff -ruN acpid-1.0.10/Changelog acpid-1.0.10-netlink2/Changelog +--- acpid-1.0.10/Changelog 2009-04-28 09:23:21.000000000 +0200 ++++ acpid-1.0.10-netlink2/Changelog 2009-05-03 02:02:33.000000000 +0200 +@@ -1,4 +1,7 @@ + %changelog ++* Sat May 02 2009 Michael Meskes and Ted Felix <http://www.tedfelix.com/> ++ - Merge of the following three 1.0.10 changes into 1.0.10-netlink2 ++ + * Wed Apr 22 2009 Tim Hockin <thockin@hockin.org> + - Bump version to 1.0.10 for release. + +@@ -13,6 +16,11 @@ + * Mon Feb 09 2009 Tim Hockin <thockin@hockin.org> + - Open /dev/null O_RDWR, rather than O_RDONLY. (acpid.c) + ++* Thu Dec 11 2008 Ted Felix <http://www.tedfelix.com/> ++ - Version 1.0.8ted1 ++ - Netlink and Input Layer support. Many files have been changed and ++ several have been added. (Ted Felix <http://www.tedfelix.com/>) ++ + * Tue Oct 28 2008 Tim Hockin <thockin@hockin.org> + - Bump version to 1.0.8 for release. + +diff -ruN acpid-1.0.10/connection_list.c acpid-1.0.10-netlink2/connection_list.c +--- acpid-1.0.10/connection_list.c 1970-01-01 01:00:00.000000000 +0100 ++++ acpid-1.0.10-netlink2/connection_list.c 2009-04-29 16:37:13.000000000 +0200 +@@ -0,0 +1,124 @@ ++/* ++ * connection_list.c - ACPI daemon connection list ++ * ++ * Copyright (C) 2008, Ted Felix (www.tedfelix.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Tabs at 4 ++ */ ++ ++#include <unistd.h> ++#include <stdio.h> ++#include <sys/select.h> ++ ++#include "acpid.h" ++ ++#include "connection_list.h" ++ ++#define max(a, b) (((a)>(b))?(a):(b)) ++ ++/*---------------------------------------------------------------*/ ++/* private objects */ ++ ++#define MAX_CONNECTIONS 10 ++ ++static struct connection connection_list[MAX_CONNECTIONS]; ++ ++static int nconnections = 0; ++ ++/* fd_set containing all the fd's that come in */ ++static fd_set allfds; ++ ++/* highest fd that is opened */ ++/* (-2 + 1) causes select() to return immediately */ ++static int highestfd = -2; ++ ++/*---------------------------------------------------------------*/ ++/* public functions */ ++ ++void ++add_connection(struct connection *p) ++{ ++ if (nconnections < 0) ++ return; ++ if (nconnections >= MAX_CONNECTIONS) { ++ acpid_log(LOG_ERR, "Too many connections.\n"); ++ return; ++ } ++ ++ if (nconnections == 0) ++ FD_ZERO(&allfds); ++ ++ /* add the connection to the connection list */ ++ connection_list[nconnections] = *p; ++ ++nconnections; ++ ++ /* add to the fd set */ ++ FD_SET |
