chiark / gitweb /
[PATCH] support =, ==, !=, += for the key match and assignment
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Sun, 13 Mar 2005 04:46:31 +0000 (05:46 +0100)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 06:53:17 +0000 (23:53 -0700)
RELEASE-NOTES
test/udev-test.pl
udev.8.in
udev_config.c
udev_rules.c
udev_rules.h
udev_rules_parse.c
udev_utils.c

index 870020c430f8de34f0bfa2194f8043d7ac2c5c64..ee77d845be3733975d166c473bbaf4845bf927b6 100644 (file)
@@ -8,3 +8,13 @@ a built-in userdb parser to resolve user and group names.
 THE PLACE= key is gone. It can be replaced by an ID= for a long time, cause
 we walk up the chain of physical devices to find a match.
 
 THE PLACE= key is gone. It can be replaced by an ID= for a long time, cause
 we walk up the chain of physical devices to find a match.
 
+The KEY="<value>" format supports '=', '==', '!=,' , '+=' now. This makes it
+easier to skip certain devices without composing rules with weird character
+class negations like:
+  KERNEL="[!s][!c][!d]*"
+
+this can be replaced by:
+  KERNEL!="scd*"
+
+The simple '=' is still supported, but the rules should be converted if
+possible, to be better human-readable.
index 52c5c8d481832ef12e6715ef2041f714bf974b4e..8d66536b94462880fde4950e7146b6ccaf77ef01 100644 (file)
@@ -39,8 +39,8 @@ my @tests = (
                devpath         => "/block/sda",
                exp_name        => "boot_disk" ,
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "boot_disk" ,
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="boot_disk%n"
-KERNEL="ttyUSB0", NAME="visor"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", NAME="boot_disk%n"
+KERNEL=="ttyUSB0", NAME="visor"
 EOF
        },
        {
 EOF
        },
        {
@@ -49,7 +49,7 @@ EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="boot_disk%n"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", NAME="boot_disk%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -58,10 +58,10 @@ EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="?IBM-ESXS", NAME="boot_disk%n-1"
-BUS="scsi", SYSFS{vendor}="IBM-ESXS?", NAME="boot_disk%n-2"
-BUS="scsi", SYSFS{vendor}="IBM-ES??", NAME="boot_disk%n"
-BUS="scsi", SYSFS{vendor}="IBM-ESXSS", NAME="boot_disk%n-3"
+BUS=="scsi", SYSFS{vendor}=="?IBM-ESXS", NAME="boot_disk%n-1"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS?", NAME="boot_disk%n-2"
+BUS=="scsi", SYSFS{vendor}=="IBM-ES??", NAME="boot_disk%n"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXSS", NAME="boot_disk%n-3"
 EOF
        },
        {
 EOF
        },
        {
@@ -70,8 +70,8 @@ EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW   !#", NAME="boot_diskX%n"
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW    !#", NAME="boot_disk%n"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", SYSFS{model}=="ST336605LW   !#", NAME="boot_diskX%n"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", SYSFS{model}=="ST336605LW    !#", NAME="boot_disk%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -80,8 +80,8 @@ EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "boot_disk1" ,
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW    !#", SYSFS{scsi_level}="4", SYSFS{rev}="B245", SYSFS{type}="2", SYSFS{queue_depth}="32", NAME="boot_diskXX%n"
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW    !#", SYSFS{scsi_level}="4", SYSFS{rev}="B245", SYSFS{type}="0", NAME="boot_disk%n"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", SYSFS{model}=="ST336605LW    !#", SYSFS{scsi_level}=="4", SYSFS{rev}=="B245", SYSFS{type}=="2", SYSFS{queue_depth}=="32", NAME="boot_diskXX%n"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", SYSFS{model}=="ST336605LW    !#", SYSFS{scsi_level}=="4", SYSFS{rev}=="B245", SYSFS{type}=="0", NAME="boot_disk%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -90,7 +90,7 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor/0" ,
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor/0" ,
                conf            => <<EOF
-KERNEL="ttyUSB*", NAME="visor/%n"
+KERNEL=="ttyUSB*", NAME="visor/%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -99,8 +99,8 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor/0" ,
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor/0" ,
                conf            => <<EOF
-KERNEL="*USB1", NAME="bad"
-KERNEL="*USB0", NAME="visor/%n"
+KERNEL=="*USB1", NAME="bad"
+KERNEL=="*USB0", NAME="visor/%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -109,9 +109,9 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor/0" ,
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor/0" ,
                conf            => <<EOF
-KERNEL="ttyUSB??*", NAME="visor/%n-1"
-KERNEL="ttyUSB??", NAME="visor/%n-2"
-KERNEL="ttyUSB?", NAME="visor/%n"
+KERNEL=="ttyUSB??*", NAME="visor/%n-1"
+KERNEL=="ttyUSB??", NAME="visor/%n-2"
+KERNEL=="ttyUSB?", NAME="visor/%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -120,9 +120,9 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor/0" ,
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor/0" ,
                conf            => <<EOF
-KERNEL="ttyUSB[A-Z]*", NAME="visor/%n-1"
-KERNEL="ttyUSB?[0-9]", NAME="visor/%n-2"
-KERNEL="ttyUSB[0-9]*", NAME="visor/%n"
+KERNEL=="ttyUSB[A-Z]*", NAME="visor/%n-1"
+KERNEL=="ttyUSB?[0-9]", NAME="visor/%n-2"
+KERNEL=="ttyUSB[0-9]*", NAME="visor/%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -131,7 +131,7 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor" ,
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor" ,
                conf            => <<EOF
-KERNEL="ttyUSB0", NAME="visor"
+KERNEL=="ttyUSB0", NAME="visor"
 EOF
        },
        {
 EOF
        },
        {
@@ -141,7 +141,7 @@ EOF
                exp_name        => "visor" ,
                conf            => <<EOF
 # this is a comment
                exp_name        => "visor" ,
                conf            => <<EOF
 # this is a comment
-KERNEL="ttyUSB0", NAME="visor"
+KERNEL=="ttyUSB0", NAME="visor"
 
 EOF
        },
 
 EOF
        },
@@ -152,7 +152,7 @@ EOF
                exp_name        => "visor" ,
                conf            => <<EOF
  # this is a comment with whitespace before the comment 
                exp_name        => "visor" ,
                conf            => <<EOF
  # this is a comment with whitespace before the comment 
-KERNEL="ttyUSB0", NAME="visor"
+KERNEL=="ttyUSB0", NAME="visor"
 
 EOF
        },
 
 EOF
        },
@@ -166,7 +166,7 @@ EOF
  
 
  # this is a comment with whitespace before the comment 
  
 
  # this is a comment with whitespace before the comment 
-KERNEL="ttyUSB0", NAME="whitespace"
+KERNEL=="ttyUSB0", NAME="whitespace"
 
  
 
 
  
 
@@ -179,7 +179,7 @@ EOF
                exp_name        => "visor" ,
                conf            => <<EOF
 
                exp_name        => "visor" ,
                conf            => <<EOF
 
-KERNEL="ttyUSB0", NAME="visor"
+KERNEL=="ttyUSB0", NAME="visor"
 
 EOF
        },
 
 EOF
        },
@@ -189,7 +189,7 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor" ,
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor" ,
                conf            => <<EOF
-KERNEL="ttyUSB0", \\
+KERNEL=="ttyUSB0", \\
 NAME="visor"
 
 EOF
 NAME="visor"
 
 EOF
@@ -200,7 +200,7 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "aaa",
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "aaa",
                conf            => <<EOF
-KERNEL="ttyUSB0", PROGRAM="/bin/echo -e \\101", RESULT="A", NAME="aaa"
+KERNEL=="ttyUSB0", PROGRAM=="/bin/echo -e \\101", RESULT=="A", NAME="aaa"
 EOF
        },
        {
 EOF
        },
        {
@@ -217,7 +217,7 @@ EOF
 
 #\\
 
 
 #\\
 
-KERNEL="ttyUSB0", \\
+KERNEL=="ttyUSB0", \\
        NAME="visor"
 
 EOF
        NAME="visor"
 
 EOF
@@ -228,7 +228,7 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "sub/direct/ory/visor" ,
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "sub/direct/ory/visor" ,
                conf            => <<EOF
-KERNEL="ttyUSB0", NAME="sub/direct/ory/visor"
+KERNEL=="ttyUSB0", NAME="sub/direct/ory/visor"
 EOF
        },
        {
 EOF
        },
        {
@@ -237,7 +237,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "first_disk3" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "first_disk3" ,
                conf            => <<EOF
-BUS="scsi", ID="0:0:0:0", NAME="first_disk%n"
+BUS=="scsi", ID=="0:0:0:0", NAME="first_disk%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -246,7 +246,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" ,
                conf            => <<EOF
-BUS="scsi", ID="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b"
+BUS=="scsi", ID=="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b"
 EOF
        },
        {
 EOF
        },
        {
@@ -255,7 +255,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "M8-m3-n3-b0:0-sIBM" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "M8-m3-n3-b0:0-sIBM" ,
                conf            => <<EOF
-BUS="scsi", ID="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}"
+BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}"
 EOF
        },
        {
 EOF
        },
        {
@@ -264,7 +264,7 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "good" ,
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "good" ,
                conf            => <<EOF
-BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="good"
+BUS=="scsi", SYSFS_vendor=="IBM-ESXS", NAME="good"
 EOF
        },
        {
 EOF
        },
        {
@@ -273,8 +273,8 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "disk-IBM-ESXS-sda" ,
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "disk-IBM-ESXS-sda" ,
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="disk-%s{vendor}-%k"
-KERNEL="ttyUSB0", NAME="visor"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", NAME="disk-%s{vendor}-%k"
+KERNEL=="ttyUSB0", NAME="visor"
 EOF
        },
        {
 EOF
        },
        {
@@ -283,11 +283,11 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "special-device-3" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "special-device-3" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="-special-*", NAME="%c-1-%n"
-BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special--*", NAME="%c-2-%n"
-BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-device-", NAME="%c-3-%n"
-BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-devic", NAME="%c-4-%n"
-BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-*", NAME="%c-%n"
+BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="-special-*", NAME="%c-1-%n"
+BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special--*", NAME="%c-2-%n"
+BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-device-", NAME="%c-3-%n"
+BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-devic", NAME="%c-4-%n"
+BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-*", NAME="%c-%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -296,7 +296,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "subsys_block" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "subsys_block" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo", RESULT="block", NAME="subsys_block"
+BUS=="scsi", PROGRAM=="/bin/echo", RESULT=="block", NAME="subsys_block"
 EOF
        },
        {
 EOF
        },
        {
@@ -305,7 +305,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "newline_removed" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "newline_removed" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo test", RESULT="test", NAME="newline_removed"
+BUS=="scsi", PROGRAM=="/bin/echo test", RESULT=="test", NAME="newline_removed"
 EOF
        },
        {
 EOF
        },
        {
@@ -314,7 +314,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "test-0:0:0:0" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "test-0:0:0:0" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-0:0*", NAME="%c"
+BUS=="scsi", PROGRAM=="/bin/echo -n test-%b", RESULT=="test-0:0*", NAME="%c"
 EOF
        },
        {
 EOF
        },
        {
@@ -323,7 +323,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "escape-3" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "escape-3" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n escape-%%n", KERNEL="sda3", NAME="%c"
+BUS=="scsi", PROGRAM=="/bin/echo -n escape-%%n", KERNEL=="sda3", NAME="%c"
 EOF
        },
        {
 EOF
        },
        {
@@ -332,7 +332,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "foo9" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "foo9" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL="sda3", NAME="%c{7}"
+BUS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda3", NAME="%c{7}"
 EOF
        },
        {
 EOF
        },
        {
@@ -341,7 +341,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "bar9" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "bar9" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/sh -c 'echo foo3 foo4 foo5 foo6 foo7 foo8 foo9 | sed  s/foo9/bar9/'", KERNEL="sda3", NAME="%c{7}"
+BUS=="scsi", PROGRAM=="/bin/sh -c 'echo foo3 foo4 foo5 foo6 foo7 foo8 foo9 | sed  s/foo9/bar9/'", KERNEL=="sda3", NAME="%c{7}"
 EOF
        },
        {
 EOF
        },
        {
@@ -350,7 +350,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "foo7" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "foo7" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n 'foo3 foo4'   'foo5   foo6   foo7 foo8'", KERNEL="sda3", NAME="%c{5}"
+BUS=="scsi", PROGRAM=="/bin/echo -n 'foo3 foo4'   'foo5   foo6   foo7 foo8'", KERNEL=="sda3", NAME="%c{5}"
 EOF
        },
        {
 EOF
        },
        {
@@ -359,7 +359,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "my-foo9" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "my-foo9" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL="sda3", NAME="my-%c{7}"
+BUS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda3", NAME="my-%c{7}"
 EOF
        },
        {
 EOF
        },
        {
@@ -368,7 +368,7 @@ EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "my-foo8" ,
                conf            => <<EOF
                devpath         => "/block/sda/sda3",
                exp_name        => "my-foo8" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL="sda3", NAME="my-%c{6}"
+BUS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda3", NAME="my-%c{6}"
 EOF
        },
        {
 EOF
        },
        {
@@ -377,8 +377,8 @@ EOF
                devpath         => "/class/tty/console",
                exp_name        => "TTY" ,
                conf            => <<EOF
                devpath         => "/class/tty/console",
                exp_name        => "TTY" ,
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n foo", RESULT="foo", NAME="foo"
-KERNEL="console", NAME="TTY"
+BUS=="scsi", PROGRAM=="/bin/echo -n foo", RESULT=="foo", NAME="foo"
+KERNEL=="console", NAME="TTY"
 EOF
        },
        {
 EOF
        },
        {
@@ -387,8 +387,8 @@ EOF
                devpath         => "/class/tty/console",
                exp_name        => "foo" ,
                conf            => <<EOF
                devpath         => "/class/tty/console",
                exp_name        => "foo" ,
                conf            => <<EOF
-PROGRAM="/bin/echo -n foo", RESULT="foo", NAME="foo"
-KERNEL="console", NAME="TTY"
+PROGRAM=="/bin/echo -n foo", RESULT=="foo", NAME="foo"
+KERNEL=="console", NAME="TTY"
 EOF
        },
        {
 EOF
        },
        {
@@ -397,8 +397,8 @@ EOF
                devpath         => "/class/tty/console",
                exp_name        => "TTY" ,
                conf            => <<EOF
                devpath         => "/class/tty/console",
                exp_name        => "TTY" ,
                conf            => <<EOF
-BUS="foo", SYSFS{dev}="5:1", NAME="foo"
-KERNEL="console", NAME="TTY"
+BUS=="foo", SYSFS{dev}=="5:1", NAME="foo"
+KERNEL=="console", NAME="TTY"
 EOF
        },
        {
 EOF
        },
        {
@@ -407,8 +407,8 @@ EOF
                devpath         => "/class/tty/console",
                exp_name        => "foo" ,
                conf            => <<EOF
                devpath         => "/class/tty/console",
                exp_name        => "foo" ,
                conf            => <<EOF
-SYSFS{dev}="5:1", NAME="foo"
-KERNEL="console", NAME="TTY"
+SYSFS{dev}=="5:1", NAME="foo"
+KERNEL=="console", NAME="TTY"
 EOF
        },
        {
 EOF
        },
        {
@@ -417,9 +417,9 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0" ,
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0" ,
                conf            => <<EOF
-BUS="usb", PROGRAM="/bin/echo -n usb-%b", NAME="%c"
-BUS="scsi", PROGRAM="/bin/echo -n scsi-%b", NAME="%c"
-BUS="foo", PROGRAM="/bin/echo -n foo-%b", NAME="%c"
+BUS=="usb", PROGRAM=="/bin/echo -n usb-%b", NAME="%c"
+BUS=="scsi", PROGRAM=="/bin/echo -n scsi-%b", NAME="%c"
+BUS=="foo", PROGRAM=="/bin/echo -n foo-%b", NAME="%c"
 EOF
        },
        {
 EOF
        },
        {
@@ -428,7 +428,7 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "boot_disk15" ,
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "boot_disk15" ,
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME{all_partitions}="boot_disk"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", NAME{all_partitions}="boot_disk"
 EOF
        },
        {
 EOF
        },
        {
@@ -437,7 +437,7 @@ EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor" ,
                conf            => <<EOF
                devpath         => "/class/tty/ttyUSB0",
                exp_name        => "visor" ,
                conf            => <<EOF
-SYSFS{idProduct}="2008", NAME="visor"
+SYSFS{idProduct}=="2008", NAME="visor"
 EOF
        },
        {
 EOF
        },
        {
@@ -446,8 +446,8 @@ EOF
                devpath         => "/block/rd!c0d0",
                exp_name        => "rd/c0d0" ,
                conf            => <<EOF
                devpath         => "/block/rd!c0d0",
                exp_name        => "rd/c0d0" ,
                conf            => <<EOF
-BUS="scsi", NAME="%k"
-KERNEL="ttyUSB0", NAME="visor"
+BUS=="scsi", NAME="%k"
+KERNEL=="ttyUSB0", NAME="visor"
 EOF
        },
        {
 EOF
        },
        {
@@ -456,7 +456,7 @@ EOF
                devpath         => "/block/rd!c0d0",
                exp_name        => "rd/c0d0" ,
                conf            => <<EOF
                devpath         => "/block/rd!c0d0",
                exp_name        => "rd/c0d0" ,
                conf            => <<EOF
-KERNEL="ttyUSB0", NAME="visor"
+KERNEL=="ttyUSB0", NAME="visor"
 EOF
        },
        {
 EOF
        },
        {
@@ -465,8 +465,8 @@ EOF
                devpath         => "/block/cciss!c0d0/cciss!c0d0p1",
                exp_name        => "cciss/c0d0p1" ,
                conf            => <<EOF
                devpath         => "/block/cciss!c0d0/cciss!c0d0p1",
                exp_name        => "cciss/c0d0p1" ,
                conf            => <<EOF
-BUS="scsi", NAME="%k"
-KERNEL="ttyUSB0", NAME="visor"
+BUS=="scsi", NAME="%k"
+KERNEL=="ttyUSB0", NAME="visor"
 EOF
        },
        {
 EOF
        },
        {
@@ -475,11 +475,11 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0",
                conf            => <<EOF
-BUS="usb", ID="0:0:0:0", NAME="not-scsi"
-BUS="scsi", ID="0:0:0:1", NAME="no-match"
-BUS="scsi", ID=":0", NAME="short-id"
-BUS="scsi", ID="/0:0:0:0", NAME="no-match"
-BUS="scsi", ID="0:0:0:0", NAME="scsi-0:0:0:0"
+BUS=="usb", ID=="0:0:0:0", NAME="not-scsi"
+BUS=="scsi", ID=="0:0:0:1", NAME="no-match"
+BUS=="scsi", ID==":0", NAME="short-id"
+BUS=="scsi", ID=="/0:0:0:0", NAME="no-match"
+BUS=="scsi", ID=="0:0:0:0", NAME="scsi-0:0:0:0"
 EOF
        },
        {
 EOF
        },
        {
@@ -488,11 +488,11 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0",
                conf            => <<EOF
-BUS="scsi", ID="*:1", NAME="no-match"
-BUS="scsi", ID="*:0:1", NAME="no-match"
-BUS="scsi", ID="*:0:0:1", NAME="no-match"
-BUS="scsi", ID="*", NAME="scsi-0:0:0:0"
-BUS="scsi", ID="0:0:0:0", NAME="bad"
+BUS=="scsi", ID=="*:1", NAME="no-match"
+BUS=="scsi", ID=="*:0:1", NAME="no-match"
+BUS=="scsi", ID=="*:0:0:1", NAME="no-match"
+BUS=="scsi", ID=="*", NAME="scsi-0:0:0:0"
+BUS=="scsi", ID=="0:0:0:0", NAME="bad"
 EOF
        },
        {
 EOF
        },
        {
@@ -501,8 +501,8 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0",
                conf            => <<EOF
-BUS="scsi", ID="*:0", NAME="scsi-0:0:0:0"
-BUS="scsi", ID="0:0:0:0", NAME="bad"
+BUS=="scsi", ID=="*:0", NAME="scsi-0:0:0:0"
+BUS=="scsi", ID=="0:0:0:0", NAME="bad"
 EOF
        },
        {
 EOF
        },
        {
@@ -511,8 +511,8 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "scsi-0:0:0:0",
                conf            => <<EOF
-BUS="scsi", ID="*:0:0:0", NAME="scsi-0:0:0:0"
-BUS="scsi", ID="0:0:0:0", NAME="bad"
+BUS=="scsi", ID=="*:0:0:0", NAME="scsi-0:0:0:0"
+BUS=="scsi", ID=="0:0:0:0", NAME="bad"
 EOF
        },
        {
 EOF
        },
        {
@@ -521,7 +521,7 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "ignored",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "ignored",
                conf            => <<EOF
-BUS="scsi", SYSFS{whitespace_test}="WHITE  SPACE", NAME="ignored"
+BUS=="scsi", SYSFS{whitespace_test}=="WHITE  SPACE", NAME="ignored"
 EOF
        },
        {
 EOF
        },
        {
@@ -530,8 +530,8 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "matched-with-space",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "matched-with-space",
                conf            => <<EOF
-BUS="scsi", SYSFS{whitespace_test}="WHITE  SPACE ", NAME="wrong-to-ignore"
-BUS="scsi", SYSFS{whitespace_test}="WHITE  SPACE   ", NAME="matched-with-space"
+BUS=="scsi", SYSFS{whitespace_test}=="WHITE  SPACE ", NAME="wrong-to-ignore"
+BUS=="scsi", SYSFS{whitespace_test}=="WHITE  SPACE   ", NAME="matched-with-space"
 EOF
        },
        {
 EOF
        },
        {
@@ -541,7 +541,7 @@ EOF
                exp_name        => "tty33",
                exp_perms       => "0:0:0660",
                conf            => <<EOF
                exp_name        => "tty33",
                exp_perms       => "0:0:0660",
                conf            => <<EOF
-KERNEL="tty33", NAME="tty33", OWNER="bad", GROUP="name"
+KERNEL=="tty33", NAME="tty33", OWNER="bad", GROUP="name"
 EOF
        },
        {
 EOF
        },
        {
@@ -551,7 +551,7 @@ EOF
                exp_name        => "node",
                exp_perms       => "5000::0660",
                conf            => <<EOF
                exp_name        => "node",
                exp_perms       => "5000::0660",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node", OWNER="5000"
+BUS=="scsi", KERNEL=="sda", NAME="node", OWNER="5000"
 EOF
        },
        {
 EOF
        },
        {
@@ -561,7 +561,7 @@ EOF
                exp_name        => "node",
                exp_perms       => ":100:0660",
                conf            => <<EOF
                exp_name        => "node",
                exp_perms       => ":100:0660",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node", GROUP="100"
+BUS=="scsi", KERNEL=="sda", NAME="node", GROUP="100"
 EOF
        },
        {
 EOF
        },
        {
@@ -571,7 +571,7 @@ EOF
                exp_name        => "node",
                exp_perms       => "::0777",
                conf            => <<EOF
                exp_name        => "node",
                exp_perms       => "::0777",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node", MODE="0777"
+BUS=="scsi", KERNEL=="sda", NAME="node", MODE="0777"
 EOF
        },
        {
 EOF
        },
        {
@@ -581,7 +581,7 @@ EOF
                exp_name        => "node",
                exp_perms       => "5000:100:0777",
                conf            => <<EOF
                exp_name        => "node",
                exp_perms       => "5000:100:0777",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node", OWNER="5000", GROUP="100", MODE="0777"
+BUS=="scsi", KERNEL=="sda", NAME="node", OWNER="5000", GROUP="100", MODE="0777"
 EOF
        },
        {
 EOF
        },
        {
@@ -591,7 +591,7 @@ EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "5000::",
                conf            => <<EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "5000::",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", OWNER="5000"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", OWNER="5000"
 EOF
        },
        {
 EOF
        },
        {
@@ -601,7 +601,7 @@ EOF
                exp_name        => "ttyUSB0",
                exp_perms       => ":100:0660",
                conf            => <<EOF
                exp_name        => "ttyUSB0",
                exp_perms       => ":100:0660",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", GROUP="100"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", GROUP="100"
 EOF
        },
        {
 EOF
        },
        {
@@ -611,7 +611,7 @@ EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "::0060",
                conf            => <<EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "::0060",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", MODE="0060"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", MODE="0060"
 EOF
        },
        {
 EOF
        },
        {
@@ -621,7 +621,7 @@ EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "5000:100:0777",
                conf            => <<EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "5000:100:0777",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", OWNER="5000", GROUP="100", MODE="0777"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", OWNER="5000", GROUP="100", MODE="0777"
 EOF
        },
        {
 EOF
        },
        {
@@ -631,9 +631,9 @@ EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "5000:100:0777",
                conf            => <<EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "5000:100:0777",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", OWNER="5000", GROUP="100", MODE="0777"
-KERNEL="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n"
+KERNEL=="ttyUSB[0-9]*", OWNER="5000", GROUP="100", MODE="0777"
+KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -643,11 +643,11 @@ EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "3000:4000:0777",
                conf            => <<EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "3000:4000:0777",
                conf            => <<EOF
-SUBSYSTEM="tty", OWNER="3000"
-SUBSYSTEM="tty", GROUP="4000"
-SUBSYSTEM="tty", MODE="0777"
-KERNEL="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n"
+SUBSYSTEM=="tty", OWNER="3000"
+SUBSYSTEM=="tty", GROUP="4000"
+SUBSYSTEM=="tty", MODE="0777"
+KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -657,11 +657,11 @@ EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "3000:8000:0777",
                conf            => <<EOF
                exp_name        => "ttyUSB0",
                exp_perms       => "3000:8000:0777",
                conf            => <<EOF
-SUBSYSTEM="tty", OWNER="3000"
-SUBSYSTEM="tty", GROUP="4000"
-SUBSYSTEM="tty", MODE="0777"
-KERNEL="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", GROUP="8000"
+SUBSYSTEM=="tty", OWNER="3000"
+SUBSYSTEM=="tty", GROUP="4000"
+SUBSYSTEM=="tty", MODE="0777"
+KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", GROUP="8000"
 EOF
        },
        {
 EOF
        },
        {
@@ -671,7 +671,7 @@ EOF
                exp_name        => "node",
                exp_majorminor  => "8:0",
                conf            => <<EOF
                exp_name        => "node",
                exp_majorminor  => "8:0",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node"
+BUS=="scsi", KERNEL=="sda", NAME="node"
 EOF
        },
        {
 EOF
        },
        {
@@ -681,7 +681,7 @@ EOF
                exp_name        => "node",
                exp_majorminor  => "89:300",
                conf            => <<EOF
                exp_name        => "node",
                exp_majorminor  => "89:300",
                conf            => <<EOF
-KERNEL="i2c-300", NAME="node"
+KERNEL=="i2c-300", NAME="node"
 EOF
        },
        {
 EOF
        },
        {
@@ -691,7 +691,7 @@ EOF
                exp_name        => "node",
                exp_majorminor  => "4095:1",
                conf            => <<EOF
                exp_name        => "node",
                exp_majorminor  => "4095:1",
                conf            => <<EOF
-KERNEL="i2c-fake1", NAME="node"
+KERNEL=="i2c-fake1", NAME="node"
 EOF
        },
        {
 EOF
        },
        {
@@ -701,7 +701,7 @@ EOF
                exp_name        => "node",
                exp_majorminor  => "4094:89999",
                conf            => <<EOF
                exp_name        => "node",
                exp_majorminor  => "4094:89999",
                conf            => <<EOF
-KERNEL="i2c-fake2", NAME="node"
+KERNEL=="i2c-fake2", NAME="node"
 EOF
        },
        {
 EOF
        },
        {
@@ -711,7 +711,7 @@ EOF
                exp_name        => "symlink2-ttyUSB0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "symlink2-ttyUSB0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink1-%n symlink2-%k symlink3-%b"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink1-%n symlink2-%k symlink3-%b"
 EOF
        },
        {
 EOF
        },
        {
@@ -721,7 +721,7 @@ EOF
                exp_name        => "visor0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "visor0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="visor%n"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="visor%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -731,7 +731,7 @@ EOF
                exp_name        => "1/2/symlink" ,
                exp_target      => "a/b/node",
                conf            => <<EOF
                exp_name        => "1/2/symlink" ,
                exp_target      => "a/b/node",
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/symlink"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/symlink"
 EOF
        },
        {
 EOF
        },
        {
@@ -741,7 +741,7 @@ EOF
                exp_name        => "1/2/c/d/symlink" ,
                exp_target      => "../../a/b/node",
                conf            => <<EOF
                exp_name        => "1/2/c/d/symlink" ,
                exp_target      => "../../a/b/node",
                conf            => <<EOF
-BUS="scsi", SYSFS{vendor}="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink"
+BUS=="scsi", SYSFS{vendor}=="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink"
 EOF
        },
        {
 EOF
        },
        {
@@ -751,7 +751,7 @@ EOF
                exp_name        => "second-0" ,
                exp_target      => "visor" ,
                conf            => <<EOF
                exp_name        => "second-0" ,
                exp_target      => "visor" ,
                conf            => <<EOF
-KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"
+KERNEL=="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -761,9 +761,9 @@ EOF
                exp_name        => "symlink-only2",
                exp_target      => "link",
                conf            => <<EOF
                exp_name        => "symlink-only2",
                exp_target      => "link",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", SYMLINK="symlink-only1"
-BUS="scsi", KERNEL="sda", SYMLINK="symlink-only2"
-BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="symlink0"
+BUS=="scsi", KERNEL=="sda", SYMLINK="symlink-only1"
+BUS=="scsi", KERNEL=="sda", SYMLINK="symlink-only2"
+BUS=="scsi", KERNEL=="sda", NAME="link", SYMLINK="symlink0"
 EOF
        },
        {
 EOF
        },
        {
@@ -775,7 +775,7 @@ EOF
                exp_add_error   => "yes",
                exp_rem_error   => "yes",
                conf            => <<EOF
                exp_add_error   => "yes",
                exp_rem_error   => "yes",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="."
+BUS=="scsi", KERNEL=="sda", NAME="link", SYMLINK="."
 EOF
        },
        {
 EOF
        },
        {
@@ -787,7 +787,7 @@ EOF
                exp_rem_error   => "yes",
                option          => "clear",
                conf            => <<EOF
                exp_rem_error   => "yes",
                option          => "clear",
                conf            => <<EOF
-KERNEL="tty0", NAME="link", SYMLINK="link"
+KERNEL=="tty0", NAME="link", SYMLINK="link"
 EOF
        },
        {
 EOF
        },
        {
@@ -797,7 +797,7 @@ EOF
                exp_name        => "symlink0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "symlink0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink%n"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink%n"
 EOF
        },
        {
 EOF
        },
        {
@@ -807,7 +807,7 @@ EOF
                exp_name        => "symlink-ttyUSB0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "symlink-ttyUSB0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink-%k"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink-%k"
 EOF
        },
        {
 EOF
        },
        {
@@ -817,7 +817,7 @@ EOF
                exp_name        => "major-188:0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "major-188:0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="major-%M:%m"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="major-%M:%m"
 EOF
        },
        {
 EOF
        },
        {
@@ -827,7 +827,7 @@ EOF
                exp_name        => "symlink-0:0:0:0",
                exp_target      => "node",
                conf            => <<EOF
                exp_name        => "symlink-0:0:0:0",
                exp_target      => "node",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node", SYMLINK="symlink-%b"
+BUS=="scsi", KERNEL=="sda", NAME="node", SYMLINK="symlink-%b"
 EOF
        },
        {
 EOF
        },
        {
@@ -837,7 +837,7 @@ EOF
                exp_name        => "test",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "test",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo test" NAME="ttyUSB%n", SYMLINK="%c"
+KERNEL=="ttyUSB[0-9]*", PROGRAM=="/bin/echo test" NAME="ttyUSB%n", SYMLINK="%c"
 EOF
        },
        {
 EOF
        },
        {
@@ -847,7 +847,7 @@ EOF
                exp_name        => "test",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "test",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo symlink test this" NAME="ttyUSB%n", SYMLINK="%c{2}"
+KERNEL=="ttyUSB[0-9]*", PROGRAM=="/bin/echo symlink test this" NAME="ttyUSB%n", SYMLINK="%c{2}"
 EOF
        },
        {
 EOF
        },
        {
@@ -857,7 +857,7 @@ EOF
                exp_name        => "this",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "this",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", PROGRAM="/bin/echo symlink test this" NAME="ttyUSB%n", SYMLINK="%c{2+}"
+KERNEL=="ttyUSB[0-9]*", PROGRAM=="/bin/echo symlink test this" NAME="ttyUSB%n", SYMLINK="%c{2+}"
 EOF
        },
        {
 EOF
        },
        {
@@ -867,8 +867,8 @@ EOF
                exp_name        => "test",
                exp_target      => "link",
                conf            => <<EOF
                exp_name        => "test",
                exp_target      => "link",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", PROGRAM="/bin/echo link test this" SYMLINK="%c{2+}"
-BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="symlink0"
+BUS=="scsi", KERNEL=="sda", PROGRAM=="/bin/echo link test this" SYMLINK="%c{2+}"
+BUS=="scsi", KERNEL=="sda", NAME="link", SYMLINK="symlink0"
 EOF
        },
        {
 EOF
        },
        {
@@ -878,7 +878,7 @@ EOF
                exp_name        => "188:0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "188:0",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%s{dev}"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%s{dev}"
 EOF
        },
        {
 EOF
        },
        {
@@ -888,7 +888,7 @@ EOF
                exp_name        => "188",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "188",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%3s{dev}"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%3s{dev}"
 EOF
        },
        {
 EOF
        },
        {
@@ -898,7 +898,7 @@ EOF
                exp_name        => "percent%sign",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "percent%sign",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="percent%%sign"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="percent%%sign"
 EOF
        },
        {
 EOF
        },
        {
@@ -908,7 +908,7 @@ EOF
                exp_name        => "%ttyUSB0_name",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
                exp_name        => "%ttyUSB0_name",
                exp_target      => "ttyUSB0",
                conf            => <<EOF
-KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%%%k_name"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="%%%k_name"
 EOF
        },
        {
 EOF
        },
        {
@@ -918,7 +918,7 @@ EOF
                exp_name        => "link1",
                exp_target      => "node",
                conf            => <<EOF
                exp_name        => "link1",
                exp_target      => "node",
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", RESULT="node *", NAME="%c{1}", SYMLINK="%c{2} %c{3}"
+BUS=="scsi", PROGRAM=="/bin/echo -n node link1 link2", RESULT=="node *", NAME="%c{1}", SYMLINK="%c{2} %c{3}"
 EOF
        },
        {
 EOF
        },
        {
@@ -928,7 +928,7 @@ EOF
                exp_name        => "link4",
                exp_target      => "node",
                conf            => <<EOF
                exp_name        => "link4",
                exp_target      => "node",
                conf            => <<EOF
-BUS="scsi", PROGRAM="/bin/echo -n node link1 link2 link3 link4", RESULT="node *", NAME="%c{1}", SYMLINK="%c{2+}"
+BUS=="scsi", PROGRAM=="/bin/echo -n node link1 link2 link3 link4", RESULT=="node *", NAME="%c{1}", SYMLINK="%c{2+}"
 EOF
        },
        {
 EOF
        },
        {
@@ -937,7 +937,7 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "cdrom",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "cdrom",
                conf            => <<EOF
-KERNEL="sda", NAME="cdrom%e"
+KERNEL=="sda", NAME="cdrom%e"
 EOF
        },
        {
 EOF
        },
        {
@@ -947,7 +947,7 @@ EOF
                exp_name        => "cdrom",
                option          => "keep",
                conf            => <<EOF
                exp_name        => "cdrom",
                option          => "keep",
                conf            => <<EOF
-KERNEL="sda", NAME="cdrom%e"
+KERNEL=="sda", NAME="cdrom%e"
 EOF
        },
        {
 EOF
        },
        {
@@ -957,7 +957,7 @@ EOF
                exp_name        => "enum",
                option          => "keep",
                conf            => <<EOF
                exp_name        => "enum",
                option          => "keep",
                conf            => <<EOF
-KERNEL="sda1", NAME="enum%e"
+KERNEL=="sda1", NAME="enum%e"
 EOF
        },
        {
 EOF
        },
        {
@@ -967,7 +967,7 @@ EOF
                exp_name        => "cdrom1",
                option          => "keep",
                conf            => <<EOF
                exp_name        => "cdrom1",
                option          => "keep",
                conf            => <<EOF
-KERNEL="sda2", NAME="cdrom%e"
+KERNEL=="sda2", NAME="cdrom%e"
 EOF
        },
        {
 EOF
        },
        {
@@ -977,7 +977,7 @@ EOF
                exp_name        => "enum1",
                option          => "keep",
                conf            => <<EOF
                exp_name        => "enum1",
                option          => "keep",
                conf            => <<EOF
-KERNEL="sda3", NAME="enum%e"
+KERNEL=="sda3", NAME="enum%e"
 EOF
        },
        {
 EOF
        },
        {
@@ -987,7 +987,7 @@ EOF
                exp_name        => "cdrom2",
                option          => "clear",
                conf            => <<EOF
                exp_name        => "cdrom2",
                option          => "clear",
                conf            => <<EOF
-KERNEL="sda4", NAME="cdrom%e"
+KERNEL=="sda4", NAME="cdrom%e"
 EOF
        },
        {
 EOF
        },
        {
@@ -996,7 +996,7 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "cdrom",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "cdrom",
                conf            => <<EOF
-KERNEL="sda", NAME="cdrom%e"
+KERNEL=="sda", NAME="cdrom%e"
 EOF
        },
        {
 EOF
        },
        {
@@ -1006,7 +1006,7 @@ EOF
                exp_name        => "node",
                exp_add_error   => "yes",
                conf            => <<EOF
                exp_name        => "node",
                exp_add_error   => "yes",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore"
+BUS=="scsi", KERNEL=="sda", NAME="node", OPTIONS="ignore"
 EOF
        },
        {
 EOF
        },
        {
@@ -1015,8 +1015,8 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "node6",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "node6",
                conf            => <<EOF
-SUBSYSTEM="block", OPTIONS="all_partitions"
-BUS="scsi", KERNEL="sda", NAME="node"
+SUBSYSTEM=="block", OPTIONS="all_partitions"
+BUS=="scsi", KERNEL=="sda", NAME="node"
 EOF
        },
        {
 EOF
        },
        {
@@ -1026,8 +1026,8 @@ EOF
                exp_name        => "node6",
                exp_add_error   => "yes",
                conf            => <<EOF
                exp_name        => "node6",
                exp_add_error   => "yes",
                conf            => <<EOF
-SUBSYSTEM="block", OPTIONS="all_partitions"
-BUS="scsi", KERNEL="sda", NAME="node"
+SUBSYSTEM=="block", OPTIONS="all_partitions"
+BUS=="scsi", KERNEL=="sda", NAME="node"
 EOF
        },
        {
 EOF
        },
        {
@@ -1037,7 +1037,7 @@ EOF
                exp_name        => "node",
                exp_rem_error   => "yes",
                conf            => <<EOF
                exp_name        => "node",
                exp_rem_error   => "yes",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore_remove"
+BUS=="scsi", KERNEL=="sda", NAME="node", OPTIONS="ignore_remove"
 EOF
        },
        {
 EOF
        },
        {
@@ -1048,7 +1048,7 @@ EOF
                exp_rem_error   => "yes",
                option          => "clear",
                conf            => <<EOF
                exp_rem_error   => "yes",
                option          => "clear",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore_remove, all_partitions"
+BUS=="scsi", KERNEL=="sda", NAME="node", OPTIONS="ignore_remove, all_partitions"
 EOF
        },
        {
 EOF
        },
        {
@@ -1057,9 +1057,9 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "node",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "node",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="should_not_match", SUBSYSTEM="vc"
-BUS="scsi", KERNEL="sda", NAME="node", SUBSYSTEM="block"
-BUS="scsi", KERNEL="sda", NAME="should_not_match2", SUBSYSTEM="vc"
+BUS=="scsi", KERNEL=="sda", NAME="should_not_match", SUBSYSTEM=="vc"
+BUS=="scsi", KERNEL=="sda", NAME="node", SUBSYSTEM=="block"
+BUS=="scsi", KERNEL=="sda", NAME="should_not_match2", SUBSYSTEM=="vc"
 EOF
        },
        {
 EOF
        },
        {
@@ -1068,8 +1068,8 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "node",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "node",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="should_not_match", DRIVER="sd-wrong"
-BUS="scsi", KERNEL="sda", NAME="node", DRIVER="sd"
+BUS=="scsi", KERNEL=="sda", NAME="should_not_match", DRIVER=="sd-wrong"
+BUS=="scsi", KERNEL=="sda", NAME="node", DRIVER=="sd"
 EOF
        },
        {
 EOF
        },
        {
@@ -1078,7 +1078,7 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "node",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "node",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", PROGRAM="/usr/bin/test -b %N" NAME="node"
+BUS=="scsi", KERNEL=="sda", PROGRAM=="/usr/bin/test -b %N" NAME="node"
 EOF
        },
        {
 EOF
        },
        {
@@ -1087,7 +1087,7 @@ EOF
                devpath         => "/block/sda",
                exp_name        => "sda",
                conf            => <<EOF
                devpath         => "/block/sda",
                exp_name        => "sda",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", PROGRAM="/bin/echo %p", RESULT="/block/sda" NAME="%k"
+BUS=="scsi", KERNEL=="sda", PROGRAM=="/bin/echo %p", RESULT=="/block/sda" NAME="%k"
 EOF
        },
        {
 EOF
        },
        {
@@ -1097,7 +1097,7 @@ EOF
                exp_name        => "main_device",
                option          => "keep",
                conf            => <<EOF
                exp_name        => "main_device",
                option          => "keep",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda", NAME="main_device"
+BUS=="scsi", KERNEL=="sda", NAME="main_device"
 EOF
        },
        {
 EOF
        },
        {
@@ -1107,7 +1107,7 @@ EOF
                exp_name        => "main_device-part-1",
                option          => "clean",
                conf            => <<EOF
                exp_name        => "main_device-part-1",
                option          => "clean",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda1", NAME="%P-part-1"
+BUS=="scsi", KERNEL=="sda1", NAME="%P-part-1"
 EOF
        },
        {
 EOF
        },
        {
@@ -1116,7 +1116,7 @@ EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "start-udev-root-end",
                conf            => <<EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "start-udev-root-end",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda1", NAME="start-%r-end"
+BUS=="scsi", KERNEL=="sda1", NAME="start-%r-end"
 EOF
        },
        {
 EOF
        },
        {
@@ -1125,8 +1125,40 @@ EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "last",
                conf            => <<EOF
                devpath         => "/block/sda/sda1",
                exp_name        => "last",
                conf            => <<EOF
-BUS="scsi", KERNEL="sda1", SYMLINK="last", OPTIONS="last_rule"
-BUS="scsi", KERNEL="sda1", NAME="very-last"
+BUS=="scsi", KERNEL=="sda1", SYMLINK="last", OPTIONS="last_rule"
+BUS=="scsi", KERNEL=="sda1", NAME="very-last"
+EOF
+       },
+       {
+               desc            => "negation KERNEL!=",
+               subsys          => "block",
+               devpath         => "/block/sda/sda1",
+               exp_name        => "match",
+               conf            => <<EOF
+BUS=="scsi", KERNEL!="sda1", NAME="matches-but-is-negated"
+BUS=="scsi", KERNEL!="xsda1", NAME="match"
+BUS=="scsi", KERNEL=="sda1", NAME="wrong"
+EOF
+       },
+       {
+               desc            => "negation SUBSYSTEM!=",
+               subsys          => "block",
+               devpath         => "/block/sda/sda1",
+               exp_name        => "not-anything",
+               conf            => <<EOF
+BUS=="scsi", SUBSYSTEM=="block", KERNEL!="sda1", NAME="matches-but-is-negated"
+BUS=="scsi", SUBSYSTEM!="anything", NAME="not-anything"
+BUS=="scsi", KERNEL=="sda1", NAME="wrong"
+EOF
+       },
+       {
+               desc            => "negation PROGRAM!= exit code",
+               subsys          => "block",
+               devpath         => "/block/sda/sda1",
+               exp_name        => "nonzero-program",
+               conf            => <<EOF
+KERNEL=="sda1", PROGRAM!="/bin/false", NAME="nonzero-program"
+BUS=="scsi", KERNEL=="sda1", NAME="wrong"
 EOF
        },
 );
 EOF
        },
 );
index e02596053258523a99715330630b5ad1f3d2d1a6..dbba2979728f3f57ed0db18f030d0bc3ef549a7e 100644 (file)
--- a/udev.8.in
+++ b/udev.8.in
@@ -92,11 +92,11 @@ the name is used to name the device file or the network interface.
 .br
 If no matching rule is found, the default kernel device name is used.
 .P
 .br
 If no matching rule is found, the default kernel device name is used.
 .P
-Every rule consists of a list of comma separated fields:
+Every rule consists of a list of comma separated key value fields:
 .sp
 .sp
-.IR "key " ,[ "key " ,...] " name " [, " symlink" ]
-.sp
-where fields are:
+.IR "key " ,[ "key " ,...]
+.P
+The following key names can be used to match against device properties:
 .TP
 .B BUS
 Match the bus type of the device.
 .TP
 .B BUS
 Match the bus type of the device.
@@ -126,18 +126,20 @@ the key doesn't have any trailing whitespace characters by itself.
 Call external program. This key is valid if the program returns successful.
 The environment variables of
 .B udev
 Call external program. This key is valid if the program returns successful.
 The environment variables of
 .B udev
-are also available for the program.
+are also available to the program.
 .br
 The string returned by the program may be additionally matched with the
 .B RESULT
 .br
 The string returned by the program may be additionally matched with the
 .B RESULT
-key.
+key in the same or any later rule.
 .TP
 .B RESULT
 Match the returned string of the last
 .B PROGRAM
 .TP
 .B RESULT
 Match the returned string of the last
 .B PROGRAM
-call. This key may be used in any following rule after a
+call. This key can be used in the same or in any later rule after a
 .B PROGRAM
 call.
 .B PROGRAM
 call.
+.P
+The following keys can get values assigned:
 .TP
 .B NAME
 The name of the node to be created, or the name, the network interface
 .TP
 .B NAME
 The name of the node to be created, or the name, the network interface
@@ -162,6 +164,10 @@ The permissions for the device node. Every specified value overwrites the
 compiled-in default value.
 .TP
 .B OPTIONS
 compiled-in default value.
 .TP
 .B OPTIONS
+.B last_rule
+will be the last rule applied. No later rules will have any effect.
+.sp
+.B OPTIONS
 .B ignore_device
 will ignore this device. No node will be created.
 .sp
 .B ignore_device
 will ignore this device. No node will be created.
 .sp
@@ -240,31 +246,31 @@ the first three characters of the sysfs attribute.
 .sp
 .nf
 # if /sbin/scsi_id returns "OEM 0815", the device will be called disk1
 .sp
 .nf
 # if /sbin/scsi_id returns "OEM 0815", the device will be called disk1
-BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="OEM 0815", NAME="disk1"
+BUS=="scsi", PROGRAM=="/sbin/scsi_id", RESULT=="OEM 0815", NAME="disk1"
 
 # USB printer to be called lp_color
 
 # USB printer to be called lp_color
-BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_color"
+BUS=="usb", SYSFS{serial}=="W09090207101241330", NAME="lp_color"
 
 # SCSI disk with a specific vendor and model number will be called boot
 
 # SCSI disk with a specific vendor and model number will be called boot
-BUS="scsi", SYSFS{vendor}="IBM", SYSFS{model}="ST336", NAME="boot%n"
+BUS=="scsi", SYSFS{vendor}=="IBM", SYSFS{model}=="ST336", NAME="boot%n"
 
 # sound card with PCI bus id 00:0b.0 to be called dsp
 
 # sound card with PCI bus id 00:0b.0 to be called dsp
-BUS="pci", ID="00:0b.0", NAME="dsp"
+BUS=="pci", ID=="00:0b.0", NAME="dsp"
 
 # USB mouse at third port of the second hub to be called mouse1
 
 # USB mouse at third port of the second hub to be called mouse1
-BUS="usb", ID="2.3", NAME="mouse1"
+BUS=="usb", ID=="2.3", NAME="mouse1"
 
 # ttyUSB1 should always be called pda with two additional symlinks
 
 # ttyUSB1 should always be called pda with two additional symlinks
-KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld"
+KERNEL=="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld"
 
 # multiple USB webcams with symlinks to be called webcam0, webcam1, ...
 
 # multiple USB webcams with symlinks to be called webcam0, webcam1, ...
-BUS="usb", SYSFS{model}="XV3", NAME="video%n", SYMLINK="webcam%n"
+BUS=="usb", SYSFS{model}=="XV3", NAME=="video%n", SYMLINK="webcam%n"
 
 # grouping of optical drives from multiple kernel subsystems
 
 # grouping of optical drives from multiple kernel subsystems
-KERNEL="sr*", NAME="%k", SYMLINK="cdrom%e"
-KERNEL="scd*", NAME="%k", SYMLINK="cdrom%e"
-KERNEL="pcd*", NAME="%k", SYMLINK="cdrom%e"
-KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom",
+KERNEL=="sr*", NAME="%k", SYMLINK="cdrom%e"
+KERNEL=="scd*", NAME="%k", SYMLINK="cdrom%e"
+KERNEL=="pcd*", NAME="%k", SYMLINK="cdrom%e"
+KERNEL=="hd[a-z]", PROGRAM=="/bin/cat /proc/ide/%k/media", RESULT=="cdrom",
   NAME="%k", SYMLINK="cdrom%e"
 .fi
 .P
   NAME="%k", SYMLINK="cdrom%e"
 .fi
 .P
index 77ac38a791e1f891c5800517cedc3fd0411fd329..45b11de2aa573ef3485e7ef80fe5a6e8a0843e9a 100644 (file)
@@ -59,6 +59,54 @@ static int string_is_true(const char *str)
        return 0;
 }
 
        return 0;
 }
 
+static int get_key(char **line, char **key, char **value)
+{
+       char *linepos;
+       char *temp;
+
+       linepos = *line;
+       if (!linepos)
+               return -1;
+
+       /* skip whitespace */
+       while (isspace(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;
+       }
+
+       /* terminate key */
+       linepos[0] = '\0';
+       linepos++;
+
+       /* skip whitespace */
+       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';
+
+       return 0;
+}
+
 static void init_variables(void)
 {
        const char *env;
 static void init_variables(void)
 {
        const char *env;
@@ -86,7 +134,7 @@ static int parse_config_file(void)
 {
        char line[LINE_SIZE];
        char *bufline;
 {
        char line[LINE_SIZE];
        char *bufline;
-       char *temp;
+       char *linepos;
        char *variable;
        char *value;
        char *buf;
        char *variable;
        char *value;
        char *buf;
@@ -130,13 +178,14 @@ static int parse_config_file(void)
                        continue;
 
                strlcpy(line, bufline, count);
                        continue;
 
                strlcpy(line, bufline, count);
-               temp = line;
-               dbg("read '%s'", temp);
+               dbg("read '%s'", line);
 
 
-               retval = parse_get_pair(&temp, &variable, &value);
-               if (retval != 0)
-                       info("%s:%d:%Zd: error parsing '%s'",
-                            udev_config_filename, lineno, temp-line, temp);
+               linepos = line;
+               retval = get_key(&linepos, &variable, &value);
+               if (retval != 0) {
+                       info("error parsing %s, line %d:%d", udev_config_filename, lineno, (int) (linepos-line));
+                       continue;
+               }
 
                dbg("variable='%s', value='%s'", variable, value);
 
 
                dbg("variable='%s', value='%s'", variable, value);
 
@@ -168,17 +217,16 @@ static int parse_config_file(void)
        return retval;
 }
 
        return retval;
 }
 
-static void get_dirs(void)
+void udev_init_config(void)
 {
 {
-       char *temp;
-       int retval;
 
 
-       retval = sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path));
-       if (retval)
-               dbg("sysfs_get_mnt_path failed");
+       init_variables();
+       sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path));
 
        /* see if we should try to override any of the default values */
        if (getenv("UDEV_TEST") != NULL) {
 
        /* see if we should try to override any of the default values */
        if (getenv("UDEV_TEST") != NULL) {
+               char *temp;
+
                temp = getenv("SYSFS_PATH");
                if (temp != NULL) {
                        strlcpy(sysfs_path, temp, sizeof(sysfs_path));
                temp = getenv("SYSFS_PATH");
                if (temp != NULL) {
                        strlcpy(sysfs_path, temp, sizeof(sysfs_path));
@@ -198,9 +246,3 @@ static void get_dirs(void)
        dbg("udev_rules_filename='%s'", udev_rules_filename);
        dbg("udev_log=%d", udev_log);
 }
        dbg("udev_rules_filename='%s'", udev_rules_filename);
        dbg("udev_log=%d", udev_log);
 }
-
-void udev_init_config(void)
-{
-       init_variables();
-       get_dirs();
-}
index 16f23ccb04ebc570fc6b66066ce4f47db378fdf4..3a55270791780923c7bfdc57977bf30765508e29 100644 (file)
@@ -390,7 +390,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value,
                dup2(fds[1], STDOUT_FILENO);
                retval = execv(arg, argv);
 
                dup2(fds[1], STDOUT_FILENO);
                retval = execv(arg, argv);
 
-               info(FIELD_PROGRAM " execution of '%s' failed", path);
+               info(KEY_PROGRAM " execution of '%s' failed", path);
                exit(1);
        case -1:
                dbg("fork failed");
                exit(1);
        case -1:
                dbg("fork failed");
@@ -508,8 +508,13 @@ static int match_sysfs_pairs(struct udev_rule *rule, struct sysfs_class_device *
                if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
                        break;
                if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
                if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
                        break;
                if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
-                       dbg("sysfs attribute doesn't match");
-                       return -ENODEV;
+                       dbg("sysfs pair #%u does not match", i);
+                       if (pair->operation != KEY_OP_NOMATCH)
+                               return -1;
+               } else {
+                       dbg("sysfs pair #%u matches", i);
+                       if (pair->operation == KEY_OP_NOMATCH)
+                               return -1;
                }
        }
 
                }
        }
 
@@ -535,23 +540,33 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
                      struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
        if (rule->kernel[0] != '\0') {
                      struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
        if (rule->kernel[0] != '\0') {
-               dbg("check for " FIELD_KERNEL " rule->kernel='%s' class_dev->name='%s'",
+               dbg("check for " KEY_KERNEL " rule->kernel='%s' class_dev->name='%s'",
                    rule->kernel, class_dev->name);
                if (strcmp_pattern(rule->kernel, class_dev->name) != 0) {
                    rule->kernel, class_dev->name);
                if (strcmp_pattern(rule->kernel, class_dev->name) != 0) {
-                       dbg(FIELD_KERNEL " is not matching");
-                       goto exit;
+                       dbg(KEY_KERNEL " is not matching");
+                       if (rule->kernel_operation != KEY_OP_NOMATCH)
+                               goto exit;
+               } else {
+                       dbg(KEY_KERNEL " matches");
+                       if (rule->kernel_operation == KEY_OP_NOMATCH)
+                               goto exit;
                }
                }
-               dbg(FIELD_KERNEL " matches");
+               dbg(KEY_KERNEL " key is true");
        }
 
        if (rule->subsystem[0] != '\0') {
        }
 
        if (rule->subsystem[0] != '\0') {
-               dbg("check for " FIELD_SUBSYSTEM " rule->subsystem='%s' class_dev->name='%s'",
+               dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' class_dev->name='%s'",
                    rule->subsystem, class_dev->name);
                if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) {
                    rule->subsystem, class_dev->name);
                if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) {
-                       dbg(FIELD_SUBSYSTEM " is not matching");
-                       goto exit;
+                       dbg(KEY_SUBSYSTEM " is not matching");
+                       if (rule->subsystem_operation != KEY_OP_NOMATCH)
+                               goto exit;
+               } else {
+                       dbg(KEY_SUBSYSTEM " matches");
+                       if (rule->subsystem_operation == KEY_OP_NOMATCH)
+                               goto exit;
                }
                }
-               dbg(FIELD_SUBSYSTEM " matches");
+               dbg(KEY_SUBSYSTEM " key is true");
        }
 
        /* walk up the chain of physical devices and find a match */
        }
 
        /* walk up the chain of physical devices and find a match */
@@ -562,13 +577,18 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
                                dbg("device has no sysfs_device");
                                goto try_parent;
                        }
                                dbg("device has no sysfs_device");
                                goto try_parent;
                        }
-                       dbg("check for " FIELD_DRIVER " rule->driver='%s' sysfs_device->driver_name='%s'",
+                       dbg("check for " KEY_DRIVER " rule->driver='%s' sysfs_device->driver_name='%s'",
                            rule->driver, sysfs_device->driver_name);
                        if (strcmp_pattern(rule->driver, sysfs_device->driver_name) != 0) {
                            rule->driver, sysfs_device->driver_name);
                        if (strcmp_pattern(rule->driver, sysfs_device->driver_name) != 0) {
-                               dbg(FIELD_DRIVER " is not matching");
-                               goto try_parent;
+                               dbg(KEY_DRIVER " is not matching");
+                               if (rule->driver_operation != KEY_OP_NOMATCH)
+                                       goto try_parent;
+                       } else {
+                               dbg(KEY_DRIVER " matches");
+                               if (rule->driver_operation == KEY_OP_NOMATCH)
+                                       goto try_parent;
                        }
                        }
-                       dbg(FIELD_DRIVER " matches");
+                       dbg(KEY_DRIVER " key is true");
                }
 
                /* check for matching bus value */
                }
 
                /* check for matching bus value */
@@ -577,13 +597,18 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
                                dbg("device has no sysfs_device");
                                goto try_parent;
                        }
                                dbg("device has no sysfs_device");
                                goto try_parent;
                        }
-                       dbg("check for " FIELD_BUS " rule->bus='%s' sysfs_device->bus='%s'",
+                       dbg("check for " KEY_BUS " rule->bus='%s' sysfs_device->bus='%s'",
                            rule->bus, sysfs_device->bus);
                        if (strcmp_pattern(rule->bus, sysfs_device->bus) != 0) {
                            rule->bus, sysfs_device->bus);
                        if (strcmp_pattern(rule->bus, sysfs_device->bus) != 0) {
-                               dbg(FIELD_BUS " is not matching");
-                               goto try_parent;
+                               dbg(KEY_BUS " is not matching");
+                               if (rule->bus_operation != KEY_OP_NOMATCH)
+                                       goto try_parent;
+                       } else {
+                               dbg(KEY_BUS " matches");
+                               if (rule->bus_operation == KEY_OP_NOMATCH)
+                                       goto try_parent;
                        }
                        }
-                       dbg(FIELD_BUS " matches");
+                       dbg(KEY_BUS " key is true");
                }
 
                /* check for matching bus id */
                }
 
                /* check for matching bus id */
@@ -592,22 +617,27 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
                                dbg("device has no sysfs_device");
                                goto try_parent;
                        }
                                dbg("device has no sysfs_device");
                                goto try_parent;
                        }
-                       dbg("check " FIELD_ID);
+                       dbg("check " KEY_ID);
                        if (match_id(rule, sysfs_device) != 0) {
                        if (match_id(rule, sysfs_device) != 0) {
-                               dbg(FIELD_ID " is not matching");
-                               goto try_parent;
+                               dbg(KEY_ID " is not matching");
+                               if (rule->id_operation != KEY_OP_NOMATCH)
+                                       goto try_parent;
+                       } else {
+                               dbg(KEY_ID " matches");
+                               if (rule->id_operation == KEY_OP_NOMATCH)
+                                       goto try_parent;
                        }
                        }
-                       dbg(FIELD_ID " matches");
+                       dbg(KEY_ID " key is true");
                }
 
                /* check for matching sysfs pairs */
                if (rule->sysfs_pair[0].file[0] != '\0') {
                }
 
                /* check for matching sysfs pairs */
                if (rule->sysfs_pair[0].file[0] != '\0') {
-                       dbg("check " FIELD_SYSFS " pairs");
+                       dbg("check " KEY_SYSFS " pairs");
                        if (match_sysfs_pairs(rule, class_dev, sysfs_device) != 0) {
                        if (match_sysfs_pairs(rule, class_dev, sysfs_device) != 0) {
-                               dbg(FIELD_SYSFS " is not matching");
+                               dbg(KEY_SYSFS " is not matching");
                                goto try_parent;
                        }
                                goto try_parent;
                        }
-                       dbg(FIELD_SYSFS " matches");
+                       dbg(KEY_SYSFS " keys are true");
                }
 
                /* found matching physical device  */
                }
 
                /* found matching physical device  */
@@ -625,25 +655,35 @@ try_parent:
        if (rule->program[0] != '\0') {
                char program[PATH_SIZE];
 
        if (rule->program[0] != '\0') {
                char program[PATH_SIZE];
 
-               dbg("check " FIELD_PROGRAM);
+               dbg("check " KEY_PROGRAM);
                strlcpy(program, rule->program, sizeof(program));
                apply_format(udev, program, sizeof(program), class_dev, sysfs_device);
                if (execute_program(udev, program, udev->program_result, sizeof(udev->program_result)) != 0) {
                strlcpy(program, rule->program, sizeof(program));
                apply_format(udev, program, sizeof(program), class_dev, sysfs_device);
                if (execute_program(udev, program, udev->program_result, sizeof(udev->program_result)) != 0) {
-                       dbg(FIELD_PROGRAM " returned nonzero");
-                       goto try_parent;
+                       dbg(KEY_PROGRAM " returned nonzero");
+                       if (rule->program_operation != KEY_OP_NOMATCH)
+                               goto exit;
+               } else {
+                       dbg(KEY_PROGRAM " returned successful");
+                       if (rule->program_operation == KEY_OP_NOMATCH)
+                               goto exit;
                }
                }
-               dbg(FIELD_PROGRAM " returned successful");
+               dbg(KEY_PROGRAM " key is true");
        }
 
        /* check for matching result of external program */
        if (rule->result[0] != '\0') {
        }
 
        /* check for matching result of external program */
        if (rule->result[0] != '\0') {
-               dbg("check for " FIELD_RESULT "rule->result='%s', udev->program_result='%s'",
+               dbg("check for " KEY_RESULT " rule->result='%s', udev->program_result='%s'",
                   rule->result, udev->program_result);
                if (strcmp_pattern(rule->result, udev->program_result) != 0) {
                   rule->result, udev->program_result);
                if (strcmp_pattern(rule->result, udev->program_result) != 0) {
-                       dbg(FIELD_RESULT " is not matching");
-                       goto try_parent;
+                       dbg(KEY_RESULT " is not matching");
+                       if (rule->result_operation != KEY_OP_NOMATCH)
+                               goto exit;
+               } else {
+                       dbg(KEY_RESULT " matches");
+                       if (rule->result_operation == KEY_OP_NOMATCH)
+                               goto exit;
                }
                }
-               dbg(FIELD_RESULT " matches");
+               dbg(KEY_RESULT " key is true");
        }
 
        /* rule matches */
        }
 
        /* rule matches */
index 42552cfa410ece68203dfb7abddb905a21eff169..d0142031e7f70087ecfcc09b6464c871044a5473 100644 (file)
 #include "list.h"
 
 
 #include "list.h"
 
 
-#define FIELD_KERNEL           "KERNEL"
-#define FIELD_SUBSYSTEM                "SUBSYSTEM"
-#define FIELD_BUS              "BUS"
-#define FIELD_SYSFS            "SYSFS"
-#define FIELD_ID               "ID"
-#define FIELD_PROGRAM          "PROGRAM"
-#define FIELD_RESULT           "RESULT"
-#define FIELD_DRIVER           "DRIVER"
-#define FIELD_NAME             "NAME"
-#define FIELD_SYMLINK          "SYMLINK"
-#define FIELD_OWNER            "OWNER"
-#define FIELD_GROUP            "GROUP"
-#define FIELD_MODE             "MODE"
-#define FIELD_OPTIONS          "OPTIONS"
+#define KEY_KERNEL             "KERNEL"
+#define KEY_SUBSYSTEM          "SUBSYSTEM"
+#define KEY_BUS                        "BUS"
+#define KEY_SYSFS              "SYSFS"
+#define KEY_ID                 "ID"
+#define KEY_PROGRAM            "PROGRAM"
+#define KEY_RESULT             "RESULT"
+#define KEY_DRIVER             "DRIVER"
+#define KEY_NAME               "NAME"
+#define KEY_SYMLINK            "SYMLINK"
+#define KEY_OWNER              "OWNER"
+#define KEY_GROUP              "GROUP"
+#define KEY_MODE               "MODE"
+#define KEY_OPTIONS            "OPTIONS"
 
 #define OPTION_LAST_RULE       "last_rule"
 #define OPTION_IGNORE_DEVICE   "ignore_device"
 
 #define OPTION_LAST_RULE       "last_rule"
 #define OPTION_IGNORE_DEVICE   "ignore_device"
 
 #define RULEFILE_SUFFIX                ".rules"
 
 
 #define RULEFILE_SUFFIX                ".rules"
 
+enum key_operation {
+       KEY_OP_UNKNOWN,
+       KEY_OP_MATCH,
+       KEY_OP_NOMATCH,
+       KEY_OP_ADD,
+       KEY_OP_ASSIGN,
+};
+
 struct sysfs_pair {
        char file[PATH_SIZE];
        char value[VALUE_SIZE];
 struct sysfs_pair {
        char file[PATH_SIZE];
        char value[VALUE_SIZE];
+       enum key_operation operation;
 };
 
 struct udev_rule {
        struct list_head node;
 
        char kernel[NAME_SIZE];
 };
 
 struct udev_rule {
        struct list_head node;
 
        char kernel[NAME_SIZE];
+       enum key_operation kernel_operation;
        char subsystem[NAME_SIZE];
        char subsystem[NAME_SIZE];
+       enum key_operation subsystem_operation;
        char bus[NAME_SIZE];
        char bus[NAME_SIZE];
+       enum key_operation bus_operation;
        char id[NAME_SIZE];
        char id[NAME_SIZE];
-       struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
+       enum key_operation id_operation;
+       char driver[NAME_SIZE];
+       enum key_operation driver_operation;
        char program[PATH_SIZE];
        char program[PATH_SIZE];
+       enum key_operation program_operation;
        char result[PATH_SIZE];
        char result[PATH_SIZE];
-       char driver[NAME_SIZE];
+       enum key_operation result_operation;
+       struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
+
        char name[PATH_SIZE];
        char symlink[PATH_SIZE];
        char name[PATH_SIZE];
        char symlink[PATH_SIZE];
-
        char owner[USER_SIZE];
        char group[USER_SIZE];
        mode_t mode;
        char owner[USER_SIZE];
        char group[USER_SIZE];
        mode_t mode;
index f77f3db915758e24200e2d6201c14413572641cc..ac4755fd37d578a9cf6002b1568f96809b3f7e53 100644 (file)
@@ -73,6 +73,90 @@ void udev_rule_list_dump(void)
                udev_rule_dump(rule);
 }
 
                udev_rule_dump(rule);
 }
 
+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;
+       }
+
+       /* 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");
+       } 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;
+}
+
 /* extract possible KEY{attr} */
 static char *get_key_attribute(char *str)
 {
 /* extract possible KEY{attr} */
 static char *get_key_attribute(char *str)
 {
@@ -100,9 +184,7 @@ static int rules_parse(struct udevice *udev, const char *filename)
        char line[LINE_SIZE];
        char *bufline;
        int lineno;
        char line[LINE_SIZE];
        char *bufline;
        int lineno;
-       char *temp;
-       char *temp2;
-       char *temp3;
+       char *linepos;
        char *attr;
        char *buf;
        size_t bufsize;
        char *attr;
        char *buf;
        size_t bufsize;
@@ -113,12 +195,11 @@ static int rules_parse(struct udevice *udev, const char *filename)
        int retval = 0;
        struct udev_rule rule;
 
        int retval = 0;
        struct udev_rule rule;
 
-       if (file_map(filename, &buf, &bufsize) == 0) {
-               dbg("reading '%s' as rules file", filename);
-       } else {
+       if (file_map(filename, &buf, &bufsize) != 0) {
                dbg("can't open '%s' as rules file", filename);
                return -1;
        }
                dbg("can't open '%s' as rules file", filename);
                return -1;
        }
+       dbg("reading '%s' as rules file", filename);
 
        /* loop through the whole file */
        cur = 0;
 
        /* loop through the whole file */
        cur = 0;
@@ -160,39 +241,47 @@ static int rules_parse(struct udevice *udev, const char *filename)
 
                /* get all known keys */
                memset(&rule, 0x00, sizeof(struct udev_rule));
 
                /* get all known keys */
                memset(&rule, 0x00, sizeof(struct udev_rule));
-               temp = line;
+               linepos = line;
                valid = 0;
 
                while (1) {
                valid = 0;
 
                while (1) {
-                       retval = parse_get_pair(&temp, &temp2, &temp3);
+                       char *key;
+                       char *value;
+                       enum key_operation operation = KEY_OP_UNKNOWN;
+
+                       retval = get_key(&linepos, &key, &operation, &value);
                        if (retval)
                                break;
 
                        if (retval)
                                break;
 
-                       if (strcasecmp(temp2, FIELD_KERNEL) == 0) {
-                               strlcpy(rule.kernel, temp3, sizeof(rule.kernel));
+                       if (strcasecmp(key, KEY_KERNEL) == 0) {
+                               strlcpy(rule.kernel, value, sizeof(rule.kernel));
+                               rule.kernel_operation = operation;
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_SUBSYSTEM) == 0) {
-                               strlcpy(rule.subsystem, temp3, sizeof(rule.subsystem));
+                       if (strcasecmp(key, KEY_SUBSYSTEM) == 0) {
+                               strlcpy(rule.subsystem, value, sizeof(rule.subsystem));
+                               rule.subsystem_operation = operation;
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_BUS) == 0) {
-                               strlcpy(rule.bus, temp3, sizeof(rule.bus));
+                       if (strcasecmp(key, KEY_BUS) == 0) {
+                               strlcpy(rule.bus, value, sizeof(rule.bus));
+                               rule.bus_operation = operation;
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_ID) == 0) {
-                               strlcpy(rule.id, temp3, sizeof(rule.id));
+                       if (strcasecmp(key, KEY_ID) == 0) {
+                               strlcpy(rule.id, value, sizeof(rule.id));
+                               rule.id_operation = operation;
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) {
+                       if (strncasecmp(key, KEY_SYSFS, sizeof(KEY_SYSFS)-1) == 0) {
                                struct sysfs_pair *pair = &rule.sysfs_pair[0];
                                int sysfs_pair_num = 0;
 
                                struct sysfs_pair *pair = &rule.sysfs_pair[0];
                                int sysfs_pair_num = 0;
 
@@ -206,39 +295,43 @@ static int rules_parse(struct udevice *udev, const char *filename)
                                        ++pair;
                                }
                                if (pair) {
                                        ++pair;
                                }
                                if (pair) {
-                                       attr = get_key_attribute(temp2 + sizeof(FIELD_SYSFS)-1);
+                                       attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1);
                                        if (attr == NULL) {
                                        if (attr == NULL) {
-                                               dbg("error parsing " FIELD_SYSFS " attribute");
+                                               dbg("error parsing " KEY_SYSFS " attribute");
                                                continue;
                                        }
                                        strlcpy(pair->file, attr, sizeof(pair->file));
                                                continue;
                                        }
                                        strlcpy(pair->file, attr, sizeof(pair->file));
-                                       strlcpy(pair->value, temp3, sizeof(pair->value));
+                                       strlcpy(pair->value, value, sizeof(pair->value));
+                                       pair->operation = operation;
                                        valid = 1;
                                }
                                continue;
                        }
 
                                        valid = 1;
                                }
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_DRIVER) == 0) {
-                               strlcpy(rule.driver, temp3, sizeof(rule.driver));
+                       if (strcasecmp(key, KEY_DRIVER) == 0) {
+                               strlcpy(rule.driver, value, sizeof(rule.driver));
+                               rule.driver_operation = operation;
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_PROGRAM) == 0) {
-                               program_given = 1;
-                               strlcpy(rule.program, temp3, sizeof(rule.program));
+                       if (strcasecmp(key, KEY_RESULT) == 0) {
+                               strlcpy(rule.result, value, sizeof(rule.result));
+                               rule.result_operation = operation;
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_RESULT) == 0) {
-                               strlcpy(rule.result, temp3, sizeof(rule.result));
+                       if (strcasecmp(key, KEY_PROGRAM) == 0) {
+                               strlcpy(rule.program, value, sizeof(rule.program));
+                               rule.program_operation = operation;
+                               program_given = 1;
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) {
-                               attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1);
+                       if (strncasecmp(key, KEY_NAME, sizeof(KEY_NAME)-1) == 0) {
+                               attr = get_key_attribute(key + sizeof(KEY_NAME)-1);
                                /* FIXME: remove old style options and make OPTIONS= mandatory */
                                if (attr != NULL) {
                                        if (strstr(attr, OPTION_PARTITIONS) != NULL) {
                                /* FIXME: remove old style options and make OPTIONS= mandatory */
                                if (attr != NULL) {
                                        if (strstr(attr, OPTION_PARTITIONS) != NULL) {
@@ -250,52 +343,52 @@ static int rules_parse(struct udevice *udev, const char *filename)
                                                rule.ignore_remove = 1;
                                        }
                                }
                                                rule.ignore_remove = 1;
                                        }
                                }
-                               if (temp3[0] != '\0')
-                                       strlcpy(rule.name, temp3, sizeof(rule.name));
+                               if (value[0] != '\0')
+                                       strlcpy(rule.name, value, sizeof(rule.name));
                                else
                                        rule.ignore_device = 1;
                                valid = 1;
                                continue;
                        }
 
                                else
                                        rule.ignore_device = 1;
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_SYMLINK) == 0) {
-                               strlcpy(rule.symlink, temp3, sizeof(rule.symlink));
+                       if (strcasecmp(key, KEY_SYMLINK) == 0) {
+                               strlcpy(rule.symlink, value, sizeof(rule.symlink));
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_OWNER) == 0) {
-                               strlcpy(rule.owner, temp3, sizeof(rule.owner));
+                       if (strcasecmp(key, KEY_OWNER) == 0) {
+                               strlcpy(rule.owner, value, sizeof(rule.owner));
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_GROUP) == 0) {
-                               strlcpy(rule.group, temp3, sizeof(rule.group));
+                       if (strcasecmp(key, KEY_GROUP) == 0) {
+                               strlcpy(rule.group, value, sizeof(rule.group));
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_MODE) == 0) {
-                               rule.mode = strtol(temp3, NULL, 8);
+                       if (strcasecmp(key, KEY_MODE) == 0) {
+                               rule.mode = strtol(value, NULL, 8);
                                valid = 1;
                                continue;
                        }
 
                                valid = 1;
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_OPTIONS) == 0) {
-                               if (strstr(temp3, OPTION_LAST_RULE) != NULL) {
+                       if (strcasecmp(key, KEY_OPTIONS) == 0) {
+                               if (strstr(value, OPTION_LAST_RULE) != NULL) {
                                        dbg("last rule to be applied");
                                        rule.last_rule = 1;
                                }
                                        dbg("last rule to be applied");
                                        rule.last_rule = 1;
                                }
-                               if (strstr(temp3, OPTION_IGNORE_DEVICE) != NULL) {
+                               if (strstr(value, OPTION_IGNORE_DEVICE) != NULL) {
                                        dbg("device should be ignored");
                                        rule.ignore_device = 1;
                                }
                                        dbg("device should be ignored");
                                        rule.ignore_device = 1;
                                }
-                               if (strstr(temp3, OPTION_IGNORE_REMOVE) != NULL) {
+                               if (strstr(value, OPTION_IGNORE_REMOVE) != NULL) {
                                        dbg("remove event should be ignored");
                                        rule.ignore_remove = 1;
                                }
                                        dbg("remove event should be ignored");
                                        rule.ignore_remove = 1;
                                }
-                               if (strstr(temp3, OPTION_PARTITIONS) != NULL) {
+                               if (strstr(value, OPTION_PARTITIONS) != NULL) {
                                        dbg("creation of partition nodes requested");
                                        rule.partitions = DEFAULT_PARTITIONS_COUNT;
                                }
                                        dbg("creation of partition nodes requested");
                                        rule.partitions = DEFAULT_PARTITIONS_COUNT;
                                }
@@ -303,7 +396,7 @@ static int rules_parse(struct udevice *udev, const char *filename)
                                continue;
                        }
 
                                continue;
                        }
 
-                       dbg("unknown type of field '%s'", temp2);
+                       dbg("unknown key '%s'", key);
                        goto error;
                }
 
                        goto error;
                }
 
@@ -314,13 +407,13 @@ static int rules_parse(struct udevice *udev, const char *filename)
                /* simple plausibility checks for given keys */
                if ((rule.sysfs_pair[0].file[0] == '\0') ^
                    (rule.sysfs_pair[0].value[0] == '\0')) {
                /* simple plausibility checks for given keys */
                if ((rule.sysfs_pair[0].file[0] == '\0') ^
                    (rule.sysfs_pair[0].value[0] == '\0')) {
-                       info("inconsistency in " FIELD_SYSFS " key");
+                       info("inconsistency in " KEY_SYSFS " key");
                        goto error;
                }
 
                if ((rule.result[0] != '\0') && (program_given == 0)) {
                        goto error;
                }
 
                if ((rule.result[0] != '\0') && (program_given == 0)) {
-                       info(FIELD_RESULT " is only useful when "
-                            FIELD_PROGRAM " is called in any rule before");
+                       info(KEY_RESULT " is only useful when "
+                            KEY_PROGRAM " is called in any rule before");
                        goto error;
                }
 
                        goto error;
                }
 
@@ -332,7 +425,7 @@ static int rules_parse(struct udevice *udev, const char *filename)
                        continue;
 error:
                        info("parse error %s, line %d:%d, rule skipped",
                        continue;
 error:
                        info("parse error %s, line %d:%d, rule skipped",
-                            filename, lineno, (int) (temp - line));
+                            filename, lineno, (int) (linepos - line));
                }
        }
 
                }
        }
 
index b650096593308f7e0e7e6c67ff64c5895940cc55..c6658e6933fbcc0a795d26c3dcbf71044aabf19a 100644 (file)
@@ -177,41 +177,6 @@ int unlink_secure(const char *filename)
        return retval;
 }
 
        return retval;
 }
 
-int parse_get_pair(char **orig_string, char **left, char **right)
-{
-       char *temp;
-       char *string = *orig_string;
-
-       if (!string)
-               return -ENODEV;
-
-       /* eat any whitespace */
-       while (isspace(*string) || *string == ',')
-               ++string;
-
-       /* split based on '=' */
-       temp = strsep(&string, "=");
-       *left = temp;
-       if (!string)
-               return -ENODEV;
-
-       /* take the right side and strip off the '"' */
-       while (isspace(string[0]))
-               ++string;
-       if (string[0] == '"')
-               ++string;
-       else
-               return -ENODEV;
-
-       temp = strsep(&string, "\"");
-       if (!string || temp[0] == '\0')
-               return -ENODEV;
-       *right = temp;
-       *orig_string = string;
-
-       return 0;
-}
-
 int file_map(const char *filename, char **buf, size_t *bufsize)
 {
        struct stat stats;
 int file_map(const char *filename, char **buf, size_t *bufsize)
 {
        struct stat stats;