USB -> PS/2
Walter C. Pelissero
walter at pelissero.de
Sun Aug 31 09:12:12 PDT 2003
Just noticed that the patch to usbd.c I proposed yesterday shows an
undesirable behaviour. That is, usbd executes the actions in
usbd.conf of all matching devices, which is not exactly what I meant
to do. In fact, usbd should execute for every device name the "best"
matching action in usbd.conf.
Supposed usbd.conf is sorted in a way that the most specific entries
precede the less specific ones, the following patch should do the
trick.
Cheers,
--
walter pelissero
http://www.pelissero.de
--- usbd.c.orig Sun Aug 31 17:24:14 2003
+++ usbd.c Sun Aug 31 17:08:19 2003
@@ -102,6 +102,7 @@
int lineno;
int verbose = 0; /* print message on what it is doing */
+int single_action = 0;
typedef struct event_name_s {
int type; /* event number (from usb.h) */
@@ -204,8 +205,7 @@
void print_event __P((struct usb_event *event));
void print_action __P((action_t *action, int i));
void print_actions __P((void));
-int find_action __P((struct usb_device_info *devinfo,
- action_match_t *action_match));
+void execute_command __P((char *cmd));
void
@@ -674,37 +674,19 @@
int
-match_devname(action_t *action, struct usb_device_info *devinfo)
+match_devname(regex_t *regex, char *name)
{
- int i;
- regmatch_t match;
- int error;
-
- for (i = 0; i < USB_MAX_DEVNAMES; i++) {
- if (devinfo->udi_devnames[i][0] == '\0')
- break;
-
- error = regexec(&action->devname_regex, devinfo->udi_devnames[i],
- 1, &match, 0);
- if (error == 0) {
- if (verbose >= 2)
- printf("%s: %s matches %s\n", __progname,
- devinfo->udi_devnames[i], action->devname);
- return(i);
- }
- }
-
- return(-1);
+ return regexec(regex, name, 0, 0, 0) == 0;
}
-
-int
-find_action(struct usb_device_info *devinfo, action_match_t *action_match)
+void
+execute_actions (struct usb_device_info *devinfo, int event_type)
{
action_t *action;
char *devname = NULL;
- int match = -1;
+ int i;
+ for (i = 0; i < USB_MAX_DEVNAMES && devinfo->udi_devnames[i][0] != '\0'; i++) {
STAILQ_FOREACH(action, &actions, next) {
if ((action->vendor == WILDCARD_INT ||
action->vendor == devinfo->udi_vendorNo) &&
@@ -719,15 +701,15 @@
(action->protocol == WILDCARD_INT ||
action->protocol == devinfo->udi_protocol) &&
(action->devname == WILDCARD_STRING ||
- (match = match_devname(action, devinfo)) != -1)) {
- /* found match !*/
-
+ match_devname(&action->devname_regex, devinfo->udi_devnames[i]))) {
+ if (verbose >= 2)
+ print_action(action, 0);
/* Find a devname for pretty printing. Either
* the matched one or otherwise, if there is only
* one devname for that device, use that.
*/
- if (match >= 0)
- devname = devinfo->udi_devnames[match];
+ if (action->devname != WILDCARD_STRING)
+ devname = devinfo->udi_devnames[i];
else if (devinfo->udi_devnames[0][0] != '\0' &&
devinfo->udi_devnames[1][0] == '\0')
/* if we have exactly 1 device name */
@@ -742,16 +724,37 @@
printf("\n");
}
- action_match->action = action;
- action_match->devname = devname;
+ if (devname) {
+ int error;
+ if (verbose >= 2)
+ printf("%s: Setting DEVNAME='%s'\n",
+ __progname, devname);
+ error = setenv("DEVNAME", devname, 1);
+ if (error)
+ fprintf(stderr, "%s: setenv(\"DEVNAME\",
+ \"%s\",1) failed, %s\n",
+ __progname, devname, strerror(errno));
+ }
- return(1);
+ if (USB_EVENT_IS_ATTACH(event_type) && action->attach)
+ execute_command(action->attach);
+ if (USB_EVENT_IS_DETACH(event_type) && action->detach)
+ execute_command(action->detach);
+ /* We are done if either we are
+ * running in single action mode or we
+ * didn't match the device name, that
+ * is, we have a catch-all entry for
+ * the particular USB device. */
+ if (single_action || action->devname == WILDCARD_STRING)
+ return;
+ /* get on to the next device name */
+ break;
+ }
}
}
-
- return(0);
}
+
void
execute_command(char *cmd)
{
@@ -881,30 +884,7 @@
break;
case USB_EVENT_DEVICE_ATTACH:
case USB_EVENT_DEVICE_DETACH:
- if (find_action(&event.u.ue_device, &action_match) == 0)
- /* nothing found */
- break;
-
- if (verbose >= 2)
- print_action(action_match.action, 0);
-
- if (action_match.devname) {
- if (verbose >= 2)
- printf("%s: Setting DEVNAME='%s'\n",
- __progname, action_match.devname);
-
- error = setenv("DEVNAME", action_match.devname, 1);
- if (error)
- fprintf(stderr, "%s: setenv(\"DEVNAME\", \"%s\",1) failed, %s\n",
- __progname, action_match.devname, strerror(errno));
- }
-
- if (USB_EVENT_IS_ATTACH(event.ue_type) &&
- action_match.action->attach)
- execute_command(action_match.action->attach);
- if (USB_EVENT_IS_DETACH(event.ue_type) &&
- action_match.action->detach)
- execute_command(action_match.action->detach);
+ execute_actions(&event.u.ue_device, event.ue_type);
break;
case USB_EVENT_DRIVER_ATTACH:
if (verbose)
@@ -944,7 +924,7 @@
}
}
- while ((ch = getopt(argc, argv, "c:def:nt:v")) != -1) {
+ while ((ch = getopt(argc, argv, "c:def:nst:v")) != -1) {
switch(ch) {
case 'c':
configfile = strdup(optarg);
@@ -965,6 +945,9 @@
break;
case 'n':
handle_events = 0;
+ break;
+ case 's':
+ single_action = 1;
break;
case 't':
itimeout = atoi(optarg);
More information about the freebsd-questions
mailing list