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)
SUBST_KERNEL,
SUBST_KERNEL_NUMBER,
SUBST_ID,
+ SUBST_DRIVER,
SUBST_MAJOR,
SUBST_MINOR,
SUBST_RESULT,
{ .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 },
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);
if (match_key("NAME", rule, &rule->name, udev->name))
goto nomatch;
+ /* match against current list of symlinks */
+ if (rule->symlink_match.operation == KEY_OP_MATCH ||
+ rule->symlink_match.operation == KEY_OP_NOMATCH) {
+ struct name_entry *name_loop;
+ int match = 0;
+
+ list_for_each_entry(name_loop, &udev->symlink_list, node) {
+ if (match_key("SYMLINK", rule, &rule->symlink_match, name_loop->name) == 0) {
+ match = 1;
+ break;
+ }
+ }
+ if (!match)
+ goto nomatch;
+ }
+
for (i = 0; i < rule->env.count; i++) {
struct key_pair *pair = &rule->env.keys[i];
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);
}
/* collect symlinks */
- if (!udev->symlink_final && rule->symlink.operation != KEY_OP_UNSET) {
+ if (!udev->symlink_final &&
+ (rule->symlink.operation == KEY_OP_ASSIGN ||
+ rule->symlink.operation == KEY_OP_ASSIGN_FINAL ||
+ rule->symlink.operation == KEY_OP_ADD)) {
char temp[PATH_SIZE];
char *pos, *next;
int count;
if (rule->symlink.operation == KEY_OP_ASSIGN_FINAL)
udev->symlink_final = 1;
- if (rule->symlink.operation == KEY_OP_ASSIGN || rule->symlink.operation == KEY_OP_ASSIGN_FINAL) {
+ if (rule->symlink.operation == KEY_OP_ASSIGN ||
+ rule->symlink.operation == KEY_OP_ASSIGN_FINAL) {
info("reset symlink list");
name_list_cleanup(&udev->symlink_list);
}
}
if (!name_set) {
- strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name));
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') {