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);
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to