Package: lirc
Version: 0.7.2-2
Severity: wishlist
I've found that while unloading and reloading an input device module
(remote control input via budget-ci, which I'm modifying a bit), the input
device number isn't stable - it normally appears as input3 but has appeared
as input4 (with nothing at input3).
The attached patch (which should be applied after 04_man_page)) allows the
use of "name=foo" and "phys=foo" for --device (or, for that matter, DEVICE in
/etc/lirc/hardware.conf); shell wildcards are allowed.
--
| Darren Salt | nr. Ashington, | linux (or ds) at
| sarge, | Northumberland | youmustbejoking
| RISC OS | Toon Army | demon co uk
| Kill all extremists!
Nothing endures but change.
--- lirc.orig/doc/man/lircd.8
+++ lirc/doc/man/lircd.8
@@ -57,6 +57,16 @@
should read from. The default currently is /dev/lirc but it probably
will change in future.
+If you're using the dev/input driver, you can use
+.I name=STRING
+or
+.I phys=STRING
+to select the device; lircd will look in /dev/input to
+find a device with a matching description. This is useful in case the
+device name isn't fixed.
+.I STRING
+may contain the '*' and '?' wildcards and '\' to mark them as literal.
+
With the \-\-listen option you can let lircd listen for network
connections on the given port. The default port is 8765. No security
checks are currently implemented.
--- lirc.orig/doc/html/lircd.html
+++ lirc/doc/html/lircd.html
@@ -91,6 +91,12 @@
should read from. The default currently is /dev/lirc but it probably
will change in future.
<P>
+If you're using the dev/input driver, you can use <tt>name=STRING</tt> or
+<tt>phys=STRING</tt> to select the device; lircd will look in /dev/input to
+find a device with a matching description. This is useful in case the device
+name isn't fixed. <tt>STRING</tt> may contain the '*' and '?' wildcards and
+\ to mark them as literal.
+<P>
With the \-\-listen option you can let lircd listen for network
connections on the given port. The default port is 8765. No security
checks are currently implemented.
--- lirc.orig/daemons/hw_devinput.c
+++ lirc/daemons/hw_devinput.c
@@ -25,6 +25,9 @@
#include <stdio.h>
#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fnmatch.h>
#include <linux/input.h>
@@ -63,9 +66,105 @@
static ir_code code;
static int repeat_flag=0;
+static int do_match (const char *text, const char *wild)
+{
+ while (*wild) {
+ if (*wild == '*') {
+ const char *next = text - 1;
+ ++wild;
+ while (*++next)
+ if (!do_match (next, wild))
+ return 0;
+ return 1;
+ }
+ else if (*wild == '?') {
+ if (!*text++)
+ return 1;
+ }
+ else if (*wild == '\\') {
+ if (wild[1] != *text++)
+ return 1;
+ if (!wild[1])
+ return 0;
+ wild += 2;
+ }
+ else if (*wild++ != *text++)
+ return 1;
+ }
+ return 0;
+}
+
+static int locate_dev (const char *label, int type)
+{
+ static char devname[FILENAME_MAX];
+ char ioname[255];
+ DIR *dir;
+ struct dirent *obj;
+ int ionum;
+
+ dir = opendir ("/dev/input");
+ if (!dir)
+ return 1;
+
+ devname[0] = 0;
+ switch (type) {
+ case 0:
+ ionum = EVIOCGNAME (sizeof (ioname));
+ break;
+ case 1:
+ ionum = EVIOCGPHYS (sizeof (ioname));
+ break;
+ default:
+ closedir (dir);
+ return 1;
+ }
+
+ while ((obj = readdir (dir))) {
+ int fd;
+ if (obj->d_name[0] == '.' &&
+ (obj->d_name[1] == 0 ||
+ (obj->d_name[1] == '.' && obj->d_name[2] == 0)))
+ continue; /* skip "." and ".." */
+ sprintf (devname, "/dev/input/%s", obj->d_name);
+ fd = open (devname, O_RDONLY);
+ if (!fd)
+ continue;
+ if (ioctl (fd, ionum, ioname) >= 0) {
+ close (fd);
+ int ret = do_match (ioname, label);
+ if (!ret) {
+ hw.device = devname;
+ closedir (dir);
+ return 0;
+ }
+ }
+ close (fd);
+ }
+
+ closedir (dir);
+ return 1;
+}
+
int devinput_init()
{
logprintf(LOG_INFO, "initializing '%s'", hw.device);
+
+printf ("device = %s\n", hw.device);
+
+ if (!strncmp (hw.device, "name=", 5)) {
+ if (locate_dev (hw.device + 5, 0)) {
+ logprintf(LOG_ERR, "unable to find '%s'", hw.device);
+ return 0;
+ }
+ }
+ else if (!strncmp (hw.device, "phys=", 5)) {
+puts ("checking phys");
+ if (locate_dev (hw.device + 5, 1)) {
+ logprintf(LOG_ERR, "unable to find '%s'", hw.device);
+ return 0;
+ }
+printf ("match found: %s\n", hw.device);
+ }
if ((hw.fd = open(hw.device, O_RDONLY)) < 0) {
logprintf(LOG_ERR, "unable to open '%s'", hw.device);