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, symlink);
return 0;
}
{
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--;
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;
break;
case 'D':
if (strlen(udev->kernel_number) == 0) {
- strcat(pos, "disk");
+ strcat(pos, "disc");
break;
}
strcat(pos, "part");
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]);
pid_t pid;
int value_set = 0;
char buffer[256];
- char *arg;
+ char *pos;
char *args[CALLOUT_MAXARG];
int i;
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;
}
} 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) {
if (strcmp_pattern(dev->id, udev->callout_value) != 0)
continue;
strfieldcpy(udev->name, dev->name);
+ strfieldcpy(udev->symlink, dev->symlink);
dbg("callout returned matching value '%s', '%s' becomes '%s'",
dev->id, class_dev->name, udev->name);
return 0;
*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);
+ strfieldcpy(udev->symlink, dev->symlink);
dbg("found matching attribute '%s', '%s' becomes '%s' ",
dev->sysfs_file, class_dev->name, udev->name);
if (!found)
continue;
strfieldcpy(udev->name, dev->name);
+ strfieldcpy(udev->symlink, dev->symlink);
dbg("found matching id '%s', '%s' becomes '%s'",
dev->id, class_dev->name, udev->name);
return 0;
continue;
strfieldcpy(udev->name, dev->name);
+ strfieldcpy(udev->symlink, dev->symlink);
dbg("found matching place '%s', '%s' becomes '%s'",
dev->place, class_dev->name, udev->name);
return 0;
continue;
strfieldcpy(udev->name, dev->name);
+ strfieldcpy(udev->symlink, dev->symlink);
dbg("found name, '%s' becomes '%s'", dev->kernel_name, udev->name);
return 0;
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);
}
}
}
goto done;
found:
- /* substitute placeholder in NAME */
+ /* substitute placeholder */
apply_format(udev, udev->name);
+ apply_format(udev, udev->symlink);
done:
perm = find_perm(udev->name);
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;
}