linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PATCH : new key MODEFILE
@ 2007-02-24  2:36 Jean Tourrilhes
  2007-02-24  4:48 ` Andrey Borzenkov
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Jean Tourrilhes @ 2007-02-24  2:36 UTC (permalink / raw)
  To: linux-hotplug

	Hi,

	I was looking into using the key name RUN and PROGRAM in udev,
and I realised that udev attempt to run those programs even if they
don't exist. This is a bit wasteful timewise...

	In shell programming, you typically do something like this :
		if [ -x /sbin/myprogram ]; then
			/sbin/myprogram $MYARGS
		fi

	My first thought was to hack the RUN and PROGRAM keys to check
the existence of the program to be launched (cut to the first
whitespace...), but this was a bit hackish.
	I also thought that a generic facility to test file
existence/permisions would be useful. Maybe we want to replicate this
kind of construct :
		if [ -x /sbin/myprogram ] && [ -r /etc/itsconfigfile ]; then
			/sbin/myprogram $MYARGS
		fi
	And you can think of many other interesting ideas along those
lines, where you can use dummy files to impact the rules as an
alternative to env variables...

	So, I decided to create a real MODEMASK key in udev. This idea
is that this key take a filename and a permission key and verify that
the file has such permission.
	The example above would be :
MODEMASK{/sbin/myprogram}="0100", MODEMASK{/etc/itsconfigfile}="0400", 

	The good news is that it was not so bad, and the changes very
localised. I tested it with udev-103, and verified that the patch
applies to udev-105.
	Patch included...

	Regards,

	Jean

---------------------------------------------------------------------

diff -u -p udev-103-pristine/udev_rules.c udev-103/udev_rules.c
--- udev-103-pristine/udev_rules.c	2006-10-20 05:43:35.000000000 -0700
+++ udev-103/udev_rules.c	2007-02-23 18:13:54.000000000 -0800
@@ -609,6 +609,53 @@ static int match_key(const char *key_nam
 	return -1;
 }
 
+static int match_modemask(const char *key_name, struct udev_rule *rule, struct key *key, const char *key_file)
+{
+	int match;
+	char value[PATH_SIZE];
+	char filename[PATH_SIZE];
+	struct stat stats;
+	mode_t modemask;
+	char *eptr;
+
+	if (key->operation != KEY_OP_MATCH &&
+	    key->operation != KEY_OP_NOMATCH)
+		return 0;
+
+	strlcpy(value, rule->buf + key->val_off, sizeof(value));
+
+	/* Value should be a mode mask - octal integer */
+	modemask = strtol(value, &eptr, 8);
+	/* Parsing error = no match */
+	if(*eptr != '\0')
+		return -1;
+
+	/* Check if we have an absolute path, otherwise default to /dev */
+	if(key_file[0] = '/')
+		snprintf(filename, sizeof(filename), "%s", key_file);
+	else
+		snprintf(filename, sizeof(filename), "%s/%s", udev_root, key_file);
+	filename[sizeof(filename)-1] = '\0';
+
+	/* If file does not exist -> no match */
+	if (stat(filename, &stats) != 0)
+		return -1;
+	dbg("match %s '%o' <-> '%o'", key_name, modemask, stats.st_mode);
+
+	/* Check if match -> we make a binary AND of the two numbers */
+	match = stats.st_mode & modemask;
+	if (match && (key->operation != KEY_OP_NOMATCH)) {
+		dbg("%s is true (matching value)", key_name);
+		return 0;
+	}
+	if (!match && (key->operation = KEY_OP_NOMATCH)) {
+		dbg("%s is true (non-matching value)", key_name);
+		return 0;
+	}
+	dbg("%s is false", key_name);
+	return -1;
+}
+
 /* match a single rule against a given device and possibly its parent devices */
 static int match_rule(struct udevice *udev, struct udev_rule *rule)
 {
@@ -690,6 +737,19 @@ static int match_rule(struct udevice *ud
 		}
 	}
 
+	/* Check for matching MODEMASK attribute pairs */
+	for (i = 0; i < rule->modemask.count; i++) {
+		struct key_pair *pair = &rule->modemask.keys[i];
+
+		if (pair->key.operation = KEY_OP_MATCH ||
+		    pair->key.operation = KEY_OP_NOMATCH) {
+			const char *key_name = key_pair_name(rule, pair);
+
+			if (match_modemask("MODEMASK", rule, &pair->key, key_name))
+				goto nomatch;
+		}
+	}
+
 	/* walk up the chain of parent devices and find a match */
 	udev->dev_parent = udev->dev;
 	while (1) {
diff -u -p udev-103-pristine/udev_rules.h udev-103/udev_rules.h
--- udev-103-pristine/udev_rules.h	2006-10-20 05:43:35.000000000 -0700
+++ udev-103/udev_rules.h	2007-02-23 17:37:40.000000000 -0800
@@ -71,6 +71,7 @@ struct udev_rule {
 	struct key_pairs attrs;
 
 	struct key_pairs env;
+	struct key_pairs modemask;
 	struct key program;
 	struct key result;
 	struct key import;
diff -u -p udev-103-pristine/udev_rules_parse.c udev-103/udev_rules_parse.c
--- udev-103-pristine/udev_rules_parse.c	2006-10-20 05:43:35.000000000 -0700
+++ udev-103/udev_rules_parse.c	2007-02-23 17:17:56.000000000 -0800
@@ -400,6 +400,18 @@ static int add_to_rules(struct udev_rule
 			continue;
 		}
 
+		if (strncasecmp(key, "MODEMASK{", sizeof("MODEMASK{")-1) = 0) {
+			attr = get_key_attribute(key + sizeof("MODEMASK")-1);
+			if (attr = NULL) {
+				err("error parsing MODEMASK attribute");
+				goto invalid;
+			}
+			if (add_rule_key_pair(rule, &rule->modemask, operation, attr, value) != 0)
+				goto invalid;
+			valid = 1;
+			continue;
+		}
+
 		if (strcasecmp(key, "PROGRAM") = 0) {
 			add_rule_key(rule, &rule->program, operation, value);
 			valid = 1;

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CIDÞVDEV
_______________________________________________
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

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

end of thread, other threads:[~2007-03-16  1:04 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-24  2:36 PATCH : new key MODEFILE Jean Tourrilhes
2007-02-24  4:48 ` Andrey Borzenkov
2007-02-24 14:34 ` Kay Sievers
2007-02-24 14:58 ` Marco d'Itri
2007-02-26 17:42 ` Jean Tourrilhes
2007-02-27 12:47 ` Kay Sievers
2007-02-27 17:19 ` Jean Tourrilhes
2007-03-16  0:55 ` Kay Sievers
2007-03-16  1:04 ` Jean Tourrilhes

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).