X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=namedev.c;h=633a7bf0dad1f7b892aa68575f7c241a1c4911ab;hb=5d4754f19521568b775ba7a31465d3af192ce382;hp=b9e099413bc3bec815d860f11b730ddb6227adf2;hpb=9f1da3613897346b6a45e1f7a706d2315bc0f420;p=elogind.git diff --git a/namedev.c b/namedev.c index b9e099413..633a7bf0d 100644 --- a/namedev.c +++ b/namedev.c @@ -39,6 +39,7 @@ #include "klibc_fixups.h" LIST_HEAD(config_device_list); +LIST_HEAD(perm_device_list); /* compare string with pattern (supports * ? [0-9] [!A-Z]) */ static int strcmp_pattern(const char *p, const char *s) @@ -113,7 +114,6 @@ int add_config_dev(struct config_device *new_dev) if (strncmp(dev->bus, new_dev->bus, sizeof(dev->name))) continue; copy_var(dev, new_dev, type); - copy_var(dev, new_dev, mode); copy_string(dev, new_dev, bus); copy_string(dev, new_dev, sysfs_file); copy_string(dev, new_dev, sysfs_value); @@ -121,8 +121,7 @@ int add_config_dev(struct config_device *new_dev) copy_string(dev, new_dev, place); copy_string(dev, new_dev, kernel_name); copy_string(dev, new_dev, exec_program); - copy_string(dev, new_dev, owner); - copy_string(dev, new_dev, group); + copy_string(dev, new_dev, symlink); return 0; } @@ -136,10 +135,54 @@ int add_config_dev(struct config_device *new_dev) return 0; } +int add_perm_dev(struct perm_device *new_dev) +{ + struct list_head *tmp; + struct perm_device *tmp_dev; + + /* update the values if we already have the device */ + list_for_each(tmp, &perm_device_list) { + struct perm_device *dev = list_entry(tmp, struct perm_device, node); + if (strcmp_pattern(new_dev->name, dev->name)) + continue; + copy_var(dev, new_dev, mode); + copy_string(dev, new_dev, owner); + copy_string(dev, new_dev, group); + return 0; + } + + /* not found, add new structure to the perm list */ + tmp_dev = malloc(sizeof(*tmp_dev)); + if (!tmp_dev) + return -ENOMEM; + memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); + list_add_tail(&tmp_dev->node, &perm_device_list); + //dump_perm_dev(tmp_dev); + return 0; +} + +static struct perm_device *find_perm(char *name) +{ + struct list_head *tmp; + struct perm_device *perm = NULL; + + list_for_each(tmp, &perm_device_list) { + perm = list_entry(tmp, struct perm_device, node); + if (strcmp_pattern(perm->name, name)) + continue; + return perm; + } + return NULL; +} + static mode_t get_default_mode(struct sysfs_class_device *class_dev) { - /* just default everyone to rw for the world! */ - return 0666; + mode_t mode = 0600; /* default to owner rw only */ + + if (strlen(default_mode_str) != 0) { + mode = strtol(default_mode_str, NULL, 8); + } + return mode; } static void build_kernel_number(struct sysfs_class_device *class_dev, struct udevice *udev) @@ -180,7 +223,7 @@ static void apply_format(struct udevice *udev, unsigned char *string) break; case 'D': if (strlen(udev->kernel_number) == 0) { - strcat(pos, "disk"); + strcat(pos, "disc"); break; } strcat(pos, "part"); @@ -324,15 +367,9 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev if (strcmp_pattern(dev->id, udev->callout_value) != 0) continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("callout returned matching value '%s', '%s' becomes '%s'" - " - owner='%s', group='%s', mode=%#o", - dev->id, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + strfieldcpy(udev->symlink, dev->symlink); + dbg("callout returned matching value '%s', '%s' becomes '%s'", + dev->id, class_dev->name, udev->name); return 0; } return -ENODEV; @@ -343,6 +380,7 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_attribute *tmpattr = NULL; struct config_device *dev; struct list_head *tmp; + char *c; list_for_each(tmp, &config_device_list) { dev = list_entry(tmp, struct config_device, node); @@ -371,22 +409,18 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, continue; label_found: - tmpattr->value[strlen(tmpattr->value)-1] = 0x00; + c = tmpattr->value + strlen(tmpattr->value)-1; + if (*c == '\n') + *c = 0x00; dbg("compare attribute '%s' value '%s' with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); - if (strcmp(dev->sysfs_value, tmpattr->value) != 0) + if (strcmp_pattern(dev->sysfs_value, tmpattr->value) != 0) continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("found matching attribute '%s', '%s' becomes '%s' " - "- owner='%s', group='%s', mode=%#o", - dev->sysfs_file, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + strfieldcpy(udev->symlink, dev->symlink); + dbg("found matching attribute '%s', '%s' becomes '%s' ", + dev->sysfs_file, class_dev->name, udev->name); return 0; } @@ -430,15 +464,9 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, if (!found) continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("found matching id '%s', '%s' becomes '%s'" - " - owner='%s', group ='%s', mode=%#o", - dev->id, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + strfieldcpy(udev->symlink, dev->symlink); + dbg("found matching id '%s', '%s' becomes '%s'", + dev->id, class_dev->name, udev->name); return 0; } return -ENODEV; @@ -482,15 +510,9 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("found matching place '%s', '%s' becomes '%s'" - " - owner='%s', group ='%s', mode=%#o", - dev->place, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + strfieldcpy(udev->symlink, dev->symlink); + dbg("found matching place '%s', '%s' becomes '%s'", + dev->place, class_dev->name, udev->name); return 0; } return -ENODEV; @@ -511,15 +533,8 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("found name, '%s' becomes '%s'" - " - owner='%s', group='%s', mode = %#o", - dev->kernel_name, udev->name, - dev->owner, dev->group, dev->mode); + strfieldcpy(udev->symlink, dev->symlink); + dbg("found name, '%s' becomes '%s'", dev->kernel_name, udev->name); return 0; } @@ -528,24 +543,8 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice *udev) { - struct config_device *dev; - struct list_head *tmp; - int len; - + /* heh, this is pretty simple... */ strfieldcpy(udev->name, class_dev->name); - /* look for permissions */ - list_for_each(tmp, &config_device_list) { - dev = list_entry(tmp, struct config_device, node); - len = strlen(dev->name); - if (strcmp_pattern(dev->name, class_dev->name)) - continue; - if (dev->mode != 0) { - dbg("found permissions for '%s'", class_dev->name); - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - } } int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) @@ -553,41 +552,34 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud struct sysfs_device *sysfs_device = NULL; struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; - char *temp = NULL; + struct perm_device *perm; udev->mode = 0; /* find the sysfs_device for this class device */ /* Wouldn't it really be nice if libsysfs could do this for us? */ - if (class_dev->sysdevice) { - sysfs_device = class_dev->sysdevice; - } else { + sysfs_device = sysfs_get_classdev_device(class_dev); + if (sysfs_device == NULL) { /* bah, let's go backwards up a level to see if the device is there, * as block partitions don't point to the physical device. Need to fix that * up in the kernel... */ - if (strstr(class_dev->path, "block")) { + if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { dbg("looking at block device"); if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - char path[SYSFS_PATH_MAX]; - dbg("really is a partition"); - strfieldcpy(path, class_dev->path); - temp = strrchr(path, '/'); - *temp = 0x00; - dbg("looking for a class device at '%s'", path); - class_dev_parent = sysfs_open_class_device(path); + class_dev_parent = sysfs_get_classdev_parent + (class_dev); if (class_dev_parent == NULL) { - dbg("sysfs_open_class_device at '%s' failed", path); + dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); } else { dbg("class_dev_parent->name='%s'", class_dev_parent->name); - if (class_dev_parent->sysdevice) - sysfs_device = class_dev_parent->sysdevice; + sysfs_device = sysfs_get_classdev_device(class_dev_parent); } } } } - + if (sysfs_device) { dbg("sysfs_device->path='%s'", sysfs_device->path); dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); @@ -624,19 +616,24 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud goto done; found: - /* substitute placeholder in NAME */ + /* substitute placeholder */ apply_format(udev, udev->name); + apply_format(udev, udev->symlink); done: - /* mode was never set above */ - if (!udev->mode) { + perm = find_perm(udev->name); + if (perm) { + udev->mode = perm->mode; + strfieldcpy(udev->owner, perm->owner); + strfieldcpy(udev->group, perm->group); + } else { + /* no matching perms found :( */ udev->mode = get_default_mode(class_dev); udev->owner[0] = 0x00; udev->group[0] = 0x00; } - - if (class_dev_parent) - sysfs_close_class_device(class_dev_parent); + dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", + udev->name, udev->owner, udev->group, udev->mode); return 0; } @@ -644,7 +641,7 @@ done: int namedev_init(void) { int retval; - + retval = namedev_init_rules(); if (retval) return retval; @@ -654,5 +651,6 @@ int namedev_init(void) return retval; dump_config_dev_list(); + dump_perm_dev_list(); return retval; }