From c9e461d98277237145e162fa209bd7d6c79e9cfd Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Fri, 15 Nov 2019 19:39:27 +0000 Subject: [PATCH] Use common option processing for dinit/dinitcheck service dir --- src/Makefile | 4 +- src/dinit.cc | 23 ++------- src/dinitcheck.cc | 83 +++++++++++-------------------- src/includes/options-processing.h | 13 ++--- src/options-processing.cc | 2 +- 5 files changed, 41 insertions(+), 84 deletions(-) diff --git a/src/Makefile b/src/Makefile index 4a5f07c..8d96318 100644 --- a/src/Makefile +++ b/src/Makefile @@ -41,8 +41,8 @@ dinit: $(dinit_objects) dinitctl: dinitctl.o $(CXX) -o dinitctl dinitctl.o $(LDFLAGS) -dinitcheck: dinitcheck.o - $(CXX) -o dinitcheck dinitcheck.o $(LDFLAGS) +dinitcheck: dinitcheck.o options-processing.o + $(CXX) -o dinitcheck dinitcheck.o options-processing.o $(LDFLAGS) shutdown: shutdown.o $(CXX) -o shutdown shutdown.o $(LDFLAGS) diff --git a/src/dinit.cc b/src/dinit.cc index 8fb405a..7de6156 100644 --- a/src/dinit.cc +++ b/src/dinit.cc @@ -86,27 +86,9 @@ static const char *env_file_path = "/etc/dinit/environment"; static const char *log_path = "/dev/log"; static bool log_is_syslog = true; // if false, log is a file -static const char *user_home_path = nullptr; - // Set to true (when console_input_watcher is active) if console input becomes available static bool console_input_ready = false; -// Get user home (and set user_home_path). (The return may become invalid after -// changing the environment (HOME variable) or using the getpwuid() function). -static const char * get_user_home() -{ - if (user_home_path == nullptr) { - user_home_path = getenv("HOME"); - if (user_home_path == nullptr) { - struct passwd * pwuid_p = getpwuid(getuid()); - if (pwuid_p != nullptr) { - user_home_path = pwuid_p->pw_dir; - } - } - } - return user_home_path; -} - namespace { // Event-loop handler for a signal, which just delegates to a function (pointer). @@ -192,6 +174,7 @@ namespace { log_flush_timer_t log_flush_timer; } +// Main entry point int dinit_main(int argc, char **argv) { using namespace std; @@ -344,7 +327,7 @@ int dinit_main(int argc, char **argv) signal(SIGPIPE, SIG_IGN); if (! am_system_init && ! control_socket_path_set) { - const char * userhome = get_user_home(); + const char * userhome = service_dir_opt::get_user_home(); if (userhome != nullptr) { control_socket_str = userhome; control_socket_str += "/.dinitctl"; @@ -402,7 +385,7 @@ int dinit_main(int argc, char **argv) log_flush_timer.add_timer(event_loop, dasynq::clock_type::MONOTONIC); - service_dir_opts.build_paths(); + service_dir_opts.build_paths(am_system_init); /* start requested services */ services = new dirload_service_set(std::move(service_dir_opts.get_paths())); diff --git a/src/dinitcheck.cc b/src/dinitcheck.cc index 04c9fd7..7fb74f7 100644 --- a/src/dinitcheck.cc +++ b/src/dinitcheck.cc @@ -24,24 +24,7 @@ using string = std::string; using string_iterator = std::string::iterator; -static const char *user_home_path = nullptr; - -// Get user home (and set user_home_path). (The return may become invalid after -// changing the environment (HOME variable) or using the getpwuid() function). -static const char * get_user_home() -{ - if (user_home_path == nullptr) { - user_home_path = getenv("HOME"); - if (user_home_path == nullptr) { - struct passwd * pwuid_p = getpwuid(getuid()); - if (pwuid_p != nullptr) { - user_home_path = pwuid_p->pw_dir; - } - } - } - return user_home_path; -} - +// prelim_dep: A preliminary (unresolved) service dependency class prelim_dep { public: @@ -67,7 +50,7 @@ public: using service_set_t = std::map; service_record *load_service(service_set_t &services, const std::string &name, - const std::vector &service_dirs); + const service_dir_pathlist &service_dirs); // Add some missing standard library functionality... template bool contains(std::vector vec, const T& elem) @@ -79,44 +62,33 @@ int main(int argc, char **argv) { using namespace std; - bool add_all_service_dirs = false; - bool for_system = false; - const char * service_dir = nullptr; - bool service_dir_dynamic = false; // service_dir dynamically allocated? + service_dir_opt service_dir_opts; + bool am_system_init = (getuid() == 0); std::vector services_to_check; - // Figure out service dirs - /* service directory name */ - if (service_dir == nullptr && ! for_system) { - const char * userhome = get_user_home(); - if (userhome != nullptr) { - const char * user_home = get_user_home(); - size_t user_home_len = strlen(user_home); - size_t dinit_d_len = strlen("/dinit.d"); - size_t full_len = user_home_len + dinit_d_len + 1; - char *service_dir_w = new char[full_len]; - std::memcpy(service_dir_w, user_home, user_home_len); - std::memcpy(service_dir_w + user_home_len, "/dinit.d", dinit_d_len); - service_dir_w[full_len - 1] = 0; - - service_dir = service_dir_w; - service_dir_dynamic = true; + // Process command line + if (argc > 1) { + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + if (argv[i][0] == '-') { + // An option... + if (strcmp(argv[i], "--services-dir") == 0 || strcmp(argv[i], "-d") == 0) { + if (++i < argc) { + service_dir_opts.set_specified_service_dir(argv[i]); + } + else { + cerr << "dinitcheck: '--services-dir' (-d) requires an argument" << endl; + return 1; + } + } + } + // TODO handle other options, err if unrecognized + } } } - if (service_dir == nullptr) { - service_dir = "/etc/dinit.d"; - add_all_service_dirs = true; - } - - std::vector service_dirs; - - service_dirs.emplace_back(service_dir, service_dir_dynamic); - if (add_all_service_dirs) { - service_dirs.emplace_back("/usr/local/lib/dinit.d", false); - service_dirs.emplace_back("/lib/dinit.d", false); - } + service_dir_opts.build_paths(am_system_init); // Temporary, for testing: services_to_check.push_back("boot"); @@ -127,11 +99,11 @@ int main(int argc, char **argv) // - load the service, store dependencies as strings // - recurse - // additional: check chain-to, other lint + // TODO additional: check chain-to, other lint for (const auto &name : services_to_check) { try { - service_record *sr = load_service(service_set, name, service_dirs); + service_record *sr = load_service(service_set, name, service_dir_opts.get_paths()); service_set[name] = sr; // add dependencies to services_to_check for (auto &dep : sr->dependencies) { @@ -145,7 +117,7 @@ int main(int argc, char **argv) } } - // check for circular dependencies + // TODO check for circular dependencies return 0; } @@ -201,8 +173,9 @@ static void process_dep_dir(const char *servicename, closedir(depdir); } +// TODO: this is pretty much copy-paste from load_service.cc. Need to factor out common structure. service_record *load_service(service_set_t &services, const std::string &name, - const std::vector &service_dirs) + const service_dir_pathlist &service_dirs) { using namespace std; using namespace dinit_load; diff --git a/src/includes/options-processing.h b/src/includes/options-processing.h index dba724e..e591dca 100644 --- a/src/includes/options-processing.h +++ b/src/includes/options-processing.h @@ -55,7 +55,7 @@ public: service_dirs.emplace_back(service_dir_p, dyn_allocd); } - size_t size() + size_t size() const { return service_dirs.size(); } @@ -65,12 +65,12 @@ public: return service_dirs[index]; } - std::vector::iterator begin() + std::vector::const_iterator begin() const { return service_dirs.begin(); } - std::vector::iterator end() + std::vector::const_iterator end() const { return service_dirs.end(); } @@ -81,8 +81,6 @@ class service_dir_opt const char *service_dir = nullptr;; bool service_dir_dynamic = false; - bool am_system_init; - static const char *user_home_path; service_dir_pathlist service_dir_paths; @@ -97,8 +95,11 @@ public: service_dir = specified_dir; } - void build_paths(); + // Build the set of service directory paths, as per configuration specified thus far. This might be a + // single specified path, or a set of default paths. + void build_paths(bool am_system_init); + // Get the service directory paths as a (mutable) collection. Call only after calling build_paths(). service_dir_pathlist &get_paths() { return service_dir_paths; diff --git a/src/options-processing.cc b/src/options-processing.cc index c3a3d4f..3365b7d 100644 --- a/src/options-processing.cc +++ b/src/options-processing.cc @@ -25,7 +25,7 @@ const char * service_dir_opt::get_user_home() return user_home_path; } -void service_dir_opt::build_paths() +void service_dir_opt::build_paths(bool am_system_init) { /* service directory name */ if (service_dir == nullptr && ! am_system_init) { -- 2.25.1