summaryrefslogtreecommitdiff
path: root/recipes
diff options
context:
space:
mode:
authorKoen Kooi <koen@openembedded.org>2009-05-21 15:02:42 +0200
committerKoen Kooi <koen@openembedded.org>2009-05-21 15:02:42 +0200
commitccab93e06e6b3fc9a58a000fce97270d99911780 (patch)
tree545cf8b2e2d6a23df9f47aa4128d5baef75b61a0 /recipes
parentd543c80be652f118cbbfa94250bd2aca9bb9aea4 (diff)
parenteca20211da63073e3a35dd1f647ef534662c4771 (diff)
Merge branch 'org.openembedded.dev' of git@git.openembedded.org:openembedded into org.openembedded.dev
Diffstat (limited to 'recipes')
-rw-r--r--recipes/acpid/acpid/event.c.diff43
-rw-r--r--recipes/acpid/acpid/fixfd.diff12
-rw-r--r--recipes/acpid/acpid/netlink.diff2797
-rw-r--r--recipes/acpid/acpid_1.0.8.bb6
-rw-r--r--recipes/boost/boost-36.inc24
-rw-r--r--recipes/cups/cups.inc10
-rw-r--r--recipes/cups/cups_1.1.23.bb2
-rw-r--r--recipes/cups/cups_1.2.12.bb2
-rw-r--r--recipes/cups/cups_1.2.7.bb2
-rw-r--r--recipes/cups/cups_1.3.8.bb2
-rw-r--r--recipes/gnash/gnash-minimal.inc2
-rw-r--r--recipes/gnash/gnash.inc2
-rw-r--r--recipes/gnome/libgnomeprintui_2.18.3.bb3
-rw-r--r--recipes/gnumeric/gnumeric_1.8.2.bb31
-rw-r--r--recipes/gnumeric/gnumeric_1.8.4.bb (renamed from recipes/gnumeric/gnumeric_1.8.3.bb)2
-rw-r--r--recipes/grub/grub-0.93/autohell.patch166
-rw-r--r--recipes/grub/grub-0.93/memcpy.patch13
-rw-r--r--recipes/grub/grub-0.93/reiserfs.patch11
-rw-r--r--recipes/grub/grub_0.93.bb15
-rw-r--r--recipes/grub/grub_0.97.bb36
-rw-r--r--recipes/gstreamer/gst-plugins-ugly-sid_0.10.7.bb8
-rw-r--r--recipes/gstreamer/gst-plugins-ugly_0.10.10.bb8
-rw-r--r--recipes/gtk-engines/gtk-engines_2.18.1.bb30
-rw-r--r--recipes/gtksourceview/gtksourceview2_2.6.0.bb18
-rw-r--r--recipes/hal/hal-cups-utils_0.6.19.bb23
-rw-r--r--recipes/initrdscripts/files/init.sh6
-rw-r--r--recipes/initrdscripts/initramfs-uniboot_1.0.bb2
-rw-r--r--recipes/linphone/linphone_1.3.99.8.bb2
-rw-r--r--recipes/mtools/files/no-x11.patch19
-rw-r--r--recipes/mtools/files/plainio.patch13
-rw-r--r--recipes/mtools/files/use-sg_io.patch80
-rw-r--r--recipes/mtools/mtools-native_4.0.10.bb (renamed from recipes/mtools/mtools-native_3.9.11.bb)0
-rw-r--r--recipes/mtools/mtools_4.0.10.bb (renamed from recipes/mtools/mtools_3.9.11.bb)7
-rw-r--r--recipes/ppp/ppp_2.4.3.bb3
-rw-r--r--recipes/python/python-pycups_1.9.45.bb16
-rw-r--r--recipes/rt2x00/rt61-firmware_1.2.bb2
-rw-r--r--recipes/system-config-printer/system-config-printer_1.1.7.bb22
-rw-r--r--recipes/xorg-driver/xf86-video-geode_2.11.2.bb5
38 files changed, 3137 insertions, 308 deletions
diff --git a/recipes/acpid/acpid/event.c.diff b/recipes/acpid/acpid/event.c.diff
new file mode 100644
index 0000000000..4ef3bafd6b
--- /dev/null
+++ b/recipes/acpid/acpid/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 <fcntl.h>
+ #include <unistd.h>
+ #include <stdio.h>
+@@ -90,6 +91,8 @@
+ struct dirent *dirent;
+ char *file = NULL;
+ int nrules = 0;
++ char *basen = NULL;
++ regex_t preg;
+
+ lock_rules();
+
+@@ -139,10 +142,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/fixfd.diff b/recipes/acpid/acpid/fixfd.diff
new file mode 100644
index 0000000000..93ceb5cfea
--- /dev/null
+++ b/recipes/acpid/acpid/fixfd.diff
@@ -0,0 +1,12 @@
+diff -Nru a/acpid.c b/acpid.c
+--- a/acpid.c 2008-11-03 14:04:43.000000000 +0100
++++ b/acpid.c 2008-12-19 18:38:14.291127677 +0100
+@@ -456,7 +456,7 @@
+ int log_opts;
+
+ /* open /dev/null */
+- nullfd = open("/dev/null", O_RDONLY);
++ nullfd = open("/dev/null", O_RDWR);
+ if (nullfd < 0) {
+ fprintf(stderr, "%s: can't open %s: %s\n", progname,
+ "/dev/null", strerror(errno));
diff --git a/recipes/acpid/acpid/netlink.diff b/recipes/acpid/acpid/netlink.diff
new file mode 100644
index 0000000000..5dbbedd5a3
--- /dev/null
+++ b/recipes/acpid/acpid/netlink.diff
@@ -0,0 +1,2797 @@
+diff -ruN acpid-1.0.8.orig/acpid.8 acpid-1.0.8/acpid.8
+--- acpid-1.0.8.orig/acpid.8 2008-11-03 14:04:43.000000000 +0100
++++ acpid-1.0.8/acpid.8 2009-03-29 17:10:14.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),
+@@ -69,6 +71,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
+@@ -122,6 +127,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.8.orig/acpid.c acpid-1.0.8/acpid.c
+--- acpid-1.0.8.orig/acpid.c 2008-11-03 14:04:43.000000000 +0100
++++ acpid-1.0.8/acpid.c 2009-03-29 17:10:14.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);
+@@ -45,7 +45,6 @@
+ static int create_pidfile(void);
+ static void clean_exit(int sig);
+ static void reload_conf(int sig);
+-static char *read_line(int fd);
+
+ /* global debug level */
+ int acpid_debug;
+@@ -53,23 +52,18 @@
+ /* do we log event info? */
+ int logevents;
+
+-static const char *progname;
+-static const char *confdir = ACPID_CONFDIR;
+-static const char *eventfile = ACPID_EVENTFILE;
+-static const char *socketfile = ACPID_SOCKETFILE;
++const char *progname;
++
+ static const char *lockfile = ACPID_LOCKFILE;
++static const char *confdir = ACPID_CONFDIR;
+ static int nosocket;
+-static const char *socketgroup;
+-static mode_t socketmode = ACPID_SOCKETMODE;
+ static int foreground;
+ static const char *pidfile = ACPID_PIDFILE;
++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];
+@@ -80,14 +74,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
+@@ -124,34 +126,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 */
+@@ -164,7 +139,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);
+@@ -183,109 +159,50 @@
+ 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;
+ }
+
+- /* 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;
+- }
++ /* for each connection */
++ for (i = 0; i <= get_number_of_connections(); ++i)
++ {
++ int fd;
+
+- /* read an event */
+- event = read_line(event_fd);
++ p = get_connection(i);
+
+- /* 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;
+- }
+-
+- /* 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];
+-
+- /* 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));
+- continue;
++ /* 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);
+ }
+ }
+
+@@ -312,6 +229,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},
+@@ -327,7 +245,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 */
+ };
+@@ -338,7 +257,7 @@
+ for (;;) {
+ int i;
+ i = getopt_long(*argc, *argv,
+- "c:de:flg:m:s:Sp:L:vh", opts, NULL);
++ "c:de:flg:m:s:Sp:L:nvh", opts, NULL);
+ if (i == -1) {
+ break;
+ }
+@@ -377,6 +296,9 @@
+ case 'L':
+ lockfile = optarg;
+ break;
++ case 'n':
++ netlink = 1;
++ break;
+ case 'v':
+ printf(PACKAGE "-" VERSION "\n");
+ exit(EXIT_SUCCESS);
+@@ -550,54 +472,11 @@
+ return 0;
+ }
+
+-/*
+- * This depends on fixes in linux ACPI after 2.4.8
+- */
+-#define MAX_BUFLEN 1024
+-static char *
+-read_line(int fd)
++int
++locked()
+ {
+- 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;
+- }
++ struct stat trash;
+
+- return buf;
++ /* check for existence of a lockfile */
++ return (stat(lockfile, &trash) == 0);
+ }
+diff -ruN acpid-1.0.8.orig/acpid.h acpid-1.0.8/acpid.h
+--- acpid-1.0.8.orig/acpid.h 2008-11-03 14:04:43.000000000 +0100
++++ acpid-1.0.8/acpid.h 2009-03-29 17:10:14.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"
+@@ -40,19 +36,12 @@
+
+ #define PACKAGE "acpid"
+
+-/*
+- * acpid.c
+- */
+ extern int acpid_debug;
+ extern int logevents;
++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 int locked();
+
+ #endif /* ACPID_H__ */
+diff -ruN acpid-1.0.8.orig/acpi_genetlink.h acpid-1.0.8/acpi_genetlink.h
+--- acpid-1.0.8.orig/acpi_genetlink.h 1970-01-01 01:00:00.000000000 +0100
++++ acpid-1.0.8/acpi_genetlink.h 2009-03-29 17:10:14.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.8.orig/acpi_ids.c acpid-1.0.8/acpi_ids.c
+--- acpid-1.0.8.orig/acpi_ids.c 1970-01-01 01:00:00.000000000 +0100
++++ acpid-1.0.8/acpi_ids.c 2009-03-29 17:10:14.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 multi