linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Adding '%s' format specifier to NAME and SYMLINK
@ 2004-02-10  8:14 Hannes Reinecke
  2004-02-13  1:34 ` Greg KH
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Hannes Reinecke @ 2004-02-10  8:14 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 846 bytes --]

Hi all,

this patch makes the format for NAME and SYMLINK a bit more flexible: 
I've added a new format specifier '%s{<SYSFS_var>}', which allows for 
the value of any sysfs entry found for this device to be inserted.
Example (for our S/390 fcp adapter):

BUS="ccw", SYSFS_devtype="1732/03", NAME="%k" \
SYMLINK="zfcp-%s{hba_id}-%s{wwpn}:%s{fcp_lun}"

I know this could also be done with an external program, but having this 
incorporated into udev makes life easier, especially if run from 
initramfs. Plus it makes the rules easier to follow, as the result is 
directly visible and need not to be looked up in some external program.

Comments etc. welcome.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke			hare@suse.de
SuSE Linux AG				S390 & zSeries
Maxfeldstraße 5				+49 911 74053 688
90409 Nürnberg				http://www.suse.de

[-- Attachment #2: namedev.diff --]
[-- Type: text/plain, Size: 4796 bytes --]

===== 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);

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-02-16 21:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-10  8:14 [PATCH] Adding '%s' format specifier to NAME and SYMLINK Hannes Reinecke
2004-02-13  1:34 ` Greg KH
2004-02-14 18:32 ` Kay Sievers
2004-02-15  2:36 ` Kay Sievers
2004-02-16  0:54 ` Kay Sievers
2004-02-16 21:40 ` Greg KH
2004-02-16 21:40 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).