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

Commit f13b1b31 authored by Lee Campbell's avatar Lee Campbell
Browse files

init: Adding support to import directories

Support added so init scripts can now import directories.

BUG: 22721249
Change-Id: I02b566bfb50ea84469f1ea0c6ad205435a1df286
TEST: Tested importing a folder on arm64 emulator
parent 5f3b05ad
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1057,7 +1057,7 @@ int main(int argc, char** argv) {
    property_load_boot_defaults();
    start_property_service();

    init_parse_config_file("/init.rc");
    init_parse_config("/init.rc");

    action_for_each_trigger("early-init", action_add_queue_tail);

+33 −3
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
@@ -32,6 +33,7 @@
#include "property_service.h"
#include "util.h"

#include <base/stringprintf.h>
#include <cutils/iosched_policy.h>
#include <cutils/list.h>

@@ -385,15 +387,15 @@ static void parse_config(const char *fn, const std::string& data)
parser_done:
    list_for_each(node, &import_list) {
         struct import* import = node_to_item(node, struct import, list);
         if (!init_parse_config_file(import->filename)) {
         if (!init_parse_config(import->filename)) {
             ERROR("could not import file '%s' from '%s': %s\n",
                   import->filename, fn, strerror(errno));
         }
    }
}

bool init_parse_config_file(const char* path) {
    INFO("Parsing %s...\n", path);
static bool init_parse_config_file(const char* path) {
    INFO("Parsing file %s...\n", path);
    Timer t;
    std::string data;
    if (!read_file(path, &data)) {
@@ -408,6 +410,34 @@ bool init_parse_config_file(const char* path) {
    return true;
}

static bool init_parse_config_dir(const char* path) {
    INFO("Parsing directory %s...\n", path);
    std::unique_ptr<DIR, int(*)(DIR*)> config_dir(opendir(path), closedir);
    if (!config_dir) {
        ERROR("Could not import directory '%s'\n", path);
        return false;
    }
    dirent* current_file;
    while ((current_file = readdir(config_dir.get()))) {
        std::string current_path =
            android::base::StringPrintf("%s/%s", path, current_file->d_name);
        // Ignore directories and only process regular files.
        if (current_file->d_type == DT_REG) {
            if (!init_parse_config_file(current_path.c_str())) {
                ERROR("could not import file '%s'\n", current_path.c_str());
            }
        }
    }
    return true;
}

bool init_parse_config(const char* path) {
    if (is_dir(path)) {
        return init_parse_config_dir(path);
    }
    return init_parse_config_file(path);
}

static int valid_name(const char *name)
{
    if (strlen(name) > 16) {
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ void queue_property_triggers(const char *name, const char *value);
void queue_all_property_triggers();
void queue_builtin_action(int (*func)(int nargs, char **args), const char *name);

bool init_parse_config_file(const char* path);
bool init_parse_config(const char* path);
int expand_props(const char *src, std::string *dst);

service* make_exec_oneshot_service(int argc, char** argv);
+4 −1
Original line number Diff line number Diff line
@@ -197,8 +197,11 @@ hostname <name>
ifup <interface>
   Bring the network interface <interface> online.

import <filename>
import <path>
   Parse an init config file, extending the current configuration.
   If <path> is a directory, each file in the directory is parsed as
   a config file. It is not recursive, nested directories will
   not be parsed.

insmod <path>
   Install the module at <path>
+11 −0
Original line number Diff line number Diff line
@@ -465,3 +465,14 @@ std::string bytes_to_hex(const uint8_t* bytes, size_t bytes_len) {
        android::base::StringAppendF(&hex, "%02x", bytes[i]);
    return hex;
}

/*
 * Returns true is pathname is a directory
 */
bool is_dir(const char* pathname) {
    struct stat info;
    if (stat(pathname, &info) == -1) {
        return false;
    }
    return S_ISDIR(info.st_mode);
}
Loading