From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrey Borzenkov Date: Sat, 17 Jan 2004 20:13:00 +0000 Subject: [PATCH] multple rules files support/symlink rules support Message-Id: <200401172313.00189.arvidjaar@mail.ru> MIME-Version: 1 Content-Type: multipart/mixed; boundary="Boundary-00=_MdZCAIU/stMVRHu" List-Id: To: linux-hotplug@vger.kernel.org --Boundary-00=_MdZCAIU/stMVRHu Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 --Boundary-00=_MdZCAIU/stMVRHu Content-Type: text/x-diff; charset="us-ascii"; name="udev013_multi.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="udev013_multi.patch" --- 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 #include #include +#include +#include #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); --Boundary-00=_MdZCAIU/stMVRHu-- ------------------------------------------------------- The SF.Net email is sponsored by EclipseCon 2004 Premiere Conference on Open Tools Development and Integration See the breadth of Eclipse activity. February 3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn _______________________________________________ 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