options-processing.cc 3.7 KB

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