[PATCH] pattern matching for namedev
As promised yesterday, here is a patch to implement a more advanced pattern matching instead of the simple '*'. We can remove the "tty"="tty" line from udev.rules now and replace "tty*" by "tty[0-9]*" to catch only the vc's. implement pattern matching in namedev '*' - to match zero or more chars '?' - to match exactly one char '[]' - character classes with ranges '[0-9]'and negation [!A]
This commit is contained in:
parent
4865de4429
commit
9f1da36138
67
namedev.c
67
namedev.c
|
@ -40,17 +40,56 @@
|
||||||
|
|
||||||
LIST_HEAD(config_device_list);
|
LIST_HEAD(config_device_list);
|
||||||
|
|
||||||
/* s2 may end with '*' to match everything */
|
/* compare string with pattern (supports * ? [0-9] [!A-Z]) */
|
||||||
static int strncmp_wildcard(char *s1, char *s2, int max)
|
static int strcmp_pattern(const char *p, const char *s)
|
||||||
{
|
{
|
||||||
int len = strlen(s2);
|
if (*s == '\0') {
|
||||||
if (len > max)
|
while (*p == '*')
|
||||||
len = max;
|
p++;
|
||||||
if (s2[len-1] == '*')
|
return (*p != '\0');
|
||||||
len--;
|
}
|
||||||
else
|
switch (*p) {
|
||||||
len = max;
|
case '[':
|
||||||
return strncmp(s1, s2, len);
|
{
|
||||||
|
int not = 0;
|
||||||
|
p++;
|
||||||
|
if (*p == '!') {
|
||||||
|
not = 1;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
while (*p && (*p != ']')) {
|
||||||
|
int match = 0;
|
||||||
|
if (p[1] == '-') {
|
||||||
|
if ((*s >= *p) && (*s <= p[2]))
|
||||||
|
match = 1;
|
||||||
|
p += 3;
|
||||||
|
} else {
|
||||||
|
match = (*p == *s);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (match ^ not) {
|
||||||
|
while (*p && (*p != ']'))
|
||||||
|
p++;
|
||||||
|
return strcmp_pattern(p+1, s+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
if (strcmp_pattern(p, s+1))
|
||||||
|
return strcmp_pattern(p+1, s);
|
||||||
|
return 0;
|
||||||
|
case '\0':
|
||||||
|
if (*s == '\0') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((*p == *s) || (*p == '?'))
|
||||||
|
return strcmp_pattern(p+1, s+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define copy_var(a, b, var) \
|
#define copy_var(a, b, var) \
|
||||||
|
@ -69,7 +108,7 @@ int add_config_dev(struct config_device *new_dev)
|
||||||
/* update the values if we already have the device */
|
/* update the values if we already have the device */
|
||||||
list_for_each(tmp, &config_device_list) {
|
list_for_each(tmp, &config_device_list) {
|
||||||
struct config_device *dev = list_entry(tmp, struct config_device, node);
|
struct config_device *dev = list_entry(tmp, struct config_device, node);
|
||||||
if (strncmp_wildcard(dev->name, new_dev->name, sizeof(dev->name)))
|
if (strcmp_pattern(new_dev->name, dev->name))
|
||||||
continue;
|
continue;
|
||||||
if (strncmp(dev->bus, new_dev->bus, sizeof(dev->name)))
|
if (strncmp(dev->bus, new_dev->bus, sizeof(dev->name)))
|
||||||
continue;
|
continue;
|
||||||
|
@ -282,7 +321,7 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev
|
||||||
apply_format(udev, dev->exec_program);
|
apply_format(udev, dev->exec_program);
|
||||||
if (exec_callout(dev, udev->callout_value, NAME_SIZE))
|
if (exec_callout(dev, udev->callout_value, NAME_SIZE))
|
||||||
continue;
|
continue;
|
||||||
if (strncmp_wildcard(udev->callout_value, dev->id, NAME_SIZE) != 0)
|
if (strcmp_pattern(dev->id, udev->callout_value) != 0)
|
||||||
continue;
|
continue;
|
||||||
strfieldcpy(udev->name, dev->name);
|
strfieldcpy(udev->name, dev->name);
|
||||||
if (dev->mode != 0) {
|
if (dev->mode != 0) {
|
||||||
|
@ -468,7 +507,7 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name);
|
dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name);
|
||||||
if (strncmp_wildcard(class_dev->name, dev->kernel_name, NAME_SIZE) != 0)
|
if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strfieldcpy(udev->name, dev->name);
|
strfieldcpy(udev->name, dev->name);
|
||||||
|
@ -498,7 +537,7 @@ static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice *
|
||||||
list_for_each(tmp, &config_device_list) {
|
list_for_each(tmp, &config_device_list) {
|
||||||
dev = list_entry(tmp, struct config_device, node);
|
dev = list_entry(tmp, struct config_device, node);
|
||||||
len = strlen(dev->name);
|
len = strlen(dev->name);
|
||||||
if (strncmp_wildcard(class_dev->name, dev->name, sizeof(dev->name)))
|
if (strcmp_pattern(dev->name, class_dev->name))
|
||||||
continue;
|
continue;
|
||||||
if (dev->mode != 0) {
|
if (dev->mode != 0) {
|
||||||
dbg("found permissions for '%s'", class_dev->name);
|
dbg("found permissions for '%s'", class_dev->name);
|
||||||
|
|
|
@ -51,12 +51,34 @@ LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n"
|
||||||
EOF
|
EOF
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc => "catch device by wildcard",
|
desc => "catch device by *",
|
||||||
subsys => "tty",
|
subsys => "tty",
|
||||||
devpath => "class/tty/ttyUSB0",
|
devpath => "class/tty/ttyUSB0",
|
||||||
expected => "visor/0" ,
|
expected => "visor/0" ,
|
||||||
conf => <<EOF
|
conf => <<EOF
|
||||||
REPLACE, KERNEL="ttyUSB*", NAME="visor/%n"
|
REPLACE, KERNEL="ttyUSB*", NAME="visor/%n"
|
||||||
|
EOF
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc => "catch device by ?",
|
||||||
|
subsys => "tty",
|
||||||
|
devpath => "class/tty/ttyUSB0",
|
||||||
|
expected => "visor/0" ,
|
||||||
|
conf => <<EOF
|
||||||
|
REPLACE, KERNEL="ttyUSB??*", NAME="visor/%n-1"
|
||||||
|
REPLACE, KERNEL="ttyUSB??", NAME="visor/%n-2"
|
||||||
|
REPLACE, KERNEL="ttyUSB?", NAME="visor/%n"
|
||||||
|
EOF
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc => "catch device by character class",
|
||||||
|
subsys => "tty",
|
||||||
|
devpath => "class/tty/ttyUSB0",
|
||||||
|
expected => "visor/0" ,
|
||||||
|
conf => <<EOF
|
||||||
|
REPLACE, KERNEL="ttyUSB[A-Z]*", NAME="visor/%n-1"
|
||||||
|
REPLACE, KERNEL="ttyUSB?[0-9]", NAME="visor/%n-2"
|
||||||
|
REPLACE, KERNEL="ttyUSB[0-9]*", NAME="visor/%n"
|
||||||
EOF
|
EOF
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -96,7 +118,7 @@ TOPOLOGY, BUS="scsi", PLACE="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:b
|
||||||
EOF
|
EOF
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc => "callout result substitution, only last should match",
|
desc => "callout result substitution",
|
||||||
subsys => "block",
|
subsys => "block",
|
||||||
devpath => "block/sda/sda3",
|
devpath => "block/sda/sda3",
|
||||||
expected => "special-device-3" ,
|
expected => "special-device-3" ,
|
||||||
|
|
Loading…
Reference in New Issue