linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrey Borzenkov <arvidjaar@mail.ru>
To: linux-hotplug@vger.kernel.org
Subject: Re: [PATCH] multple rules files support/symlink rules support
Date: Tue, 20 Jan 2004 17:09:16 +0000	[thread overview]
Message-ID: <200401202009.16476.arvidjaar@mail.ru> (raw)
In-Reply-To: <200401172313.00189.arvidjaar@mail.ru>

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

svetoslav pointed that patch removed possibility to ignore devices. Updated 
version attached. Now name is ignored if neither SYMLINK nor NAME is 
specified.

regards

-andrey

On Saturday 17 January 2004 23:13, Andrey Borzenkov wrote:
> Attached patch adds support for
>
> - multiple rules files. You can now do
>
> udev_rules="file1 dir2 file3 ..."
>
> directory is scanned and all files are read. Currently it does not descend
> into subdirs.
>
> - to make the above really useful it allows multiple rules with symlinks;
> all rules are collected and applied (note 100 characters limit for total
> names length currently). It still takes the first found name and warns if
> more were seen.
>
> The multiple files support for rules file is actually for the case when you
> need be sure about ordering; sorting readdir results was too clumsy.
>
> The patch allows easy local customization without any need to edit existing
> rules. It is expected that distributions will ship basic rules (based on
> required policy or compatibility or whatever) and users will create extra
> rules to name some devices to taste. E.g. I currently have basic Mandrake
> config that creates compatible devfs names and local rules to name some
> local devices. Ie.
>
> udev_rules="/etc/udev/conf.d"
>
> with
>
> {pts/0}% LC_ALL=C ll /etc/udev/conf.d
> total 8
> -rw-r--r--    1 root     root          142 Jan 17 22:07 bor
> -rwxr-xr-x    1 root     root         3848 Jan 17 22:58 udev.rules.devfs*
>
> where
>
> {pts/0}% cat /etc/udev/conf.d/bor
> KERNEL="hd*" PROGRAM="/etc/udev/scripts/removables %k" SYMLINK="%c/%D"
> KERNEL="sd*" PROGRAM="/etc/udev/scripts/removables %k" SYMLINK="%c/%D"
>
> and I get
>
> {pts/0}% LC_ALL=C ll /udev/flash0
> total 1
> lrwxrwxrwx    1 root     root            6 Jan 17 22:59 disc -> ../sdb
> lrwxrwxrwx    1 root     root            7 Jan 17 22:59 part1 -> ../sdb1
>
> for USB stick (upper one :)
>
> (not that interesting because currently SCSI devfs names are missing, but
> that would create them as well just fine).
>
> regards
>
> -andrey

[-- Attachment #2: udev013_multi.patch --]
[-- Type: text/x-diff, Size: 5595 bytes --]

--- udev-013/namedev.c.multi	2004-01-14 03:21:03.000000000 +0300
+++ udev-013/namedev.c	2004-01-20 19:44:08.689282216 +0300
@@ -715,28 +715,50 @@ int namedev_name_device(struct sysfs_cla
 		}
 
 		/* check if we are instructed to ignore this device */
-		if (dev->name[0] == '\0') {
+		if (dev->name[0] == '\0' && dev->symlink[0] == '\0') {
 			dbg("instructed to ignore this device");
 			return -1;
 		}
 
-		/* Yup, this rule belongs to us! */
-		dbg("found matching rule, '%s' becomes '%s'", dev->kernel, dev->name);
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		goto found;
+		/* if everything matched add symlink to list of aliases */
+		if (dev->symlink[0] != '\0') {
+			char temp[NAME_MAX];
+
+			/* do not clobber dev */
+			strfieldcpy(temp, dev->symlink);
+			apply_format(udev, temp);
+			if (strlen(udev->symlink) + strlen(temp) + 2 > sizeof(udev->symlink))
+				dbg("could not append symlink %s for %s",
+				    dev->symlink, udev->kernel_name);
+			else {
+				strfieldcat(udev->symlink, temp);
+				strfieldcat(udev->symlink, " ");
+			}
+		}
+
+		/* is this symlink only rule? */
+		if (dev->name[0] == '\0')
+			continue;
+
+		/* Yup, this rule belongs to us!
+		 * but continue to collect symlinks */
+		if (udev->name[0] == '\0') {
+			dbg("found matching rule, '%s' becomes '%s'",
+			    dev->kernel, dev->name);
+			strfieldcpy(udev->name, dev->name);
+
+			/* substitute placeholder */
+			apply_format(udev, udev->name);
+		} else
+			dbg("conflicting rule for '%s' would become '%s'",
+			    dev->kernel, dev->name);
 	}
 
 	/* no rule was found so we use the kernel name */
-	strfieldcpy(udev->name, class_dev->name);
-	goto done;
-
-found:
-	/* substitute placeholder */
-	apply_format(udev, udev->name);
-	apply_format(udev, udev->symlink);
+	if (udev->name[0] == '\0')
+		strfieldcpy(udev->name, class_dev->name);
+	dbg("symlinks for '%s' are: '%s'", udev->name, udev->symlink);
 
-done:
 	perm = find_perm(udev->name);
 	if (perm) {
 		udev->mode = perm->mode;
--- udev-013/namedev_parse.c.multi	2004-01-13 03:09:55.000000000 +0300
+++ udev-013/namedev_parse.c	2004-01-17 22:58:16.000000000 +0300
@@ -34,6 +34,8 @@
 #include <ctype.h>
 #include <unistd.h>
 #include <errno.h>
+#include <dirent.h>
+#include <sys/stat.h>
 
 #include "udev.h"
 #include "namedev.h"
@@ -120,7 +122,7 @@ void dump_perm_dev_list(void)
 }
 
 
-int namedev_init_rules(void)
+static int parse_rules_file(const char *file)
 {
 	char line[255];
 	int lineno;
@@ -132,11 +134,11 @@ int namedev_init_rules(void)
 	int retval = 0;
 	struct config_device dev;
 
-	fd = fopen(udev_rules_filename, "r");
+	fd = fopen(file, "r");
 	if (fd != NULL) {
-		dbg("reading '%s' as rules file", udev_rules_filename);
+		dbg("reading '%s' as rules file", file);
 	} else {
-		dbg("can't open '%s' as a rules file", udev_rules_filename);
+		dbg("can't open '%s' as a rules file", file);
 		return -ENODEV;
 	}
 
@@ -263,7 +265,7 @@ exit:
 	return retval;
 }
 
-int namedev_init_permissions(void)
+static int parse_permissions_file(const char *file)
 {
 	char line[255];
 	char *temp;
@@ -272,11 +274,11 @@ int namedev_init_permissions(void)
 	int retval = 0;
 	struct perm_device dev;
 
-	fd = fopen(udev_permissions_filename, "r");
+	fd = fopen(file, "r");
 	if (fd != NULL) {
-		dbg("reading '%s' as permissions file", udev_permissions_filename);
+		dbg("reading '%s' as permissions file", file);
 	} else {
-		dbg("can't open '%s' as permissions file", udev_permissions_filename);
+		dbg("can't open '%s' as permissions file", file);
 		return -ENODEV;
 	}
 
@@ -345,4 +347,67 @@ exit:
 	return retval;
 }	
 
+static int parse_rules(char *var, int (*func)(const char *))
+{
+	static char temp[PATH_MAX + NAME_MAX];
+	static char temp1[PATH_MAX + NAME_MAX];
+	char *p = temp, *file;
+	struct stat buf;
+	int err = 0;
+
+	strfieldcpy(temp, var);
+	while ((file = strsep(&p, " ")) != NULL) {
+		dbg("parse_rules: looking at file %s", file);
+
+		if (stat(file, &buf) == -1) {
+			err = errno;
+			dbg("parse_rules: can't stat %s", file);
+			goto out;
+		}
+
+		if (S_ISREG(buf.st_mode)) {
+			err = (*func)(file);
+			if (err)
+				goto out;
+		} else if (S_ISDIR(buf.st_mode)) {
+			DIR *dir;
+			struct dirent *dirent;
+
+			if ((dir = opendir(file)) == NULL) {
+				err = errno;
+				dbg("parse_rules: can't open directory %s", file);
+				goto out;
+			}
+
+			/* FIXME: This does not check for errors */
+			while ((dirent = readdir(dir)) != NULL) {
+				if (dirent->d_name[0] == '.')
+					continue;
+
+				dbg("parse_rules: for direntry %s", dirent->d_name);
+				strfieldcpy(temp1, file);
+				strfieldcat(temp1, "/");
+				strfieldcat(temp1, dirent->d_name);
+				err = (*func)(temp1);
+				/* do not skip remaining files */
+			}
+		} else {
+			dbg("parse_rules: unknown file type %s", file);
+			err = -EINVAL;
+			goto out;
+		}
+	}
 
+out:
+	return err;
+}
+
+int namedev_init_rules(void)
+{
+	return parse_rules(udev_rules_filename, parse_rules_file);
+}
+
+int namedev_init_permissions(void)
+{
+	return parse_rules(udev_permissions_filename, parse_permissions_file);
+}
--- udev-013/udev.h.multi	2004-01-13 03:09:55.000000000 +0300
+++ udev-013/udev.h	2004-01-17 22:58:16.000000000 +0300
@@ -80,6 +80,13 @@ do { \
 	strncpy(to, from, sizeof(to)-1); \
 } while (0)
 
+#define strfieldcat(to, from) \
+do { \
+	to[sizeof(to)-1] = '\0'; \
+	strncat(to, from, sizeof(to)-1); \
+} while (0)
+
+
 extern int udev_add_device(char *path, char *subsystem);
 extern int udev_remove_device(char *path, char *subsystem);
 extern void udev_init_config(void);

  reply	other threads:[~2004-01-20 17:09 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-17 20:13 [PATCH] multple rules files support/symlink rules support Andrey Borzenkov
2004-01-20 17:09 ` Andrey Borzenkov [this message]
2004-01-20 17:57 ` Svetoslav Slavtchev
2004-01-20 18:45 ` Andrey Borzenkov
2004-01-20 23:10 ` Svetoslav Slavtchev
2004-01-21 23:51 ` Greg KH
2004-01-22 17:44 ` Svetoslav Slavtchev
2004-01-26 17:31 ` Andrey Borzenkov
2004-01-26 23:42 ` Kay Sievers
2004-01-27  9:54 ` "Andrey Borzenkov" 
2004-01-27 11:43 ` Marco d'Itri
2004-02-03  1:04 ` Greg KH
2004-02-03 11:25 ` Gioele Barabucci
2004-02-16 22:34 ` Greg KH
2004-02-17  7:29 ` "Andrey Borzenkov" 
2004-02-17 17:29 ` 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=200401202009.16476.arvidjaar@mail.ru \
    --to=arvidjaar@mail.ru \
    --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).