chiark / gitweb /
[PATCH] add ENV{} key to match agains environment variables
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Sun, 13 Mar 2005 10:40:32 +0000 (11:40 +0100)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 06:53:18 +0000 (23:53 -0700)
test/udev-test.pl
udev.8.in
udev_rules.c
udev_rules.h
udev_rules_parse.c

index ebcecce..2ece431 100644 (file)
@@ -259,15 +259,6 @@ BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}"
 EOF
        },
        {
-               desc            => "old style SYSFS_ attribute",
-               subsys          => "block",
-               devpath         => "/block/sda",
-               exp_name        => "good" ,
-               conf            => <<EOF
-BUS=="scsi", SYSFS_vendor=="IBM-ESXS", NAME="good"
-EOF
-       },
-       {
                desc            => "sustitution of sysfs value (%s{file})",
                subsys          => "block",
                devpath         => "/block/sda",
@@ -1171,6 +1162,29 @@ KERNEL   ==   "sda1"     ,    NAME   =    "true"
 BUS=="scsi", KERNEL=="sda1", NAME="wrong"
 EOF
        },
+       {
+               desc            => "ENV{} test",
+               subsys          => "block",
+               devpath         => "/block/sda/sda1",
+               exp_name        => "true",
+               conf            => <<EOF
+BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="go", NAME="wrong"
+BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="yes", NAME="true"
+BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="bad", NAME="bad"
+EOF
+       },
+       {
+               desc            => "ENV{} test",
+               subsys          => "block",
+               devpath         => "/block/sda/sda1",
+               exp_name        => "true",
+               conf            => <<EOF
+BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="go", NAME="wrong"
+BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="/block/sda/sdax1", NAME="no"
+BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="/block/sda/sda1", NAME="true"
+BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="bad", NAME="bad"
+EOF
+       },
 );
 
 # set env
index dbba297..84d8a31 100644 (file)
--- a/udev.8.in
+++ b/udev.8.in
@@ -115,13 +115,17 @@ Match the kernel driver name.
 Match the device number on the bus, like PCI bus id.
 .TP
 .BI SYSFS{ filename }
-Match sysfs device attribute like label, vendor, USB serial number, SCSI UUID
-or file system label. Up to 5 different sysfs files can be checked, with
-all of the values being required to match the rule.
+Match sysfs device attribute like vendor and product id's, USB serial number
+or the SCSI disk model number. Up to 5 different sysfs files can be checked,
+with all of the values being required to match the rule.
 .br
 Trailing whitespace characters in the sysfs attribute value are ignored, if
 the key doesn't have any trailing whitespace characters by itself.
 .TP
+.BI ENV{ variable }
+Match an environment variable. Up to 5 different environment variables can be
+checked, with all of the values being required to match the rule.
+.TP
 .B PROGRAM
 Call external program. This key is valid if the program returns successful.
 The environment variables of
index d119261..551c061 100644 (file)
@@ -498,30 +498,6 @@ static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct
        return 0;
 }
 
-static int match_sysfs_pairs(struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
-{
-       int i;
-
-       for (i = 0; i < rule->sysfs_pair_count; i++) {
-               struct key_pair *pair;
-
-               pair = &rule->sysfs_pair[i];
-               if ((pair->name[0] == '\0') || (pair->value[0] == '\0'))
-                       break;
-               if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
-                       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;
-               }
-       }
-
-       return 0;
-}
-
 static int match_id(struct udev_rule *rule, struct sysfs_device *sysfs_device)
 {
        char path[PATH_SIZE];
@@ -570,6 +546,33 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
                dbg(KEY_SUBSYSTEM " key is true");
        }
 
+       if (rule->env_pair_count) {
+               int i;
+
+               dbg("check for " KEY_ENV " pairs");
+               for (i = 0; i < rule->env_pair_count; i++) {
+                       struct key_pair *pair;
+                       const char *value;
+
+                       pair = &rule->env_pair[i];
+                       value = getenv(pair->name);
+                       if (!value) {
+                               dbg(KEY_ENV "{'%s'} is not found", pair->name);
+                               goto exit;
+                       }
+                       if (strcmp_pattern(pair->value, value) != 0) {
+                               dbg(KEY_ENV "{'%s'} is not matching", pair->name);
+                               if (pair->operation != KEY_OP_NOMATCH)
+                                       goto exit;
+                       } else {
+                               dbg(KEY_ENV "{'%s'} matches", pair->name);
+                               if (pair->operation == KEY_OP_NOMATCH)
+                                       goto exit;
+                       }
+               }
+               dbg(KEY_ENV " key is true");
+       }
+
        /* walk up the chain of physical devices and find a match */
        while (1) {
                /* check for matching driver */
@@ -632,11 +635,23 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
                }
 
                /* check for matching sysfs pairs */
-               if (rule->sysfs_pair[0].name[0] != '\0') {
+               if (rule->sysfs_pair_count) {
+                       int i;
+
                        dbg("check " KEY_SYSFS " pairs");
-                       if (match_sysfs_pairs(rule, class_dev, sysfs_device) != 0) {
-                               dbg(KEY_SYSFS " is not matching");
-                               goto try_parent;
+                       for (i = 0; i < rule->sysfs_pair_count; i++) {
+                               struct key_pair *pair;
+
+                               pair = &rule->sysfs_pair[i];
+                               if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
+                                       dbg(KEY_SYSFS "{'%s'} is not matching", pair->name);
+                                       if (pair->operation != KEY_OP_NOMATCH)
+                                               goto try_parent;
+                               } else {
+                                       dbg(KEY_SYSFS "{'%s'} matches", pair->name);
+                                       if (pair->operation == KEY_OP_NOMATCH)
+                                               goto try_parent;
+                               }
                        }
                        dbg(KEY_SYSFS " keys are true");
                }
index 94a5d9d..423a6f6 100644 (file)
 #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_SYSFS              "SYSFS"
+#define KEY_ENV                        "ENV"
 #define KEY_NAME               "NAME"
 #define KEY_SYMLINK            "SYMLINK"
 #define KEY_OWNER              "OWNER"
@@ -49,6 +50,7 @@
 #define OPTION_PARTITIONS      "all_partitions"
 
 #define KEY_SYSFS_PAIRS_MAX    5
+#define KEY_ENV_PAIRS_MAX      5
 
 #define RULEFILE_SUFFIX                ".rules"
 
@@ -85,6 +87,8 @@ struct udev_rule {
        enum key_operation result_operation;
        struct key_pair sysfs_pair[KEY_SYSFS_PAIRS_MAX];
        int sysfs_pair_count;
+       struct key_pair env_pair[KEY_ENV_PAIRS_MAX];
+       int env_pair_count;
 
        char name[PATH_SIZE];
        char symlink[PATH_SIZE];
index c4c684d..face496 100644 (file)
@@ -278,16 +278,36 @@ static int rules_parse(struct udevice *udev, const char *filename)
                                        goto error;
                                }
                                pair = &rule.sysfs_pair[rule.sysfs_pair_count];
-                               rule.sysfs_pair_count++;
-
                                attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1);
                                if (attr == NULL) {
                                        dbg("error parsing " KEY_SYSFS " attribute");
+                                       goto error;
+                               }
+                               strlcpy(pair->name, attr, sizeof(pair->name));
+                               strlcpy(pair->value, value, sizeof(pair->value));
+                               pair->operation = operation;
+                               rule.sysfs_pair_count++;
+                               valid = 1;
+                               continue;
+                       }
+
+                       if (strncasecmp(key, KEY_ENV, sizeof(KEY_ENV)-1) == 0) {
+                               struct key_pair *pair;
+
+                               if (rule.env_pair_count >= KEY_ENV_PAIRS_MAX) {
+                                       dbg("skip rule, to many " KEY_ENV " keys in a single rule");
+                                       goto error;
+                               }
+                               pair = &rule.env_pair[rule.env_pair_count];
+                               attr = get_key_attribute(key + sizeof(KEY_ENV)-1);
+                               if (attr == NULL) {
+                                       dbg("error parsing " KEY_ENV " attribute");
                                        continue;
                                }
                                strlcpy(pair->name, attr, sizeof(pair->name));
                                strlcpy(pair->value, value, sizeof(pair->value));
                                pair->operation = operation;
+                               rule.env_pair_count++;
                                valid = 1;
                                continue;
                        }