chiark / gitweb /
rules: add i2o driver rule
[elogind.git] / udev_rules.c
index daf3d7fff7992841ab766b10a0339712828dabf2..35db958c8df4959fbb68664b1aed7afb0124a3aa 100644 (file)
@@ -475,10 +475,12 @@ static int pass_env_to_socket(const char *sockname, const char *devpath, const c
 
        bufpos = snprintf(buf, sizeof(buf)-1, "%s@%s", action, devpath);
        bufpos++;
-       for (i = 0; environ[i] != NULL && bufpos < sizeof(buf); i++) {
+       for (i = 0; environ[i] != NULL && bufpos < (sizeof(buf)-1); i++) {
                bufpos += strlcpy(&buf[bufpos], environ[i], sizeof(buf) - bufpos-1);
                bufpos++;
        }
+       if (bufpos > sizeof(buf))
+               bufpos = sizeof(buf);
 
        count = sendto(sock, &buf, bufpos, 0, (struct sockaddr *)&saddr, addrlen);
        if (count < 0)
@@ -597,6 +599,7 @@ void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize)
                SUBST_KERNEL,
                SUBST_KERNEL_NUMBER,
                SUBST_ID,
+               SUBST_DRIVER,
                SUBST_MAJOR,
                SUBST_MINOR,
                SUBST_RESULT,
@@ -616,6 +619,7 @@ void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize)
                { .name = "number",     .fmt = 'n',     .type = SUBST_KERNEL_NUMBER },
                { .name = "kernel",     .fmt = 'k',     .type = SUBST_KERNEL },
                { .name = "id",         .fmt = 'b',     .type = SUBST_ID },
+               { .name = "driver",     .fmt = 'd',     .type = SUBST_DRIVER },
                { .name = "major",      .fmt = 'M',     .type = SUBST_MAJOR },
                { .name = "minor",      .fmt = 'm',     .type = SUBST_MINOR },
                { .name = "result",     .fmt = 'c',     .type = SUBST_RESULT },
@@ -707,6 +711,12 @@ found:
                                dbg("substitute id '%s'", udev->dev_parent->kernel);
                        }
                        break;
+               case SUBST_DRIVER:
+                       if (udev->dev_parent != NULL) {
+                               strlcat(string, udev->dev_parent->driver, maxsize);
+                               dbg("substitute driver '%s'", udev->dev_parent->driver);
+                       }
+                       break;
                case SUBST_MAJOR:
                        sprintf(temp2, "%d", major(udev->devt));
                        strlcat(string, temp2, maxsize);
@@ -940,6 +950,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
        if (match_key("DRIVER", rule, &rule->driver, udev->dev->driver))
                goto nomatch;
 
+       /* match NAME against a value assigned by an earlier rule */
        if (match_key("NAME", rule, &rule->name, udev->name))
                goto nomatch;
 
@@ -994,6 +1005,14 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
                                strlcat(filename, "/", sizeof(filename));
                                strlcat(filename, attr, sizeof(filename));
                        }
+               } else if (filename[0] != '/') {
+                       char tmp[PATH_SIZE];
+
+                       strlcpy(tmp, sysfs_path, sizeof(tmp));
+                       strlcat(tmp, udev->dev->devpath, sizeof(tmp));
+                       strlcat(tmp, "/", sizeof(tmp));
+                       strlcat(tmp, filename, sizeof(tmp));
+                       strlcpy(filename, tmp, sizeof(filename));
                }
 
                match = (stat(filename, &statbuf) == 0);
@@ -1265,9 +1284,6 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
        dbg("udev->dev->devpath='%s'", udev->dev->devpath);
        dbg("udev->dev->kernel='%s'", udev->dev->kernel);
 
-       /* use kernel name as default node name */
-       strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name));
-
        /* look for a matching rule to apply */
        udev_rules_iter_init(rules);
        while (1) {
@@ -1422,8 +1438,10 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
                }
        }
 
-       if (!name_set)
+       if (!name_set) {
                info("no node name set, will use kernel name '%s'", udev->name);
+               strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name));
+       }
 
        if (udev->tmp_node[0] != '\0') {
                dbg("removing temporary device node");