Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be5bb1d4 authored by David Ng's avatar David Ng Committed by Steve Kondik
Browse files

init: Add "export_rc" command to export env from a specified file

New export_rc command to import environment variables from
a specified file at the time the command is executed.

Differences between "import" and "export_rc":
1) export_rc can only import environment vars
2) export_rc is performed when the command
   is executed rather than at the time the
   command is parsed (i.e. "import")

Example:
in /init.rc:
    on post-fs
        export_rc /system/etc/init.xyz.rc

in /system/etc/init.xyz.rc:
    export LD_PRELOAD /system/lib/libxyz.so

Change-Id: If616dea5b508c27e9f7a95b5e9db696ecea2fdee
parent 39948802
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
@@ -54,6 +55,7 @@
void add_environment(const char *name, const char *value);

extern int init_module(void *, unsigned long, const char *);
extern int init_export_rc_file(const char *);

static int write_file(const char *path, const char *value)
{
@@ -221,6 +223,23 @@ int do_class_reset(int nargs, char **args)
    return 0;
}

int do_export_rc(int nargs, char **args)
{
        /* Import environments from a specified file.
         * The file content is of the form:
         *     export <env name> <value>
         * e.g.
         *     export LD_PRELOAD /system/lib/xyz.so
         *     export PROMPT abcde
         * Differences between "import" and "export_rc":
         * 1) export_rc can only import environment vars
         * 2) export_rc is performed when the command
         *    is executed rather than at the time the
         *    command is parsed (i.e. "import")
         */
    return init_export_rc_file(args[1]);
}

int do_domainname(int nargs, char **args)
{
    return write_file("/proc/sys/kernel/domainname", args[1]);
+60 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ static void parse_line_service(struct parse_state *state, int nargs, char **args
static void *parse_action(struct parse_state *state, int nargs, char **args);
static void parse_line_action(struct parse_state *state, int nargs, char **args);

void add_environment(const char *name, const char *value);

#define SECTION 0x01
#define COMMAND 0x02
#define OPTION  0x04
@@ -100,6 +102,7 @@ int lookup_keyword(const char *s)
    case 'e':
        if (!strcmp(s, "xec")) return K_exec;
        if (!strcmp(s, "xport")) return K_export;
        if (!strcmp(s, "xport_rc")) return K_export_rc;
        break;
    case 'g':
        if (!strcmp(s, "roup")) return K_group;
@@ -409,6 +412,63 @@ int init_parse_config_file(const char *fn)
    return 0;
}

typedef enum {
    ENV_NOTREADY,
    ENV_NAME,
    ENV_VALUE,
    ENV_WAITFORNEXTLINE,
} export_rc_state_t;

int init_export_rc_file(const char *fn)
{
    char *data;
    struct parse_state state;
    char *env = NULL;
    export_rc_state_t env_state = ENV_NOTREADY;

    data = read_file(fn, 0);
    if (!data) return -1;

    state.filename = fn;
    state.line = 0;
    state.ptr = data;
    state.nexttoken = 0;
    state.parse_line = parse_line_no_op;
    for (;;) {
        switch (next_token(&state)) {
        case T_EOF:
            free(data);
            return 0;
        case T_NEWLINE:
            env_state = ENV_NOTREADY;
            break;
        case T_TEXT:
            switch (env_state) {
            case ENV_NOTREADY:
                if (strcmp(state.text, "export") == 0) {
                    env_state = ENV_NAME;
                } else {
                    env_state = ENV_WAITFORNEXTLINE;
                }
                break;
            case ENV_NAME:
                env = state.text;
                env_state = ENV_VALUE;
                break;
            case ENV_VALUE:
                add_environment(env, state.text);
                env_state = ENV_WAITFORNEXTLINE;
                break;
            default:
                break;
            }
            break;
        }
    }

    return 0;
}

static int valid_name(const char *name)
{
    if (strlen(name) > 16) {
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ int do_class_reset(int nargs, char **args);
int do_domainname(int nargs, char **args);
int do_exec(int nargs, char **args);
int do_export(int nargs, char **args);
int do_export_rc(int nargs, char **args);
int do_hostname(int nargs, char **args);
int do_ifup(int nargs, char **args);
int do_insmod(int nargs, char **args);
@@ -55,6 +56,7 @@ enum {
    KEYWORD(domainname,  COMMAND, 1, do_domainname)
    KEYWORD(exec,        COMMAND, 1, do_exec)
    KEYWORD(export,      COMMAND, 2, do_export)
    KEYWORD(export_rc,   COMMAND, 1, do_export_rc)
    KEYWORD(group,       OPTION,  0, 0)
    KEYWORD(hostname,    COMMAND, 1, do_hostname)
    KEYWORD(ifup,        COMMAND, 1, do_ifup)