X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=namedev.c;h=58986e25c2c712bb07e0b33f2338a603514abbee;hb=7591c18a8f3460d3e7cab85d02915c4b51638b5c;hp=fbdb125e4c39ec28a941b46bbd9fa57f9ee47061;hpb=3d150dfb28efbaf0b25f154fb8955c47d606c3d5;p=elogind.git diff --git a/namedev.c b/namedev.c index fbdb125e4..58986e25c 100644 --- a/namedev.c +++ b/namedev.c @@ -189,7 +189,6 @@ static void build_kernel_number(struct sysfs_class_device *class_dev, struct ude { 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--; @@ -200,15 +199,30 @@ static void build_kernel_number(struct sysfs_class_device *class_dev, struct ude static void apply_format(struct udevice *udev, unsigned char *string) { char name[NAME_SIZE]; + char temp[NAME_SIZE]; + char *tail; char *pos; + char *pos2; + char *pos3; + int num; while (1) { + num = 0; pos = strchr(string, '%'); if (pos) { - strfieldcpy(name, pos+2); - *pos = 0x00; - switch (pos[1]) { + *pos = '\0'; + tail = pos+1; + if (isdigit(tail[0])) { + num = (int) strtoul(&pos[1], &tail, 10); + if (tail == NULL) { + dbg("format parsing error '%s'", pos+1); + break; + } + } + strfieldcpy(name, tail+1); + + switch (tail[0]) { case 'b': if (strlen(udev->bus_id) == 0) break; @@ -223,7 +237,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"); @@ -241,8 +255,24 @@ static void apply_format(struct udevice *udev, unsigned char *string) case 'c': if (strlen(udev->callout_value) == 0) break; - strcat(pos, udev->callout_value); - dbg("substitute callout output '%s'", udev->callout_value); + if (num) { + /* get part of return string */ + strncpy(temp, udev->callout_value, sizeof(temp)); + pos2 = temp; + while (num) { + num--; + pos3 = strsep(&pos2, " "); + if (pos3 == NULL) { + dbg("requested part of callout string not found"); + break; + } + } + strcat(pos, pos3); + dbg("substitute partial callout output '%s'", pos3); + } else { + strcat(pos, udev->callout_value); + dbg("substitute callout output '%s'", udev->callout_value); + } break; default: dbg("unknown substitution type '%%%c'", pos[1]); @@ -264,7 +294,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) pid_t pid; int value_set = 0; char buffer[256]; - char *arg; + char *pos; char *args[CALLOUT_MAXARG]; int i; @@ -286,9 +316,9 @@ static int exec_callout(struct config_device *dev, char *value, int len) dup(fds[1]); /* dup write side of pipe to STDOUT */ if (strchr(dev->exec_program, ' ')) { /* callout with arguments */ - arg = dev->exec_program; + pos = dev->exec_program; for (i=0; i < CALLOUT_MAXARG-1; i++) { - args[i] = strsep(&arg, " "); + args[i] = strsep(&pos, " "); if (args[i] == NULL) break; } @@ -324,9 +354,12 @@ static int exec_callout(struct config_device *dev, char *value, int len) } else { value_set = 1; strncpy(value, buffer, len); + pos = value + strlen(value)-1; + if (pos[0] == '\n') + pos[0] = '\0'; + dbg("callout returned '%s'", value); } } - dbg("callout returned '%s'", value); close(fds[0]); res = wait(&status); if (res < 0) { @@ -552,37 +585,29 @@ 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); } } } @@ -643,9 +668,6 @@ done: dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); - if (class_dev_parent) - sysfs_close_class_device(class_dev_parent); - return 0; }