From: Andrey Borzenkov <arvidjaar@mail.ru>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH] multple rules files support/symlink rules support
Date: Sat, 17 Jan 2004 20:13:00 +0000 [thread overview]
Message-ID: <200401172313.00189.arvidjaar@mail.ru> (raw)
[-- Attachment #1: Type: text/plain, Size: 1747 bytes --]
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: 5691 bytes --]
--- udev-013/namedev.c.multi 2004-01-14 03:21:03.000000000 +0300
+++ udev-013/namedev.c 2004-01-17 22:55:20.955272056 +0300
@@ -602,6 +602,7 @@ int namedev_name_device(struct sysfs_cla
struct config_device *dev;
struct perm_device *perm;
char *pos;
+ int found = 0;
udev->mode = 0;
@@ -714,29 +715,46 @@ int namedev_name_device(struct sysfs_cla
}
}
- /* check if we are instructed to ignore this device */
- if (dev->name[0] == '\0') {
- dbg("instructed to ignore this device");
- return -1;
+ /* 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, " ");
+ }
}
- /* 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;
+ /* is this symlink only rule? */
+ if (dev->name[0] == '\0')
+ continue;
+
+ /* Yup, this rule belongs to us!
+ * but continue to collect symlinks */
+ if (!found) {
+ dbg("found matching rule, '%s' becomes '%s'",
+ dev->kernel, dev->name);
+ strfieldcpy(udev->name, dev->name);
+
+ /* substitute placeholder */
+ apply_format(udev, udev->name);
+ found = 1;
+ } 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 (!found)
+ 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:25:43.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:25:43.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);
next reply other threads:[~2004-01-17 20:13 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-01-17 20:13 Andrey Borzenkov [this message]
2004-01-20 17:09 ` [PATCH] multple rules files support/symlink rules support Andrey Borzenkov
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=200401172313.00189.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).