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).
log_flush_timer_t log_flush_timer;
}
+// Main entry point
int dinit_main(int argc, char **argv)
{
using namespace std;
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";
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()));
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:
using service_set_t = std::map<std::string, service_record *>;
service_record *load_service(service_set_t &services, const std::string &name,
- const std::vector<dir_entry> &service_dirs);
+ const service_dir_pathlist &service_dirs);
// Add some missing standard library functionality...
template <typename T> bool contains(std::vector<T> vec, const T& elem)
{
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<std::string> 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<dir_entry> 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");
// - 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) {
}
}
- // check for circular dependencies
+ // TODO check for circular dependencies
return 0;
}
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<dir_entry> &service_dirs)
+ const service_dir_pathlist &service_dirs)
{
using namespace std;
using namespace dinit_load;
service_dirs.emplace_back(service_dir_p, dyn_allocd);
}
- size_t size()
+ size_t size() const
{
return service_dirs.size();
}
return service_dirs[index];
}
- std::vector<dir_entry>::iterator begin()
+ std::vector<dir_entry>::const_iterator begin() const
{
return service_dirs.begin();
}
- std::vector<dir_entry>::iterator end()
+ std::vector<dir_entry>::const_iterator end() const
{
return service_dirs.end();
}
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;
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;