From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hannes Reinecke Date: Tue, 10 Feb 2004 08:14:20 +0000 Subject: [PATCH] Adding '%s' format specifier to NAME and SYMLINK Message-Id: <402892DC.4000003@suse.de> MIME-Version: 1 Content-Type: multipart/mixed; boundary="------------050909030905040204080900" List-Id: To: linux-hotplug@vger.kernel.org This is a multi-part message in MIME format. --------------050909030905040204080900 Content-Type: text/plain; charset="iso-8859-1"; format="flowed" Content-Transfer-Encoding: quoted-printable Hi all, this patch makes the format for NAME and SYMLINK a bit more flexible:=20 I've added a new format specifier '%s{}', which allows for=20 the value of any sysfs entry found for this device to be inserted. Example (for our S/390 fcp adapter): BUS=3D"ccw", SYSFS_devtype=3D"1732/03", NAME=3D"%k" \ SYMLINK=3D"zfcp-%s{hba_id}-%s{wwpn}:%s{fcp_lun}" I know this could also be done with an external program, but having this=20 incorporated into udev makes life easier, especially if run from=20 initramfs. Plus it makes the rules easier to follow, as the result is=20 directly visible and need not to be looked up in some external program. Comments etc. welcome. Cheers, Hannes --=20 Dr. Hannes Reinecke hare@suse.de SuSE Linux AG S390 & zSeries Maxfeldstra=DFe 5 +49 911 74053 688 90409 N=FCrnberg http://www.suse.de --------------050909030905040204080900 Content-Type: text/plain; name="namedev.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="namedev.diff" ===== namedev.c 1.98 vs edited ===== --- 1.98/namedev.c Tue Jan 27 22:40:29 2004 +++ edited/namedev.c Mon Feb 9 16:59:35 2004 @@ -168,7 +168,7 @@ return default_group_str; } -static void apply_format(struct udevice *udev, unsigned char *string) +static void apply_format(struct udevice *udev, unsigned char *string, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { char temp[NAME_SIZE]; char temp1[NAME_SIZE]; @@ -176,50 +176,75 @@ char *pos; char *pos2; char *pos3; - int num; + int num, len; + struct sysfs_attribute *tmpattr; pos = string; + strcpy(temp, string); + tail = temp; while (1) { num = 0; - pos = strchr(pos, '%'); + dbg("string is '%s' (index '%c')\n",string, *pos); +#if 1 + if (tail) { + pos2 = strchr(tail, '%'); + if (!pos2) { + strcat(pos,tail); + } else { + if ((len = pos2 - tail) > 0) { + strncat(pos,tail,len); + pos += len; + } + *pos = '\0'; + } + tail = pos2; + } + dbg("string '%s', tail '%s'\n", string, tail); +#else + pos = strchr(pos,'%'); +#endif - if (pos) { - pos[0] = '\0'; - tail = pos+1; + if (tail) { + tail ++; if (isdigit(tail[0])) { - num = (int) strtoul(&pos[1], &tail, 10); - if (tail == NULL) { - dbg("format parsing error '%s'", pos+1); + num = (int) strtoul(tail, &pos2, 10); + if (pos2 == NULL) { + dbg("format parsing error '%s'", tail); break; } + tail = pos2; } - strfieldcpy(temp, tail+1); switch (tail[0]) { case 'b': if (strlen(udev->bus_id) == 0) break; strcat(pos, udev->bus_id); + tail++; dbg("substitute bus_id '%s'", udev->bus_id); break; case 'k': if (strlen(udev->kernel_name) == 0) break; strcat(pos, udev->kernel_name); + tail++; dbg("substitute kernel name '%s'", udev->kernel_name); break; case 'n': if (strlen(udev->kernel_number) == 0) break; strcat(pos, udev->kernel_number); + tail++; dbg("substitute kernel number '%s'", udev->kernel_number); break; case 'm': sprintf(pos, "%u", udev->minor); + tail++; dbg("substitute minor number '%u'", udev->minor); break; case 'M': sprintf(pos, "%u", udev->major); + tail++; dbg("substitute major number '%u'", udev->major); break; case 'c': @@ -245,16 +270,66 @@ strcat(pos, udev->program_result); dbg("substitute result string '%s'", udev->program_result); } + tail++; break; + case 's': + if (tail[1] != '{') { + dbg("missing open braces for format"); + break; + } + pos2 = tail + 2; + if (!(pos3 = strchr(pos2,'}'))) { + dbg("missing close brace for format"); + break; + } + dbg("Tail is '%s'\n", temp); + *pos3 = '\0'; + tail = pos3 + 1; + dbg("look for class attribute '%s'", pos2); + /* try to find the attribute in the class device directory */ + tmpattr = sysfs_get_classdev_attr(class_dev, + pos2); + if (tmpattr) { + pos3 = tmpattr->value + + strlen(tmpattr->value)-1; + if (*pos3 == '\n') + *pos3 = 0x00; + strcpy(pos, tmpattr->value); + pos += strlen(tmpattr->value); + dbg("substitute sysfs value '%s'", + tmpattr->value); + break; + } + + /* look in the class device directory + if present */ + if (!sysfs_device) { + break; + } + dbg("look for device attribute '%s'", pos2); + tmpattr = sysfs_get_device_attr(sysfs_device, + pos2); + if (tmpattr) { + pos3 = tmpattr->value + + strlen(tmpattr->value)-1; + if (*pos3 == '\n') + *pos3 = 0x00; + strcpy(pos, tmpattr->value); + pos += strlen(tmpattr->value); + dbg("substitute sysfs value '%s'", + tmpattr->value); + } + break; + case '%': strcat(pos, "%"); pos++; break; default: - dbg("unknown substitution type '%%%c'", pos[1]); + dbg("unknown substitution type '%%%c'", tail[1]); break; } - strcat(string, temp); +/* strcat(string, temp); */ } else break; } @@ -647,7 +722,7 @@ /* execute external program */ if (dev->program[0] != '\0') { dbg("check " FIELD_PROGRAM); - apply_format(udev, dev->program); + apply_format(udev, dev->program, class_dev, sysfs_device); if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { dbg(FIELD_PROGRAM " returned nozero"); goto no_good; @@ -739,8 +814,8 @@ found: /* substitute placeholder */ - apply_format(udev, udev->name); - apply_format(udev, udev->symlink); + apply_format(udev, udev->name, class_dev, sysfs_device); + apply_format(udev, udev->symlink, class_dev, sysfs_device); done: perm = find_perm(udev->name); --------------050909030905040204080900-- ------------------------------------------------------- The SF.Net email is sponsored by EclipseCon 2004 Premiere Conference on Open Tools Development and Integration See the breadth of Eclipse activity. February 3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn _______________________________________________ Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net Linux-hotplug-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel