From owner-freebsd-hackers@FreeBSD.ORG Sun Aug 31 09:12:12 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5242416A4BF; Sun, 31 Aug 2003 09:12:12 -0700 (PDT) Received: from webmail.tiscali.de (relay1.tiscali.de [62.26.116.129]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2AB4443F75; Sun, 31 Aug 2003 09:12:11 -0700 (PDT) (envelope-from walter@pelissero.de) Received: from daemon.home.loc (62.246.38.160) by webmail.tiscali.de (6.7.019) id 3F42A6F5003AFA7C; Sun, 31 Aug 2003 18:12:10 +0200 Received: from hyde.home.loc (hyde.home.loc [10.0.0.2]) by daemon.home.loc (8.12.9/8.12.8) with ESMTP id h7VGAojl000972; Sun, 31 Aug 2003 18:10:50 +0200 (CEST) (envelope-from wcp@hyde.home.loc) Received: from hyde.home.loc (localhost [127.0.0.1]) by hyde.home.loc (8.12.9/8.12.8) with ESMTP id h7VGAmZf051409; Sun, 31 Aug 2003 18:10:49 +0200 (CEST) (envelope-from wcp@hyde.home.loc) Received: (from wcp@localhost) by hyde.home.loc (8.12.9/8.12.6/Submit) id h7VGAkGK051406; Sun, 31 Aug 2003 18:10:47 +0200 (CEST) (envelope-from wcp) From: "Walter C. Pelissero" MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16210.7684.367963.11923@hyde.home.loc> Date: Sun, 31 Aug 2003 18:10:44 +0200 To: Bruce M Simpson In-Reply-To: <20030830120438.GA29217@spc.org> References: <16208.36799.970894.848331@hyde.home.loc> <20030830120438.GA29217@spc.org> X-Mailer: VM 7.16 under Emacs 21.3.50.2 X-Attribution: WP cc: hackers@freebsd.org cc: questions@freebsd.org Subject: Re: USB -> PS/2 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: walter@pelissero.de List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Aug 2003 16:12:12 -0000 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);