-
-
Notifications
You must be signed in to change notification settings - Fork 50
/
options-processing.cc
96 lines (83 loc) · 3.67 KB
/
options-processing.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <vector>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include "options-processing.h"
const char *service_dir_opt::user_home_path = nullptr;
const char *service_dir_opt::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;
}
void service_dir_opt::build_paths(bool am_system_init)
{
if (service_dirs.empty()) {
bool home_service_dir_set = false;
/* service directory name */
if (!am_system_init) {
const char * xdg_config_home = getenv("XDG_CONFIG_HOME");
size_t xdg_config_home_len;
if (xdg_config_home != nullptr && *xdg_config_home != '\0') {
xdg_config_home_len = strlen(xdg_config_home);
if (xdg_config_home[xdg_config_home_len - 1] == '/') {
// strip any trailing slash
--xdg_config_home_len;
}
size_t dinit_d_len = strlen("/dinit.d");
size_t full_len = xdg_config_home_len + dinit_d_len + 1;
char *service_dir_w = new char[full_len];
std::memcpy(service_dir_w, xdg_config_home, xdg_config_home_len);
std::memcpy(service_dir_w + xdg_config_home_len, "/dinit.d", dinit_d_len);
service_dir_w[full_len - 1] = 0;
service_dir_paths.emplace_back(service_dir_w, /*dyn_allocd=*/true);
home_service_dir_set = true;
}
const char * user_home = get_user_home();
if (user_home != nullptr && *user_home != '\0') {
size_t user_home_len = strlen(user_home);
if (xdg_config_home != nullptr && *xdg_config_home != '\0'
&& xdg_config_home_len == (user_home_len + strlen("/.config"))
&& strncmp(xdg_config_home, user_home, user_home_len) == 0
&& strcmp(xdg_config_home + user_home_len, "/.config") == 0) {
// don't add duplicate directories:
goto done_user_home;
}
size_t dinit_d_len = strlen("/.config/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, "/.config/dinit.d", dinit_d_len);
service_dir_w[full_len - 1] = 0;
service_dir_paths.emplace_back(service_dir_w, /*dyn_allocd=*/true);
home_service_dir_set = true;
}
}
done_user_home:
if (home_service_dir_set) {
service_dir_paths.emplace_back("/etc/dinit.d/user", /*dyn_allocd=*/false);
service_dir_paths.emplace_back("/usr/lib/dinit.d/user", /*dyn_allocd=*/false);
service_dir_paths.emplace_back("/usr/local/lib/dinit.d/user", /*dyn_allocd=*/false);
}
else {
service_dir_paths.emplace_back("/etc/dinit.d", /*dyn_allocd=*/false);
service_dir_paths.emplace_back("/run/dinit.d", false);
service_dir_paths.emplace_back("/usr/local/lib/dinit.d", false);
service_dir_paths.emplace_back("/lib/dinit.d", false);
}
}
else {
for (const char *dir : service_dirs) {
service_dir_paths.emplace_back(dir, /*dyn_allocd=*/false);
}
}
}