mdev: add environment variable match
function old new delta make_device 1998 2189 +191 clean_up_cur_rule 61 96 +35 dirAction 75 87 +12 mdev_main 838 849 +11 packed_usage 29272 29273 +1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 250/0) Total: 250 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
1961aea305
commit
40b97fb31e
@ -51,9 +51,9 @@ device nodes if your system needs something more than the default root/root
|
|||||||
660 permissions.
|
660 permissions.
|
||||||
|
|
||||||
The file has the format:
|
The file has the format:
|
||||||
[-]<device regex> <uid>:<gid> <permissions>
|
[-][envmatch]<device regex> <uid>:<gid> <permissions>
|
||||||
or
|
or
|
||||||
@<maj[,min1[-min2]]> <uid>:<gid> <permissions>
|
[envmatch]@<maj[,min1[-min2]]> <uid>:<gid> <permissions>
|
||||||
or
|
or
|
||||||
$envvar=<regex> <uid>:<gid> <permissions>
|
$envvar=<regex> <uid>:<gid> <permissions>
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
//usage: IF_FEATURE_MDEV_CONF(
|
//usage: IF_FEATURE_MDEV_CONF(
|
||||||
//usage: "\n"
|
//usage: "\n"
|
||||||
//usage: "It uses /etc/mdev.conf with lines\n"
|
//usage: "It uses /etc/mdev.conf with lines\n"
|
||||||
//usage: " [-]DEVNAME UID:GID PERM"
|
//usage: " [-][ENV=regex;]...DEVNAME UID:GID PERM"
|
||||||
//usage: IF_FEATURE_MDEV_RENAME(" [>|=PATH]|[!]")
|
//usage: IF_FEATURE_MDEV_RENAME(" [>|=PATH]|[!]")
|
||||||
//usage: IF_FEATURE_MDEV_EXEC(" [@|$|*PROG]")
|
//usage: IF_FEATURE_MDEV_EXEC(" [@|$|*PROG]")
|
||||||
//usage: "\n"
|
//usage: "\n"
|
||||||
@ -233,6 +233,12 @@
|
|||||||
static const char keywords[] ALIGN1 = "add\0remove\0change\0";
|
static const char keywords[] ALIGN1 = "add\0remove\0change\0";
|
||||||
enum { OP_add, OP_remove };
|
enum { OP_add, OP_remove };
|
||||||
|
|
||||||
|
struct envmatch {
|
||||||
|
struct envmatch *next;
|
||||||
|
char *envname;
|
||||||
|
regex_t match;
|
||||||
|
};
|
||||||
|
|
||||||
struct rule {
|
struct rule {
|
||||||
bool keep_matching;
|
bool keep_matching;
|
||||||
bool regex_compiled;
|
bool regex_compiled;
|
||||||
@ -243,6 +249,7 @@ struct rule {
|
|||||||
char *ren_mov;
|
char *ren_mov;
|
||||||
IF_FEATURE_MDEV_EXEC(char *r_cmd;)
|
IF_FEATURE_MDEV_EXEC(char *r_cmd;)
|
||||||
regex_t match;
|
regex_t match;
|
||||||
|
struct envmatch *envmatch;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct globals {
|
struct globals {
|
||||||
@ -288,14 +295,48 @@ static void make_default_cur_rule(void)
|
|||||||
|
|
||||||
static void clean_up_cur_rule(void)
|
static void clean_up_cur_rule(void)
|
||||||
{
|
{
|
||||||
|
struct envmatch *e;
|
||||||
|
|
||||||
free(G.cur_rule.envvar);
|
free(G.cur_rule.envvar);
|
||||||
|
free(G.cur_rule.ren_mov);
|
||||||
if (G.cur_rule.regex_compiled)
|
if (G.cur_rule.regex_compiled)
|
||||||
regfree(&G.cur_rule.match);
|
regfree(&G.cur_rule.match);
|
||||||
free(G.cur_rule.ren_mov);
|
|
||||||
IF_FEATURE_MDEV_EXEC(free(G.cur_rule.r_cmd);)
|
IF_FEATURE_MDEV_EXEC(free(G.cur_rule.r_cmd);)
|
||||||
|
e = G.cur_rule.envmatch;
|
||||||
|
while (e) {
|
||||||
|
free(e->envname);
|
||||||
|
regfree(&e->match);
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
make_default_cur_rule();
|
make_default_cur_rule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *parse_envmatch_pfx(char *val)
|
||||||
|
{
|
||||||
|
struct envmatch **nextp = &G.cur_rule.envmatch;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
struct envmatch *e;
|
||||||
|
char *semicolon;
|
||||||
|
char *eq = strchr(val, '=');
|
||||||
|
if (!eq /* || eq == val? */)
|
||||||
|
return val;
|
||||||
|
if (endofname(val) != eq)
|
||||||
|
return val;
|
||||||
|
semicolon = strchr(eq, ';');
|
||||||
|
if (!semicolon)
|
||||||
|
return val;
|
||||||
|
/* ENVVAR=regex;... */
|
||||||
|
*nextp = e = xzalloc(sizeof(*e));
|
||||||
|
nextp = &e->next;
|
||||||
|
e->envname = xstrndup(val, eq - val);
|
||||||
|
*semicolon = '\0';
|
||||||
|
xregcomp(&e->match, eq + 1, REG_EXTENDED);
|
||||||
|
*semicolon = ';';
|
||||||
|
val = semicolon + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_next_rule(void)
|
static void parse_next_rule(void)
|
||||||
{
|
{
|
||||||
/* Note: on entry, G.cur_rule is set to default */
|
/* Note: on entry, G.cur_rule is set to default */
|
||||||
@ -314,6 +355,7 @@ static void parse_next_rule(void)
|
|||||||
val = tokens[0];
|
val = tokens[0];
|
||||||
G.cur_rule.keep_matching = ('-' == val[0]);
|
G.cur_rule.keep_matching = ('-' == val[0]);
|
||||||
val += G.cur_rule.keep_matching; /* swallow leading dash */
|
val += G.cur_rule.keep_matching; /* swallow leading dash */
|
||||||
|
val = parse_envmatch_pfx(val);
|
||||||
if (val[0] == '@') {
|
if (val[0] == '@') {
|
||||||
/* @major,minor[-minor2] */
|
/* @major,minor[-minor2] */
|
||||||
/* (useful when name is ambiguous:
|
/* (useful when name is ambiguous:
|
||||||
@ -328,8 +370,10 @@ static void parse_next_rule(void)
|
|||||||
if (sc == 2)
|
if (sc == 2)
|
||||||
G.cur_rule.min1 = G.cur_rule.min0;
|
G.cur_rule.min1 = G.cur_rule.min0;
|
||||||
} else {
|
} else {
|
||||||
|
char *eq = strchr(val, '=');
|
||||||
if (val[0] == '$') {
|
if (val[0] == '$') {
|
||||||
char *eq = strchr(++val, '=');
|
/* $ENVVAR=regex ... */
|
||||||
|
val++;
|
||||||
if (!eq) {
|
if (!eq) {
|
||||||
bb_error_msg("bad $envvar=regex on line %d", G.parser->lineno);
|
bb_error_msg("bad $envvar=regex on line %d", G.parser->lineno);
|
||||||
goto next_rule;
|
goto next_rule;
|
||||||
@ -423,6 +467,21 @@ static const struct rule *next_rule(void)
|
|||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int env_matches(struct envmatch *e)
|
||||||
|
{
|
||||||
|
while (e) {
|
||||||
|
int r;
|
||||||
|
char *val = getenv(e->envname);
|
||||||
|
if (!val)
|
||||||
|
return 0;
|
||||||
|
r = regexec(&e->match, val, /*size*/ 0, /*range[]*/ NULL, /*eflags*/ 0);
|
||||||
|
if (r != 0) /* no match */
|
||||||
|
return 0;
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# define next_rule() (&G.cur_rule)
|
# define next_rule() (&G.cur_rule)
|
||||||
@ -537,6 +596,8 @@ static void make_device(char *device_name, char *path, int operation)
|
|||||||
rule = next_rule();
|
rule = next_rule();
|
||||||
|
|
||||||
#if ENABLE_FEATURE_MDEV_CONF
|
#if ENABLE_FEATURE_MDEV_CONF
|
||||||
|
if (!env_matches(rule->envmatch))
|
||||||
|
continue;
|
||||||
if (rule->maj >= 0) { /* @maj,min rule */
|
if (rule->maj >= 0) { /* @maj,min rule */
|
||||||
if (major != rule->maj)
|
if (major != rule->maj)
|
||||||
continue;
|
continue;
|
||||||
@ -749,8 +810,10 @@ static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
|
|||||||
if (1 == depth) {
|
if (1 == depth) {
|
||||||
free(G.subsystem);
|
free(G.subsystem);
|
||||||
G.subsystem = strrchr(fileName, '/');
|
G.subsystem = strrchr(fileName, '/');
|
||||||
if (G.subsystem)
|
if (G.subsystem) {
|
||||||
G.subsystem = xstrdup(G.subsystem + 1);
|
G.subsystem = xstrdup(G.subsystem + 1);
|
||||||
|
xsetenv("SUBSYSTEM", G.subsystem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
|
return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
|
||||||
@ -843,8 +906,8 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
xchdir("/dev");
|
xchdir("/dev");
|
||||||
|
|
||||||
if (argv[1] && strcmp(argv[1], "-s") == 0) {
|
if (argv[1] && strcmp(argv[1], "-s") == 0) {
|
||||||
/* Scan:
|
/*
|
||||||
* mdev -s
|
* Scan: mdev -s
|
||||||
*/
|
*/
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@ -856,6 +919,8 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
G.root_major = major(st.st_dev);
|
G.root_major = major(st.st_dev);
|
||||||
G.root_minor = minor(st.st_dev);
|
G.root_minor = minor(st.st_dev);
|
||||||
|
|
||||||
|
putenv((char*)"ACTION=add");
|
||||||
|
|
||||||
/* ACTION_FOLLOWLINKS is needed since in newer kernels
|
/* ACTION_FOLLOWLINKS is needed since in newer kernels
|
||||||
* /sys/block/loop* (for example) are symlinks to dirs,
|
* /sys/block/loop* (for example) are symlinks to dirs,
|
||||||
* not real directories.
|
* not real directories.
|
||||||
|
Loading…
Reference in New Issue
Block a user