+ num = 0;
+ pos = strchr(string, '%');
+
+ if (pos) {
+ *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;
+ strcat(pos, udev->bus_id);
+ dbg("substitute bus_id '%s'", udev->bus_id);
+ break;
+ case 'k':
+ if (strlen(udev->kernel_name) == 0)
+ break;
+ strcat(pos, udev->kernel_name);
+ dbg("substitute kernel name '%s'", udev->kernel_name);
+ 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 'D':
+ if (strlen(udev->kernel_number) == 0) {
+ strcat(pos, "disc");
+ break;
+ }
+ strcat(pos, "part");
+ 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;
+ 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]);
+ break;
+ }
+ strcat(string, name);
+ } else