linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH] Adding '%s' format specifier to NAME and SYMLINK
Date: Tue, 10 Feb 2004 08:14:20 +0000	[thread overview]
Message-ID: <402892DC.4000003@suse.de> (raw)

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

             reply	other threads:[~2004-02-10  8:14 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-02-10  8:14 Hannes Reinecke [this message]
2004-02-13  1:34 ` [PATCH] Adding '%s' format specifier to NAME and SYMLINK 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=402892DC.4000003@suse.de \
    --to=hare@suse.de \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).