2003-12-03 05:38:30 +03:00
/*
2005-03-13 00:36:32 +03:00
* udev_rules_parse . c
2003-12-03 05:38:30 +03:00
*
* Userspace devfs
*
2004-01-27 06:21:58 +03:00
* Copyright ( C ) 2003 , 2004 Greg Kroah - Hartman < greg @ kroah . com >
2005-02-14 08:03:06 +03:00
* Copyright ( C ) 2003 - 2005 Kay Sievers < kay . sievers @ vrfy . org >
2003-12-03 05:38:30 +03:00
*
*
* 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 version 2 of the License .
*
* 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 . ,
* 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*
*/
# include <stddef.h>
# include <stdlib.h>
# include <string.h>
# include <stdio.h>
# include <ctype.h>
# include <unistd.h>
2004-02-24 06:31:14 +03:00
# include <sys/stat.h>
2003-12-03 05:38:30 +03:00
# include <errno.h>
2005-03-07 06:29:43 +03:00
# include "udev_libc_wrapper.h"
2003-12-03 05:38:30 +03:00
# include "udev.h"
2004-11-25 04:44:38 +03:00
# include "udev_utils.h"
[PATCH] add udev logging to info log
On Thu, Jan 15, 2004 at 05:14:16AM +0100, Kay Sievers wrote:
> On Wed, Jan 14, 2004 at 01:10:43PM -0800, Greg KH wrote:
> > On Wed, Jan 14, 2004 at 02:34:26PM -0600, Clay Haapala wrote:
> > > On Wed, 14 Jan 2004, Chris Friesen spake thusly:
> > > >
> > > > Maybe for ones with a matching rule, you could print something like:
> > > >
> > > >
> > > Is the act of printing/syslogging a rule in an of itself?
> >
> > No, as currently the only way stuff ends up in the syslog is if
> > DEBUG=true is used on the build line.
> >
> > But it's sounding like we might want to change that... :)
>
> How about this in the syslog after connect/disconnect?
>
> Jan 15 05:07:45 pim udev[28007]: configured rule in '/etc/udev/udev.rules' at line 17 applied, 'video*' becomes 'video/webcam%n'
> Jan 15 05:07:45 pim udev[28007]: creating device node '/udev/video/webcam0'
> Jan 15 05:07:47 pim udev[28015]: removing device node '/udev/video/webcam0'
Here is a slightly better version. I've created a logging.h file and
moved the debug macros from udev.h in there.
If you type:
'make' - you will get a binary that prints one or two lines to syslog
if a device node is created or deleted
'make LOG=false' - you get a binary that prints asolutely nothing
'make DEBUG=true' - the same as today, it will print all debug lines
2004-01-16 08:53:20 +03:00
# include "logging.h"
2005-03-13 00:36:32 +03:00
# include "udev_rules.h"
2003-12-03 05:38:30 +03:00
2005-03-13 00:36:32 +03:00
LIST_HEAD ( udev_rule_list ) ;
2004-03-11 09:35:37 +03:00
2005-03-13 09:14:49 +03:00
static int add_config_dev ( struct udev_rule * rule )
2003-12-23 09:31:35 +03:00
{
2005-03-13 00:36:32 +03:00
struct udev_rule * tmp_rule ;
2003-12-23 09:31:35 +03:00
2005-03-13 00:36:32 +03:00
tmp_rule = malloc ( sizeof ( * tmp_rule ) ) ;
if ( tmp_rule = = NULL )
2003-12-23 09:31:35 +03:00
return - ENOMEM ;
2005-03-13 09:14:49 +03:00
memcpy ( tmp_rule , rule , sizeof ( struct udev_rule ) ) ;
2005-03-13 00:36:32 +03:00
list_add_tail ( & tmp_rule - > node , & udev_rule_list ) ;
dbg ( " name='%s', symlink='%s', bus='%s', id='%s', "
" sysfs_file[0]='%s', sysfs_value[0]='%s', "
2005-03-13 09:14:49 +03:00
" kernel='%s', program='%s', result='%s', "
" owner='%s', group='%s', mode=%#o, "
" all_partions=%u, ignore_remove=%u, ignore_device=%u, last_rule=%u " ,
2005-03-13 00:36:32 +03:00
rule - > name , rule - > symlink , rule - > bus , rule - > id ,
2005-03-13 10:15:10 +03:00
rule - > sysfs_pair [ 0 ] . name , rule - > sysfs_pair [ 0 ] . value ,
2005-03-13 09:14:49 +03:00
rule - > kernel , rule - > program , rule - > result , rule - > owner , rule - > group , rule - > mode ,
rule - > partitions , rule - > ignore_remove , rule - > ignore_device , rule - > last_rule ) ;
2003-12-03 05:38:30 +03:00
2005-03-13 09:14:49 +03:00
return 0 ;
2003-12-03 05:38:30 +03:00
}
2003-12-04 05:33:58 +03:00
2005-03-13 07:46:31 +03:00
static int get_key ( char * * line , char * * key , enum key_operation * operation , char * * value )
{
char * linepos ;
char * temp ;
linepos = * line ;
if ( ! linepos )
return - 1 ;
/* skip whitespace */
while ( isspace ( linepos [ 0 ] ) | | linepos [ 0 ] = = ' , ' )
linepos + + ;
/* get the key */
* key = linepos ;
while ( 1 ) {
linepos + + ;
if ( linepos [ 0 ] = = ' \0 ' )
return - 1 ;
if ( isspace ( linepos [ 0 ] ) )
break ;
if ( linepos [ 0 ] = = ' = ' )
break ;
if ( linepos [ 0 ] = = ' + ' )
break ;
if ( linepos [ 0 ] = = ' ! ' )
break ;
2005-06-05 06:57:03 +04:00
if ( linepos [ 0 ] = = ' : ' )
break ;
2005-03-13 07:46:31 +03:00
}
/* remember end of key */
temp = linepos ;
/* skip whitespace after key */
while ( isspace ( linepos [ 0 ] ) )
linepos + + ;
/* get operation type */
if ( linepos [ 0 ] = = ' = ' & & linepos [ 1 ] = = ' = ' ) {
* operation = KEY_OP_MATCH ;
linepos + = 2 ;
dbg ( " operator=match " ) ;
} else if ( linepos [ 0 ] = = ' ! ' & & linepos [ 1 ] = = ' = ' ) {
* operation = KEY_OP_NOMATCH ;
linepos + = 2 ;
dbg ( " operator=nomatch " ) ;
} else if ( linepos [ 0 ] = = ' + ' & & linepos [ 1 ] = = ' = ' ) {
* operation = KEY_OP_ADD ;
linepos + = 2 ;
dbg ( " operator=add " ) ;
} else if ( linepos [ 0 ] = = ' = ' ) {
* operation = KEY_OP_ASSIGN ;
linepos + + ;
dbg ( " operator=assign " ) ;
2005-06-05 06:57:03 +04:00
} else if ( linepos [ 0 ] = = ' : ' & & linepos [ 1 ] = = ' = ' ) {
* operation = KEY_OP_ASSIGN_FINAL ;
linepos + = 2 ;
dbg ( " operator=assign_final " ) ;
2005-03-13 07:46:31 +03:00
} else
return - 1 ;
/* terminate key */
temp [ 0 ] = ' \0 ' ;
dbg ( " key='%s' " , * key ) ;
/* skip whitespace after operator */
while ( isspace ( linepos [ 0 ] ) )
linepos + + ;
/* get the value*/
if ( linepos [ 0 ] = = ' " ' )
linepos + + ;
else
return - 1 ;
* value = linepos ;
temp = strchr ( linepos , ' " ' ) ;
if ( ! temp )
return - 1 ;
temp [ 0 ] = ' \0 ' ;
temp + + ;
dbg ( " value='%s' " , * value ) ;
/* move line to next key */
* line = temp ;
return 0 ;
}
2004-11-13 14:50:44 +03:00
/* extract possible KEY{attr} */
2004-02-17 08:39:40 +03:00
static char * get_key_attribute ( char * str )
{
char * pos ;
char * attr ;
attr = strchr ( str , ' { ' ) ;
if ( attr ! = NULL ) {
attr + + ;
pos = strchr ( attr , ' } ' ) ;
if ( pos = = NULL ) {
2005-03-27 03:11:03 +04:00
err ( " missing closing brace for format " ) ;
2004-02-17 08:39:40 +03:00
return NULL ;
}
pos [ 0 ] = ' \0 ' ;
dbg ( " attribute='%s' " , attr ) ;
return attr ;
}
return NULL ;
}
2005-03-17 11:59:32 +03:00
static int rules_parse ( const char * filename )
2003-12-03 05:38:30 +03:00
{
2004-09-11 07:54:04 +04:00
char line [ LINE_SIZE ] ;
char * bufline ;
2003-12-03 05:38:30 +03:00
int lineno ;
2005-03-13 07:46:31 +03:00
char * linepos ;
2004-02-17 08:39:40 +03:00
char * attr ;
2004-03-23 09:22:20 +03:00
char * buf ;
size_t bufsize ;
size_t cur ;
size_t count ;
[PATCH] udev - drop all methods :)
> Hi,
> as promised yesterday, here is a patch that drops the explicit methods
> given in the udev config and implement only one type of rule.
>
> A rule now consists only of a number of keys to match. All known keys
> are valid in any combination. The former configs should work with a few
> changes:
>
> o the "<METHOD>, " at the beginning of the line should be removed
>
> o the result of the externel program is matched with RESULT= instead if ID=
> the PROGRAM= key is only valid if the program exits with zero
> (just exit with nozero in a script if the rule should not match)
>
> o rules are processed in order they appear in the file, no priority
>
> o if NAME="" is given, udev is instructed to ignore this device,
> no node will be created
>
>
> EXAMPLE:
>
> # combined BUS, SYSFS and KERNEL
> BUS="usb", KERNEL="video*", SYSFS_model="Creative Labs WebCam*", NAME="test/webcam%n"
>
> # exec script only for the first ide drive (hda), all other will be skipped
> BUS="ide", KERNEL="hda*", PROGRAM="/home/kay/src/udev.kay/extras/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c"
>
>
> The udev-test.pl and test.block works fine here.
> Please adapt your config and give it a try.
>
Here is a slightly better version of the patch.
After a conversation with Patrick, we are now able to execute the PROGRAM
and also match in all following rules with the RESULT value from this exec.
EXAMPLE:
We have 7 rules with RESULT and 2 with PROGRAM.
Only the 5th rule matches with the callout result from the exec in the 4th rule.
RULES:
PROGRAM="/bin/echo abc", RESULT="no_match", NAME="web-no-2"
KERNEL="video*", RESULT="123", NAME="web-no-3"
KERNEL="video*", RESULT="123", NAME="web-no-4"
PROGRAM="/bin/echo 123", RESULT="no_match", NAME="web-no-5"
KERNEL="video*", RESULT="123", NAME="web-yes"
RESULT:
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM
Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo abc'
Jan 11 23:36:52 pim udev[26050]: execute_program: result is 'abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM
Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo 123'
Jan 11 23:36:52 pim udev[26050]: execute_program: result is '123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: found matching rule, 'video*' becomes ''
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: name, 'web-yes' is going to have owner='', group='', mode = 0600
2004-01-13 08:39:05 +03:00
int program_given = 0 ;
2004-09-11 07:54:04 +04:00
int valid ;
2003-12-03 05:38:30 +03:00
int retval = 0 ;
2005-03-13 00:36:32 +03:00
struct udev_rule rule ;
2003-12-03 05:38:30 +03:00
2005-03-13 07:46:31 +03:00
if ( file_map ( filename , & buf , & bufsize ) ! = 0 ) {
2005-03-27 03:11:03 +04:00
err ( " can't open '%s' as rules file " , filename ) ;
2004-03-23 09:22:20 +03:00
return - 1 ;
2003-12-03 05:38:30 +03:00
}
2005-03-13 07:46:31 +03:00
dbg ( " reading '%s' as rules file " , filename ) ;
2003-12-03 05:38:30 +03:00
/* loop through the whole file */
2004-03-23 09:22:20 +03:00
cur = 0 ;
2003-12-03 05:38:30 +03:00
lineno = 0 ;
2004-09-11 07:54:04 +04:00
while ( cur < bufsize ) {
2005-02-05 04:38:56 +03:00
unsigned int i , j ;
2004-12-20 09:38:33 +03:00
2004-03-23 09:22:20 +03:00
count = buf_get_line ( buf , bufsize , cur ) ;
2004-09-11 07:54:04 +04:00
bufline = & buf [ cur ] ;
2004-03-23 09:22:20 +03:00
cur + = count + 1 ;
2004-09-11 07:54:04 +04:00
lineno + + ;
2003-12-03 05:38:30 +03:00
2005-03-07 06:29:43 +03:00
if ( count > = sizeof ( line ) ) {
2004-12-20 09:38:33 +03:00
info ( " line too long, rule skipped %s, line %d " , filename , lineno ) ;
2004-09-11 07:54:04 +04:00
continue ;
}
2003-12-18 05:24:05 +03:00
2004-09-11 07:54:04 +04:00
/* eat the whitespace */
2004-09-15 04:45:48 +04:00
while ( ( count > 0 ) & & isspace ( bufline [ 0 ] ) ) {
2004-09-11 07:54:04 +04:00
bufline + + ;
count - - ;
}
2004-09-15 04:45:48 +04:00
if ( count = = 0 )
continue ;
2004-09-11 07:54:04 +04:00
2003-12-03 05:38:30 +03:00
/* see if this is a comment */
2004-09-11 07:54:04 +04:00
if ( bufline [ 0 ] = = COMMENT_CHARACTER )
2003-12-03 05:38:30 +03:00
continue ;
2004-12-20 09:38:33 +03:00
/* skip backslash and newline from multi line rules */
for ( i = j = 0 ; i < count ; i + + ) {
2005-02-26 04:52:04 +03:00
if ( bufline [ i ] = = ' \\ ' & & bufline [ i + 1 ] = = ' \n ' )
2004-12-20 09:38:33 +03:00
continue ;
line [ j + + ] = bufline [ i ] ;
}
line [ j ] = ' \0 ' ;
2005-03-13 00:36:32 +03:00
dbg ( " read '%s' " , line ) ;
2003-12-03 05:38:30 +03:00
2003-12-17 10:36:19 +03:00
/* get all known keys */
2005-03-13 00:36:32 +03:00
memset ( & rule , 0x00 , sizeof ( struct udev_rule ) ) ;
2005-03-13 07:46:31 +03:00
linepos = line ;
2004-09-11 07:54:04 +04:00
valid = 0 ;
2003-12-17 10:36:19 +03:00
while ( 1 ) {
2005-03-13 07:46:31 +03:00
char * key ;
char * value ;
2005-03-28 14:20:05 +04:00
enum key_operation operation = KEY_OP_UNSET ;
2005-03-13 07:46:31 +03:00
retval = get_key ( & linepos , & key , & operation , & value ) ;
2003-12-03 05:38:30 +03:00
if ( retval )
break ;
2003-12-07 20:12:07 +03:00
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_KERNEL ) = = 0 ) {
strlcpy ( rule . kernel , value , sizeof ( rule . kernel ) ) ;
rule . kernel_operation = operation ;
2005-02-21 16:01:23 +03:00
valid = 1 ;
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_SUBSYSTEM ) = = 0 ) {
strlcpy ( rule . subsystem , value , sizeof ( rule . subsystem ) ) ;
rule . subsystem_operation = operation ;
2005-02-21 16:01:23 +03:00
valid = 1 ;
continue ;
}
2005-04-02 19:45:35 +04:00
if ( strcasecmp ( key , KEY_ACTION ) = = 0 ) {
strlcpy ( rule . action , value , sizeof ( rule . action ) ) ;
rule . action_operation = operation ;
valid = 1 ;
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_BUS ) = = 0 ) {
strlcpy ( rule . bus , value , sizeof ( rule . bus ) ) ;
rule . bus_operation = operation ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
2003-12-17 10:36:19 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_ID ) = = 0 ) {
strlcpy ( rule . id , value , sizeof ( rule . id ) ) ;
rule . id_operation = operation ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
2003-12-17 10:36:19 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strncasecmp ( key , KEY_SYSFS , sizeof ( KEY_SYSFS ) - 1 ) = = 0 ) {
2005-03-13 10:15:10 +03:00
struct key_pair * pair ;
if ( rule . sysfs_pair_count > = KEY_SYSFS_PAIRS_MAX ) {
2005-03-27 03:11:03 +04:00
err ( " skip rule, to many " KEY_SYSFS " keys in a single rule " ) ;
2005-03-13 10:15:10 +03:00
goto error ;
2003-12-23 09:31:35 +03:00
}
2005-03-13 10:15:10 +03:00
pair = & rule . sysfs_pair [ rule . sysfs_pair_count ] ;
attr = get_key_attribute ( key + sizeof ( KEY_SYSFS ) - 1 ) ;
if ( attr = = NULL ) {
2005-03-27 03:11:03 +04:00
err ( " error parsing " KEY_SYSFS " attribute " ) ;
2005-03-13 13:40:32 +03:00
goto error ;
}
strlcpy ( pair - > name , attr , sizeof ( pair - > name ) ) ;
strlcpy ( pair - > value , value , sizeof ( pair - > value ) ) ;
pair - > operation = operation ;
rule . sysfs_pair_count + + ;
valid = 1 ;
continue ;
}
if ( strncasecmp ( key , KEY_ENV , sizeof ( KEY_ENV ) - 1 ) = = 0 ) {
struct key_pair * pair ;
if ( rule . env_pair_count > = KEY_ENV_PAIRS_MAX ) {
2005-03-27 03:11:03 +04:00
err ( " skip rule, to many " KEY_ENV " keys in a single rule " ) ;
2005-03-13 13:40:32 +03:00
goto error ;
}
pair = & rule . env_pair [ rule . env_pair_count ] ;
attr = get_key_attribute ( key + sizeof ( KEY_ENV ) - 1 ) ;
if ( attr = = NULL ) {
2005-03-27 03:11:03 +04:00
err ( " error parsing " KEY_ENV " attribute " ) ;
2005-03-13 10:15:10 +03:00
continue ;
2003-12-23 09:31:35 +03:00
}
2005-03-13 10:15:10 +03:00
strlcpy ( pair - > name , attr , sizeof ( pair - > name ) ) ;
strlcpy ( pair - > value , value , sizeof ( pair - > value ) ) ;
pair - > operation = operation ;
2005-03-13 13:40:32 +03:00
rule . env_pair_count + + ;
2005-03-13 10:15:10 +03:00
valid = 1 ;
2003-12-17 10:36:19 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_DRIVER ) = = 0 ) {
strlcpy ( rule . driver , value , sizeof ( rule . driver ) ) ;
rule . driver_operation = operation ;
2004-11-13 07:21:12 +03:00
valid = 1 ;
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_RESULT ) = = 0 ) {
strlcpy ( rule . result , value , sizeof ( rule . result ) ) ;
rule . result_operation = operation ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
[PATCH] udev - drop all methods :)
> Hi,
> as promised yesterday, here is a patch that drops the explicit methods
> given in the udev config and implement only one type of rule.
>
> A rule now consists only of a number of keys to match. All known keys
> are valid in any combination. The former configs should work with a few
> changes:
>
> o the "<METHOD>, " at the beginning of the line should be removed
>
> o the result of the externel program is matched with RESULT= instead if ID=
> the PROGRAM= key is only valid if the program exits with zero
> (just exit with nozero in a script if the rule should not match)
>
> o rules are processed in order they appear in the file, no priority
>
> o if NAME="" is given, udev is instructed to ignore this device,
> no node will be created
>
>
> EXAMPLE:
>
> # combined BUS, SYSFS and KERNEL
> BUS="usb", KERNEL="video*", SYSFS_model="Creative Labs WebCam*", NAME="test/webcam%n"
>
> # exec script only for the first ide drive (hda), all other will be skipped
> BUS="ide", KERNEL="hda*", PROGRAM="/home/kay/src/udev.kay/extras/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c"
>
>
> The udev-test.pl and test.block works fine here.
> Please adapt your config and give it a try.
>
Here is a slightly better version of the patch.
After a conversation with Patrick, we are now able to execute the PROGRAM
and also match in all following rules with the RESULT value from this exec.
EXAMPLE:
We have 7 rules with RESULT and 2 with PROGRAM.
Only the 5th rule matches with the callout result from the exec in the 4th rule.
RULES:
PROGRAM="/bin/echo abc", RESULT="no_match", NAME="web-no-2"
KERNEL="video*", RESULT="123", NAME="web-no-3"
KERNEL="video*", RESULT="123", NAME="web-no-4"
PROGRAM="/bin/echo 123", RESULT="no_match", NAME="web-no-5"
KERNEL="video*", RESULT="123", NAME="web-yes"
RESULT:
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM
Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo abc'
Jan 11 23:36:52 pim udev[26050]: execute_program: result is 'abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM
Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo 123'
Jan 11 23:36:52 pim udev[26050]: execute_program: result is '123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: found matching rule, 'video*' becomes ''
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: name, 'web-yes' is going to have owner='', group='', mode = 0600
2004-01-13 08:39:05 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_PROGRAM ) = = 0 ) {
strlcpy ( rule . program , value , sizeof ( rule . program ) ) ;
rule . program_operation = operation ;
program_given = 1 ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
2003-12-17 10:36:19 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strncasecmp ( key , KEY_NAME , sizeof ( KEY_NAME ) - 1 ) = = 0 ) {
attr = get_key_attribute ( key + sizeof ( KEY_NAME ) - 1 ) ;
2004-11-13 16:43:24 +03:00
if ( attr ! = NULL ) {
2005-03-04 23:00:43 +03:00
if ( strstr ( attr , OPTION_PARTITIONS ) ! = NULL ) {
2005-03-13 00:36:32 +03:00
dbg ( " creation of partition nodes requested " ) ;
rule . partitions = DEFAULT_PARTITIONS_COUNT ;
2004-02-17 08:44:28 +03:00
}
2005-06-05 17:55:29 +04:00
/* FIXME: remove old style option and make OPTIONS= mandatory */
2005-03-04 23:00:43 +03:00
if ( strstr ( attr , OPTION_IGNORE_REMOVE ) ! = NULL ) {
2005-03-13 00:36:32 +03:00
dbg ( " remove event should be ignored " ) ;
rule . ignore_remove = 1 ;
2004-11-13 16:43:24 +03:00
}
}
2005-06-05 17:55:29 +04:00
rule . name_operation = operation ;
strlcpy ( rule . name , value , sizeof ( rule . name ) ) ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
2003-12-17 10:36:19 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_SYMLINK ) = = 0 ) {
strlcpy ( rule . symlink , value , sizeof ( rule . symlink ) ) ;
2005-06-05 06:57:03 +04:00
rule . symlink_operation = operation ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
2003-12-17 10:36:19 +03:00
continue ;
}
2003-12-07 20:12:07 +03:00
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_OWNER ) = = 0 ) {
strlcpy ( rule . owner , value , sizeof ( rule . owner ) ) ;
2005-06-05 06:57:03 +04:00
rule . owner_operation = operation ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
2004-03-11 09:35:37 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_GROUP ) = = 0 ) {
strlcpy ( rule . group , value , sizeof ( rule . group ) ) ;
2005-06-05 06:57:03 +04:00
rule . group_operation = operation ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
2004-03-11 09:35:37 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_MODE ) = = 0 ) {
rule . mode = strtol ( value , NULL , 8 ) ;
2005-06-05 06:57:03 +04:00
rule . mode_operation = operation ;
2004-09-11 07:54:04 +04:00
valid = 1 ;
2005-04-02 19:45:35 +04:00
continue ;
}
if ( strcasecmp ( key , KEY_RUN ) = = 0 ) {
strlcpy ( rule . run , value , sizeof ( rule . run ) ) ;
2005-06-05 06:57:03 +04:00
rule . run_operation = operation ;
2005-04-02 19:45:35 +04:00
valid = 1 ;
2004-03-11 09:35:37 +03:00
continue ;
}
2005-03-13 07:46:31 +03:00
if ( strcasecmp ( key , KEY_OPTIONS ) = = 0 ) {
if ( strstr ( value , OPTION_LAST_RULE ) ! = NULL ) {
2005-03-13 00:55:08 +03:00
dbg ( " last rule to be applied " ) ;
rule . last_rule = 1 ;
}
2005-03-13 07:46:31 +03:00
if ( strstr ( value , OPTION_IGNORE_DEVICE ) ! = NULL ) {
2005-03-13 00:36:32 +03:00
dbg ( " device should be ignored " ) ;
rule . ignore_device = 1 ;
2005-02-14 08:03:06 +03:00
}
2005-03-13 07:46:31 +03:00
if ( strstr ( value , OPTION_IGNORE_REMOVE ) ! = NULL ) {
2005-03-13 00:36:32 +03:00
dbg ( " remove event should be ignored " ) ;
rule . ignore_remove = 1 ;
2005-02-14 08:03:06 +03:00
}
2005-03-13 07:46:31 +03:00
if ( strstr ( value , OPTION_PARTITIONS ) ! = NULL ) {
2005-03-13 00:36:32 +03:00
dbg ( " creation of partition nodes requested " ) ;
rule . partitions = DEFAULT_PARTITIONS_COUNT ;
2005-02-14 08:03:06 +03:00
}
valid = 1 ;
continue ;
}
2005-03-27 03:11:03 +04:00
err ( " unknown key '%s' " , key ) ;
2004-01-13 10:08:43 +03:00
goto error ;
2003-12-17 10:36:19 +03:00
}
2004-09-11 07:54:04 +04:00
/* skip line if not any valid key was found */
if ( ! valid )
goto error ;
2005-03-13 00:36:32 +03:00
if ( ( rule . result [ 0 ] ! = ' \0 ' ) & & ( program_given = = 0 ) ) {
2005-03-27 03:11:03 +04:00
info ( KEY_RESULT " is only useful when " KEY_PROGRAM " is called in any rule before " ) ;
2003-12-17 10:36:19 +03:00
goto error ;
2003-12-03 05:38:30 +03:00
}
2005-03-13 00:36:32 +03:00
rule . config_line = lineno ;
strlcpy ( rule . config_file , filename , sizeof ( rule . config_file ) ) ;
retval = add_config_dev ( & rule ) ;
2003-12-03 05:38:30 +03:00
if ( retval ) {
dbg ( " add_config_dev returned with error %d " , retval ) ;
2003-12-17 10:36:19 +03:00
continue ;
[PATCH] udev - drop all methods :)
> Hi,
> as promised yesterday, here is a patch that drops the explicit methods
> given in the udev config and implement only one type of rule.
>
> A rule now consists only of a number of keys to match. All known keys
> are valid in any combination. The former configs should work with a few
> changes:
>
> o the "<METHOD>, " at the beginning of the line should be removed
>
> o the result of the externel program is matched with RESULT= instead if ID=
> the PROGRAM= key is only valid if the program exits with zero
> (just exit with nozero in a script if the rule should not match)
>
> o rules are processed in order they appear in the file, no priority
>
> o if NAME="" is given, udev is instructed to ignore this device,
> no node will be created
>
>
> EXAMPLE:
>
> # combined BUS, SYSFS and KERNEL
> BUS="usb", KERNEL="video*", SYSFS_model="Creative Labs WebCam*", NAME="test/webcam%n"
>
> # exec script only for the first ide drive (hda), all other will be skipped
> BUS="ide", KERNEL="hda*", PROGRAM="/home/kay/src/udev.kay/extras/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c"
>
>
> The udev-test.pl and test.block works fine here.
> Please adapt your config and give it a try.
>
Here is a slightly better version of the patch.
After a conversation with Patrick, we are now able to execute the PROGRAM
and also match in all following rules with the RESULT value from this exec.
EXAMPLE:
We have 7 rules with RESULT and 2 with PROGRAM.
Only the 5th rule matches with the callout result from the exec in the 4th rule.
RULES:
PROGRAM="/bin/echo abc", RESULT="no_match", NAME="web-no-2"
KERNEL="video*", RESULT="123", NAME="web-no-3"
KERNEL="video*", RESULT="123", NAME="web-no-4"
PROGRAM="/bin/echo 123", RESULT="no_match", NAME="web-no-5"
KERNEL="video*", RESULT="123", NAME="web-yes"
RESULT:
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM
Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo abc'
Jan 11 23:36:52 pim udev[26050]: execute_program: result is 'abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM
Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo 123'
Jan 11 23:36:52 pim udev[26050]: execute_program: result is '123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='123'
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT matches
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: found matching rule, 'video*' becomes ''
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: name, 'web-yes' is going to have owner='', group='', mode = 0600
2004-01-13 08:39:05 +03:00
error :
2005-03-27 03:11:03 +04:00
err ( " parse error %s, line %d:%d, rule skipped " ,
2005-03-13 07:46:31 +03:00
filename , lineno , ( int ) ( linepos - line ) ) ;
2003-12-03 05:38:30 +03:00
}
}
2004-03-23 09:22:20 +03:00
file_unmap ( buf , bufsize ) ;
2003-12-03 05:38:30 +03:00
return retval ;
2003-12-17 10:36:19 +03:00
}
2003-12-03 05:38:30 +03:00
2005-03-13 00:36:32 +03:00
int udev_rules_init ( void )
2003-12-03 05:38:30 +03:00
{
2004-12-18 13:34:17 +03:00
struct stat stats ;
int retval ;
2003-12-03 05:38:30 +03:00
2004-12-18 13:34:17 +03:00
if ( stat ( udev_rules_filename , & stats ) ! = 0 )
2004-03-23 09:22:20 +03:00
return - 1 ;
2003-12-03 05:38:30 +03:00
2004-02-24 06:31:14 +03:00
if ( ( stats . st_mode & S_IFMT ) ! = S_IFDIR )
2005-03-17 11:59:32 +03:00
retval = rules_parse ( udev_rules_filename ) ;
else {
struct name_entry * name_loop , * name_tmp ;
LIST_HEAD ( name_list ) ;
retval = add_matching_files ( & name_list , udev_rules_filename , RULEFILE_SUFFIX ) ;
list_for_each_entry_safe ( name_loop , name_tmp , & name_list , node ) {
rules_parse ( name_loop - > name ) ;
list_del ( & name_loop - > node ) ;
}
}
2004-02-24 06:31:14 +03:00
2004-12-18 13:34:17 +03:00
return retval ;
2004-02-24 06:31:14 +03:00
}
2005-02-09 10:43:18 +03:00
2005-03-13 00:36:32 +03:00
void udev_rules_close ( void )
2005-02-09 10:43:18 +03:00
{
2005-03-13 00:36:32 +03:00
struct udev_rule * rule ;
struct udev_rule * temp_rule ;
2005-02-09 10:43:18 +03:00
2005-03-13 00:36:32 +03:00
list_for_each_entry_safe ( rule , temp_rule , & udev_rule_list , node ) {
list_del ( & rule - > node ) ;
free ( rule ) ;
2005-02-09 10:43:18 +03:00
}
}