From 49d02c41fe60684e1f43cab38e4c1d80a607a921 Mon Sep 17 00:00:00 2001 From: Faustas Azuolas Bagdonas Date: Tue, 7 Aug 2018 08:31:18 -0500 Subject: Added support for a fourth field in mdev.conf --- toys/pending/mdev.c | 106 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 21 deletions(-) (limited to 'toys') diff --git a/toys/pending/mdev.c b/toys/pending/mdev.c index cab51e11..0493f1a5 100644 --- a/toys/pending/mdev.c +++ b/toys/pending/mdev.c @@ -22,19 +22,24 @@ config MDEV_CONF help The mdev config file (/etc/mdev.conf) contains lines that look like: hd[a-z][0-9]* 0:3 660 + (sd[a-z]) root:disk 660 =usb_storage Each line must contain three whitespace separated fields. The first field is a regular expression matching one or more device names, the second and third fields are uid:gid and file permissions for - matching devies. + matching devices. Fourth field is optional. It could be used to change + device name (prefix '='), path (prefix '=' and postfix '/') or create a + symlink (prefix '>'). */ #include "toys.h" +#include // mknod in /dev based on a path like "/sys/block/hda/hda1" static void make_device(char *path) { - char *device_name = 0, *s, *temp; + char *device_name = 0, *custom_name = 0, *s, *temp; + bool create_symlink = false; int major = 0, minor = 0, type, len, fd, mode = 0660; uid_t uid = 0; gid_t gid = 0; @@ -79,6 +84,7 @@ static void make_device(char *path) if (CFG_MDEV_CONF) { char *conf, *pos, *end; + bool optional_field_valid = false; // mmap the config file if (-1!=(fd = open("/etc/mdev.conf", O_RDONLY))) { @@ -96,8 +102,9 @@ static void make_device(char *path) // find end of this line for(end = pos; end-conf': + create_symlink = true; + case '=': + custom_name = strdup(&name[1]); + break; + case '!': + device_name = NULL; + break; + default: + free(name); + goto end_line; + } + free(name); + optional_field_valid = true; + } + } goto found_device; } } @@ -169,8 +209,9 @@ static void make_device(char *path) } end_line: // Did everything parse happily? - if (field && field!=3) error_exit("Bad line %d", line); - + // Note: Last field is optional. + if ((field>1 || (field==1 && !optional_field_valid)) && field!=4) + error_exit("Bad line %d", line); // Next line pos = ++end; } @@ -180,21 +221,44 @@ found_device: close(fd); } - sprintf(toybuf, "/dev/%s", device_name); + if(device_name) { + if(custom_name) { + sprintf(toybuf, "/dev/%s", custom_name); + if(custom_name[strlen(custom_name) - 1] == '/') { + DIR *dir; + dir = opendir(toybuf); + if(dir) closedir(dir); + else mkdir(toybuf, 0755); + } + } + else + sprintf(toybuf, "/dev/%s", device_name); - if ((temp=getenv("ACTION")) && !strcmp(temp, "remove")) { - unlink(toybuf); - return; - } + if ((temp=getenv("ACTION")) && !strcmp(temp, "remove")) { + unlink(toybuf); + return; + } - if (strchr(device_name, '/')) mkpath(toybuf); - if (mknod(toybuf, mode | type, dev_makedev(major, minor)) && errno != EEXIST) - perror_exit("mknod %s failed", toybuf); + if (strchr(device_name, '/')) mkpath(toybuf); + if (mknod(toybuf, mode | type, dev_makedev(major, minor)) && + errno != EEXIST) + perror_exit("mknod %s failed", toybuf); + if(create_symlink){ + char *symlink_name = malloc(sizeof("/dev/") + strlen(device_name) + 1); + if(symlink_name == NULL) + perror_exit("malloc failed while creating symlink to %s", toybuf); + sprintf(symlink_name, "/dev/%s", device_name); + if(symlink(toybuf, symlink_name)){ + free(symlink_name); + perror_exit("symlink creation failed for %s", toybuf); + } + free(symlink_name); + } - - if (type == S_IFBLK) close(open(toybuf, O_RDONLY)); // scan for partitions + if (type == S_IFBLK) close(open(toybuf, O_RDONLY)); // scan for partitions - if (CFG_MDEV_CONF) mode=chown(toybuf, uid, gid); + if (CFG_MDEV_CONF) mode=chown(toybuf, uid, gid); + } } static int callback(struct dirtree *node) -- cgit v1.2.3