Hotplug2 has a strict separation between environment variables and
event variables.  When you write %<VARNAME>% in a rule, it only looks up
the vars provided with the event, not the environment.  Inversely, the
`setenv' rules only change the environment.

The only connection between the two is that event variables are also
added to the environment (which is passed to external programs).

This is very restrictive.  The patch below changes it to bring the two
sets of variables together.  The main purpose is to be able to write
rules such as:

    DEVPATH is set {
            setenv FILEMODE 0644
    }
    DEVICENAME ~~ (null|full|ptmx|tty|zero|gpio) {
            setenv FILEMODE 0666
    }
    DEVICENAME ~~ (controlC[0-9]|pcmC0D0*|timer) {
            setenv DEVICENAME snd/%DEVICENAME%
    }
    DEVICENAME == device-mapper {
            setenv DEVICENAME mapper/control
            setenv FILEMODE 0600
    }
    # Now the DEVICENAME and FILEMODE are hopefully set,
    # so we can create (or remove) the corresponding /dev file.
    DEVPATH is set, ACTION == add {
            makedev /dev/%DEVICENAME% %FILEMODE%
    }
    DEVPATH is set, ACTION == remove, MAJOR is set, MINOR is set {
            remove /dev/%DEVICENAME%
    }

hotplug2-0.9 is basically "dead" and hotplug-1.0 has significantly
changed the relevant code.  I do not yet have a corresponding patch for
hotplug-1.0, but hotplug2's author is interested in incorporating
this idea.  But in the mean time, until OpenWRT moves to hotplug2-1.0,
I think this patch is a significant improvement.

Just place this patch into package/hotplug2/patches/130-unify-vars.patch


        Stefan


=== modified file 'hotplug2-0.9/hotplug2.c'
--- hotplug2-0.9/hotplug2.c     2009-01-14 17:01:35 +0000
+++ hotplug2-0.9/hotplug2.c     2009-01-14 17:06:33 +0000
@@ -353,6 +353,9 @@
 void perform_action(struct hotplug2_event_t *event, struct rules_t *rules) {
        int i, rv;
        
+       for (i = 0; i < event->env_vars_c; i++)
+               setenv(event->env_vars[i].key, event->env_vars[i].value, 1);
+       
        for (i = 0; i < rules->rules_c; i++) {
                rv = rule_execute(event, &rules->rules[i]);
                if (rv == -1)

=== modified file 'hotplug2-0.9/rules.c'
--- hotplug2-0.9/rules.c        2009-01-14 17:01:35 +0000
+++ hotplug2-0.9/rules.c        2009-01-14 17:21:24 +0000
@@ -196,7 +196,7 @@
  *
  * Returns: Newly allocated haystack (old is freed)
  */
-static char *replace_key_by_value(char *hay, struct hotplug2_event_t *event) {
+static char *replace_key_by_value(char *hay) {
        char *sptr = hay, *ptr = hay;
        char *buf, *replacement;
        
@@ -208,7 +208,7 @@
                        memcpy(buf, sptr, ptr - sptr + 1);
                        
                        buf[ptr - sptr] = '\0';
-                       replacement = get_hotplug2_value_by_key(event, &buf[1]);
+                       replacement = getenv(&buf[1]);
                        buf[ptr - sptr] = '%';
                        
                        if (replacement != NULL) {
@@ -244,25 +244,25 @@
        char *subsystem, *major, *minor, *devpath;
        int rv = 1;
        
-       major = get_hotplug2_value_by_key(event, "MAJOR");
+       major = getenv("MAJOR");
        if (major == NULL)
                goto return_value;
        
-       minor = get_hotplug2_value_by_key(event, "MINOR");
+       minor = getenv("MINOR");
        if (minor == NULL)
                goto return_value;
        
-       devpath = get_hotplug2_value_by_key(event, "DEVPATH");
+       devpath = getenv("DEVPATH");
        if (devpath == NULL)
                goto return_value;
        
-       subsystem = get_hotplug2_value_by_key(event, "SUBSYSTEM");
+       subsystem = getenv("SUBSYSTEM");
        if (!strcmp(subsystem, "block"))
                devmode |= S_IFBLK;
        else
                devmode |= S_IFCHR;
        
-       path = replace_key_by_value(path, event);
+       path = replace_key_by_value(path);
        mkdir_p(path);
        rv = mknod(path, devmode, makedev(atoi(major), atoi(minor)));
 
@@ -295,9 +295,9 @@
                case -1:
                        return -1;
                case 0:
-                       application = replace_key_by_value(strdup(application), 
event);
+                       application = replace_key_by_value(strdup(application));
                        for (i = 0; argv[i] != NULL; i++) {
-                               argv[i] = replace_key_by_value(argv[i], event);
+                               argv[i] = replace_key_by_value(argv[i]);
                        }
                        execvp(application, argv);
                        exit(127);
@@ -322,7 +322,7 @@
 static int exec_shell(struct hotplug2_event_t *event, char *application) {
        int rv;
        
-       application = replace_key_by_value(strdup(application), event);
+       application = replace_key_by_value(strdup(application));
        rv = WEXITSTATUS(system(application));
        free(application);
        return rv;
@@ -340,8 +340,8 @@
 static int make_symlink(struct hotplug2_event_t *event, char *target, char 
*linkname) {
        int rv;
        
-       target = replace_key_by_value(strdup(target), event);
-       linkname = replace_key_by_value(strdup(linkname), event);
+       target = replace_key_by_value(strdup(target));
+       linkname = replace_key_by_value(strdup(linkname));
        
        mkdir_p(linkname);
        rv = symlink(target, linkname);
@@ -364,8 +364,8 @@
 static int chmod_file(struct hotplug2_event_t *event, char *file, char *value) 
{
        int rv;
 
-       file = replace_key_by_value(strdup(file), event);
-       value = replace_key_by_value(strdup(value), event);
+       file = replace_key_by_value(strdup(file));
+       value = replace_key_by_value(strdup(value));
 
        rv = chmod(file, strtoul(value, 0, 8));
 
@@ -391,8 +391,8 @@
        struct passwd *pwd;
        int rv;
 
-       file = replace_key_by_value(strdup(file), event);
-       param = replace_key_by_value(strdup(param), event);
+       file = replace_key_by_value(strdup(file));
+       param = replace_key_by_value(strdup(param));
 
        rv = -1;
 
@@ -493,6 +493,7 @@
  */
 int rule_execute(struct hotplug2_event_t *event, struct rule_t *rule) {
        int i, last_rv;
+       char *arg;
        
        for (i = 0; i < rule->conditions_c; i++) {
                if (rule_condition_eval(event, &(rule->conditions[i])) != 
EVAL_MATCH)
@@ -501,9 +502,6 @@
        
        last_rv = 0;
        
-       for (i = 0; i < event->env_vars_c; i++)
-               setenv(event->env_vars[i].key, event->env_vars[i].value, 1);
-       
        for (i = 0; i < rule->actions_c; i++) {
                switch (rule->actions[i].type) {
                        case ACT_STOP_PROCESSING:
@@ -521,7 +519,9 @@
                                        return -1;
                                break;
                        case ACT_MAKE_DEVICE:
-                               last_rv = make_dev_from_event(event, 
rule->actions[i].parameter[0], strtoul(rule->actions[i].parameter[1], NULL, 0));
+                               arg = 
replace_key_by_value(strdup(rule->actions[i].parameter[1]));
+                               last_rv = make_dev_from_event(event, 
rule->actions[i].parameter[0], strtoul(arg, NULL, 0));
+                               free(arg);
                                break;
                        case ACT_CHMOD:
                                last_rv = chmod_file(event, 
rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
@@ -540,11 +540,15 @@
                                last_rv = exec_noshell(event, 
rule->actions[i].parameter[0], rule->actions[i].parameter);
                                break;
                        case ACT_SETENV:
-                               last_rv = setenv(rule->actions[i].parameter[0], 
rule->actions[i].parameter[1], 1);
+                               arg = 
replace_key_by_value(strdup(rule->actions[i].parameter[1]));
+                               last_rv = setenv(rule->actions[i].parameter[0], 
arg, 1);
+                               free(arg);
                                break;
                        case ACT_REMOVE:
-                               last_rv = unlink(rule->actions[i].parameter[0]);
-                               rmdir_p(rule->actions[i].parameter[0]);
+                               arg = 
replace_key_by_value(strdup(rule->actions[i].parameter[0]));
+                               last_rv = unlink(arg);
+                               rmdir_p(arg);
+                               free(arg);
                                break;
                        case ACT_DEBUG:
                                print_debug(event);


_______________________________________________
openwrt-devel mailing list
[email protected]
http://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to