X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=util-linux%2Fmdev.c;h=957316d52660ca5e2121dbb77acc086a3abd4c92;hb=10d0d4eec7e3a292917f43f72afae20341d9ba11;hp=73a82314c3cf3ef572ffcdf7b697898c83c2c06f;hpb=0960ca7383b3ef35433c269709d12fa6508cc78a;p=oweals%2Fbusybox.git diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 73a82314c..957316d52 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -1,32 +1,18 @@ -/* vi:set ts=4: +/* vi: set sw=4 ts=4: */ +/* * * mdev - Mini udev for busybox * * Copyright 2005 Rob Landley * Copyright 2005 Frank Sorenson * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * Licensed under GPL version 2, see file LICENSE in this tarball for details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "busybox.h" #include "xregex.h" #define DEV_PATH "/dev" -#define MDEV_CONF "/etc/mdev.conf" - -#include struct mdev_globals { @@ -36,152 +22,176 @@ struct mdev_globals #define bbg mdev_globals /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ -static void make_device(char *path) +static void make_device(char *path, int delete) { - char *device_name, *s; - int major, minor, type, len, fd; + char *device_name; + int major, minor, type, len; int mode = 0660; uid_t uid = 0; gid_t gid = 0; char *temp = path + strlen(path); + char *command = NULL; /* Try to read major/minor string. Note that the kernel puts \n after * the data, so we don't need to worry about null terminating the string * because sscanf() will stop at the first nondigit, which \n is. We * also depend on path having writeable space after it. */ - strcat(path, "/dev"); - fd = open(path, O_RDONLY); - len = read(fd, temp + 1, 64); - *temp++ = 0; - close(fd); - if (len < 1) return; + if (!delete) { + strcat(path, "/dev"); + len = open_read_close(path, temp + 1, 64); + *temp++ = 0; + if (len < 1) return; + } /* Determine device name, type, major and minor */ device_name = strrchr(path, '/') + 1; type = path[5]=='c' ? S_IFCHR : S_IFBLK; - if (sscanf(temp, "%d:%d", &major, &minor) != 2) return; /* If we have a config file, look up permissions for this device */ if (ENABLE_FEATURE_MDEV_CONF) { char *conf, *pos, *end; + int line, fd; /* mmap the config file */ - if (-1 != (fd=open(MDEV_CONF,O_RDONLY))) { - len = lseek(fd, 0, SEEK_END); - conf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); - if (conf) { - int line = 0; - - /* Loop through lines in mmaped file*/ - for (pos=conf; pos-confpw_uid; - } - s++; - /* parse GID */ - gid = strtoul(s,&s2,10); - if (end2 != s2) { - struct group *grp; - grp = getgrnam(strndupa(s,end2-s)); - if (!grp) - goto end_line; - gid = grp->gr_gid; - } - break; - } - /* mode */ - case 1: - { - mode = strtoul(pos,&pos,8); - if (pos != end2) - goto end_line; - else - goto found_device; - } - } - pos = end2; + /* Find : */ + for (s=pos; spw_uid; + } + s++; + /* parse GID */ + gid = strtoul(s, &s2, 10); + if (end2 != s2) { + struct group *grp; + grp = getgrnam(strndupa(s, end2-s)); + if (!grp) break; + gid = grp->gr_gid; } -end_line: - /* Did everything parse happily? */ - if (field && field!=3) - bb_error_msg_and_die("Bad line %d",line); + } + if (field == 2) { + /* mode */ - /* Next line */ - pos = ++end; + mode = strtoul(pos, &pos, 8); + if (pos != end2) break; + } + if (ENABLE_FEATURE_MDEV_EXEC && field == 3) { + // Command to run + char *s = "@$*", *s2; + s2 = strchr(s, *pos++); + if (!s2) { + // Force error + field = 1; + break; + } + if ((s2-s+1) & (1< 2) break; + if (field) bb_error_msg_and_die("bad line %d",line); + + /* Next line */ + pos = ++end; } + munmap(conf, len); + end_parse: /* nothing */ ; } umask(0); - if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) - bb_perror_msg_and_die("mknod %s failed", device_name); + if (!delete) { + if (sscanf(temp, "%d:%d", &major, &minor) != 2) return; + if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) + bb_perror_msg_and_die("mknod %s", device_name); - if (major==bbg.root_major && minor==bbg.root_minor) - symlink(device_name, "root"); - - if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid); + if (major == bbg.root_major && minor == bbg.root_minor) + symlink(device_name, "root"); + + if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid); + } + if (command) { + int rc; + char *s; + + s = xasprintf("MDEV=%s", device_name); + putenv(s); + rc = system(command); + s[4] = 0; + putenv(s); + free(s); + free(command); + if (rc == -1) bb_perror_msg_and_die("cannot run %s", command); + } + if (delete) unlink(device_name); } /* Recursive search of /sys/block or /sys/class. path must be a writeable @@ -193,7 +203,8 @@ static void find_dev(char *path) size_t len = strlen(path); struct dirent *entry; - if ((dir = opendir(path)) == NULL) + dir = opendir(path); + if (dir == NULL) return; while ((entry = readdir(dir)) != NULL) { @@ -212,7 +223,7 @@ static void find_dev(char *path) /* If there's a dev entry, mknod it */ - if (!strcmp(entry->d_name, "dev")) make_device(path); + if (!strcmp(entry->d_name, "dev")) make_device(path, 0); } closedir(dir); @@ -224,16 +235,16 @@ int mdev_main(int argc, char *argv[]) char *env_path; RESERVE_CONFIG_BUFFER(temp,PATH_MAX); - bb_xchdir(DEV_PATH); + xchdir(DEV_PATH); /* Scan */ if (argc == 2 && !strcmp(argv[1],"-s")) { struct stat st; - stat("/", &st); // If this fails, we have bigger problems. - bbg.root_major=major(st.st_dev); - bbg.root_minor=minor(st.st_dev); + xstat("/", &st); + bbg.root_major = major(st.st_dev); + bbg.root_minor = minor(st.st_dev); strcpy(temp,"/sys/block"); find_dev(temp); strcpy(temp,"/sys/class"); @@ -244,15 +255,12 @@ int mdev_main(int argc, char *argv[]) } else { action = getenv("ACTION"); env_path = getenv("DEVPATH"); - if (!action || !env_path) + if (!action || !env_path) bb_show_usage(); - if (!strcmp(action, "add")) { - sprintf(temp, "/sys%s", env_path); - make_device(temp); - } else if (!strcmp(action, "remove")) { - unlink(strrchr(env_path, '/') + 1); - } + sprintf(temp, "/sys%s", env_path); + if (!strcmp(action, "add")) make_device(temp,0); + else if (!strcmp(action, "remove")) make_device(temp,1); } if (ENABLE_FEATURE_CLEAN_UP) RELEASE_CONFIG_BUFFER(temp);