X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=namedev.c;h=83852f9df29abc52e9cac65140f353b750881b0a;hp=cf9e92635e0bfc2805dbedac833a2bb4d8f60d66;hb=6968d494d76ea0e6e326e23948d2428b53faccf8;hpb=c124eafa238b34a2e79100d3eb1fb143b7e8cb8b diff --git a/namedev.c b/namedev.c index cf9e92635..83852f9df 100644 --- a/namedev.c +++ b/namedev.c @@ -216,10 +216,10 @@ static int namedev_init_config(void) int retval = 0; struct config_device dev; - dbg("opening %s to read as config", udev_config_filename); + dbg("opening '%s' to read as config", udev_config_filename); fd = fopen(udev_config_filename, "r"); if (fd == NULL) { - dbg("can't open %s", udev_config_filename); + dbg("can't open '%s'", udev_config_filename); return -ENODEV; } @@ -232,7 +232,7 @@ static int namedev_init_config(void) goto exit; lineno++; - dbg_parse("read %s", temp); + dbg_parse("read '%s'", temp); /* eat the whitespace at the beginning of the line */ while (isspace(*temp)) @@ -413,10 +413,10 @@ static int namedev_init_permissions(void) int retval = 0; struct config_device dev; - dbg("opening %s to read as permissions config", udev_config_permission_filename); + dbg("opening '%s' to read as permissions config", udev_config_permission_filename); fd = fopen(udev_config_permission_filename, "r"); if (fd == NULL) { - dbg("can't open %s", udev_config_permission_filename); + dbg("can't open '%s'", udev_config_permission_filename); return -ENODEV; } @@ -426,7 +426,7 @@ static int namedev_init_permissions(void) if (temp == NULL) break; - dbg_parse("read %s", temp); + dbg_parse("read '%s'", temp); /* eat the whitespace at the beginning of the line */ while (isspace(*temp)) @@ -445,21 +445,21 @@ static int namedev_init_permissions(void) /* parse the line */ temp2 = strsep(&temp, ":"); if (!temp2) { - dbg("cannot parse line: %s", line); + dbg("cannot parse line '%s'", line); continue; } strncpy(dev.name, temp2, sizeof(dev.name)); temp2 = strsep(&temp, ":"); if (!temp2) { - dbg("cannot parse line: %s", line); + dbg("cannot parse line '%s'", line); continue; } strncpy(dev.owner, temp2, sizeof(dev.owner)); temp2 = strsep(&temp, ":"); if (!temp2) { - dbg("cannot parse line: %s", line); + dbg("cannot parse line '%s'", line); continue; } strncpy(dev.group, temp2, sizeof(dev.owner)); @@ -487,6 +487,66 @@ static mode_t get_default_mode(struct sysfs_class_device *class_dev) return 0666; } +static void build_kernel_number(struct sysfs_class_device *class_dev, struct udevice *udev) +{ + char *dig; + + /* FIXME, figure out how to handle stuff like sdaj which will not work right now. */ + dig = class_dev->name + strlen(class_dev->name); + while (isdigit(*(dig-1))) + dig--; + strfieldcpy(udev->kernel_number, dig); + dbg("kernel_number='%s'", udev->kernel_number); +} + +static void apply_format(struct udevice *udev, unsigned char *string) +{ + char name[NAME_SIZE]; + char *pos; + + while (1) { + pos = strchr(string, '%'); + + if (pos) { + strfieldcpy(name, pos+2); + *pos = 0x00; + switch (pos[1]) { + case 'b': + if (strlen(udev->bus_id) == 0) + break; + strcat(pos, udev->bus_id); + dbg("substitute bus_id '%s'", udev->bus_id); + break; + case 'n': + if (strlen(udev->kernel_number) == 0) + break; + strcat(pos, udev->kernel_number); + dbg("substitute kernel number '%s'", udev->kernel_number); + break; + case 'm': + sprintf(pos, "%u", udev->minor); + dbg("substitute minor number '%u'", udev->minor); + break; + case 'M': + sprintf(pos, "%u", udev->major); + dbg("substitute major number '%u'", udev->major); + break; + case 'c': + if (strlen(udev->callout_value) == 0) + break; + strcat(pos, udev->callout_value); + dbg("substitute callout output '%s'", udev->callout_value); + break; + default: + dbg("unknown substitution type '%%%c'", pos[1]); + break; + } + strcat(string, name); + } else + break; + } +} + static int exec_callout(struct config_device *dev, char *value, int len) { @@ -548,7 +608,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) break; buffer[res] = '\0'; if (res > len) { - dbg("callout len %d too short\n", len); + dbg("callout len %d too short", len); retval = -1; } if (value_set) { @@ -577,7 +637,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) return retval; } -static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, char *value, int len) +static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev) { struct config_device *dev; struct list_head *tmp; @@ -586,9 +646,12 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev dev = list_entry(tmp, struct config_device, node); if (dev->type != CALLOUT) continue; - if (exec_callout(dev, value, len)) + + /* substitute anything that needs to be in the program name */ + apply_format(udev, dev->exec_program); + if (exec_callout(dev, udev->callout_value, NAME_SIZE)) continue; - if (strncmp_wildcard(value, dev->id, len) != 0) + if (strncmp_wildcard(udev->callout_value, dev->id, NAME_SIZE) != 0) continue; strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { @@ -597,7 +660,7 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev strfieldcpy(udev->group, dev->group); } dbg_parse("callout returned matching value '%s', '%s' becomes '%s'" - " - owner='%s', group='%s', mode =%#o", + " - owner='%s', group='%s', mode=%#o", dev->id, class_dev->name, udev->name, dev->owner, dev->group, dev->mode); return 0; @@ -808,7 +871,6 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; char *temp = NULL; - char value[ID_SIZE]; udev->mode = 0; @@ -822,11 +884,11 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) * up in the kernel... */ if (strstr(class_dev->path, "block")) { - dbg_parse("looking at block device..."); + dbg_parse("looking at block device"); if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { char path[SYSFS_PATH_MAX]; - dbg_parse("really is a partition..."); + dbg_parse("really is a partition"); strfieldcpy(path, class_dev->path); temp = strrchr(path, '/'); *temp = 0x00; @@ -835,7 +897,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) if (class_dev_parent == NULL) { dbg("sysfs_open_class_device at '%s' failed", path); } else { - dbg_parse("class_dev_parent->name=%s", class_dev_parent->name); + dbg_parse("class_dev_parent->name='%s'", class_dev_parent->name); if (class_dev_parent->sysdevice) sysfs_device = class_dev_parent->sysdevice; } @@ -846,12 +908,15 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) if (sysfs_device) { dbg_parse("sysfs_device->path='%s'", sysfs_device->path); dbg_parse("sysfs_device->bus_id='%s'", sysfs_device->bus_id); + strfieldcpy(udev->bus_id, sysfs_device->bus_id); } else { dbg_parse("class_dev->name = '%s'", class_dev->name); } + build_kernel_number(class_dev, udev); + /* rules are looked at in priority order */ - retval = do_callout(class_dev, udev, value, sizeof(value)); + retval = do_callout(class_dev, udev); if (retval == 0) goto found; @@ -876,48 +941,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) found: /* substitute placeholder in NAME */ - while (1) { - char *pos = strchr(udev->name, '%'); - char *dig; - char name[NAME_SIZE]; - - if (pos) { - strfieldcpy(name, pos+2); - *pos = 0x00; - switch (pos[1]) { - case 'b': - if (!sysfs_device) - break; - strcat(udev->name, sysfs_device->bus_id); - dbg("substitute bus_id '%s'", sysfs_device->bus_id); - break; - case 'n': - dig = class_dev->name + strlen(class_dev->name); - while (isdigit(*(dig-1))) - dig--; - strcat(pos, dig); - dbg("substitute kernel number '%s'", dig); - break; - case 'm': - sprintf(pos, "%u", udev->minor); - dbg("substitute minor number '%u'", udev->minor); - break; - case 'M': - sprintf(pos, "%u", udev->major); - dbg("substitute major number '%u'", udev->major); - break; - case 'c': - strcat(pos, value); - dbg("substitute callout output '%s'", value); - break; - default: - dbg("unknown substitution type '%%%c'", pos[1]); - break; - } - strcat(udev->name, name); - } else - break; - } + apply_format(udev, udev->name); done: /* mode was never set above */