From c73766db40dcb9691424165ff587a22cc7cdaf75 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Fri, 20 Sep 2024 21:44:46 +0200 Subject: [PATCH] librc, rc, supervise-daemon: Repace hardcoded paths with function calls. This lays the groundwork for other features like user services, or a different root prefix, by allowing us to change where openrc looks up for files at runtime. As a side effect of this change, now all sysconfdirs (aka RC_PKG_PREFIX and RC_LOCAL_PREFIX) are checked for configuration files (rc.conf and rc.conf.d). --- src/librc/librc-daemon.c | 8 +- src/librc/librc-depend.c | 96 +++++++----- src/librc/librc-misc.c | 65 +++++--- src/librc/librc.c | 197 +++++++++++++----------- src/librc/rc.h.in | 16 ++ src/openrc-run/openrc-run.c | 65 ++++---- src/openrc/rc-logger.c | 26 ++-- src/openrc/rc.c | 82 ++++++---- src/shared/misc.c | 57 +++++-- src/shared/misc.h | 9 -- src/supervise-daemon/supervise-daemon.c | 2 +- 11 files changed, 365 insertions(+), 258 deletions(-) diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c index e23593b9a..f6a2acc7d 100644 --- a/src/librc/librc-daemon.c +++ b/src/librc/librc-daemon.c @@ -411,7 +411,7 @@ rc_service_daemon_set(const char *service, const char *exec, return false; } - xasprintf(&dirpath, RC_SVCDIR "/daemons/%s", basename_c(service)); + xasprintf(&dirpath, "%s/daemons/%s", rc_service_dir(), basename_c(service)); /* Regardless, erase any existing daemon info */ if ((dp = opendir(dirpath))) { @@ -491,7 +491,7 @@ rc_service_started_daemon(const char *service, if (!service || !exec) return false; - xasprintf(&dirpath, RC_SVCDIR "/daemons/%s", basename_c(service)); + xasprintf(&dirpath, "%s/daemons/%s", rc_service_dir(), basename_c(service)); match = _match_list(exec, argv, NULL); if (indx > 0) { @@ -543,8 +543,8 @@ rc_service_daemons_crashed(const char *service) char *ch_root; char *spidfile; - path += snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s", - basename_c(service)); + path += snprintf(dirpath, sizeof(dirpath), + "%s/daemons/%s", rc_service_dir(), basename_c(service)); if (!(dp = opendir(dirpath))) return false; diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c index a48a2ada0..e716207ef 100644 --- a/src/librc/librc-depend.c +++ b/src/librc/librc-depend.c @@ -35,8 +35,6 @@ #define GENDEP RC_LIBEXECDIR "/sh/gendepends.sh" -#define RC_DEPCONFIG RC_SVCDIR "/depconfig" - static const char *bootlevel = NULL; static char * @@ -149,7 +147,14 @@ make_deptree(void) { RC_DEPTREE * rc_deptree_load(void) { - return rc_deptree_load_file(RC_DEPTREE_CACHE); + char *deptree_cache; + RC_DEPTREE *deptree; + + xasprintf(&deptree_cache, "%s/deptree", rc_service_dir()); + deptree = rc_deptree_load_file(deptree_cache); + free(deptree_cache); + + return deptree; } RC_DEPTREE * @@ -689,19 +694,19 @@ static const DEPPAIR deppairs[] = { static const char *const depdirs[] = { - RC_SVCDIR, - RC_SVCDIR "/starting", - RC_SVCDIR "/started", - RC_SVCDIR "/stopping", - RC_SVCDIR "/inactive", - RC_SVCDIR "/wasinactive", - RC_SVCDIR "/failed", - RC_SVCDIR "/hotplugged", - RC_SVCDIR "/daemons", - RC_SVCDIR "/options", - RC_SVCDIR "/exclusive", - RC_SVCDIR "/scheduled", - RC_SVCDIR "/tmp", + "", + "starting", + "started", + "stopping", + "inactive", + "wasinactive", + "failed", + "hotplugged", + "daemons", + "options", + "exclusive", + "scheduled", + "tmp", NULL }; @@ -714,16 +719,23 @@ rc_deptree_update_needed(time_t *newest, char *file) int i; struct stat buf; time_t mtime; + char *dir; + char *deptree_cache, *depconfig; + const char *service_dir = rc_service_dir(); /* Create base directories if needed */ - for (i = 0; depdirs[i]; i++) - if (mkdir(depdirs[i], 0755) != 0 && errno != EEXIST) + for (i = 0; depdirs[i]; i++) { + xasprintf(&dir, "%s/%s", service_dir, depdirs[i]); + if (mkdir(dir, 0755) != 0 && errno != EEXIST) fprintf(stderr, "mkdir `%s': %s\n", depdirs[i], strerror(errno)); + free(dir); + } /* Quick test to see if anything we use has changed and we have * data in our deptree. */ - if (stat(RC_DEPTREE_CACHE, &buf) == 0) { + xasprintf(&deptree_cache, "%s/deptree", service_dir); + if (stat(deptree_cache, &buf) == 0) { mtime = buf.st_mtime; } else { /* No previous cache found. @@ -733,30 +745,26 @@ rc_deptree_update_needed(time_t *newest, char *file) newer = true; mtime = time(NULL); } - - newer |= !deep_mtime_check(RC_INITDIR,true,&mtime,file); - newer |= !deep_mtime_check(RC_CONFDIR,true,&mtime,file); -#ifdef RC_PKG_INITDIR - newer |= !deep_mtime_check(RC_PKG_INITDIR,true,&mtime,file); -#endif -#ifdef RC_PKG_CONFDIR - newer |= !deep_mtime_check(RC_PKG_CONFDIR,true,&mtime,file); -#endif -#ifdef RC_LOCAL_INITDIRs - newer |= !deep_mtime_check(RC_LOCAL_INITDIR,true,&mtime,file); -#endif -#ifdef RC_LOCAL_CONFDIR - newer |= !deep_mtime_check(RC_LOCAL_CONFDIR,true,&mtime,file); -#endif - newer |= !deep_mtime_check(RC_CONF,true,&mtime,file); + free(deptree_cache); + + for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) { + static const char *subdirs[] = { "init.d", "conf.d", "rc.conf", NULL }; + for (const char **subdir = subdirs; *subdir; subdir++) { + char *path; + xasprintf(&path, "%s/%s", *dirs, *subdir); + newer |= !deep_mtime_check(path, true, &mtime, file); + } + } /* Some init scripts dependencies change depending on config files * outside of baselayout, like syslog-ng, so we check those too. */ - config = rc_config_list(RC_DEPCONFIG); + xasprintf(&depconfig, "%s/depconfig", service_dir); + config = rc_config_list(depconfig); TAILQ_FOREACH(s, config, entries) { newer |= !deep_mtime_check(s->value, true, &mtime, file); } rc_stringlist_free(config); + free(depconfig); /* Return newest file time, if requested */ if ((newer) && (newest != NULL)) { @@ -791,6 +799,7 @@ rc_deptree_update(void) size_t len = 0; ssize_t size; char *depend, *depends, *service, *type; + char *deptree_cache, *depconfig; size_t i, l; bool retval = true; const char *sys = rc_sys(); @@ -1051,7 +1060,8 @@ rc_deptree_update(void) This works and should be entirely shell parseable provided that depend names don't have any non shell variable characters in */ - if ((fp = fopen(RC_DEPTREE_CACHE, "w"))) { + xasprintf(&deptree_cache, "%s/deptree", rc_service_dir()); + if ((fp = fopen(deptree_cache, "w"))) { i = 0; TAILQ_FOREACH(depinfo, deptree, entries) { fprintf(fp, "depinfo_%zu_service='%s'\n", i, depinfo->service); @@ -1066,24 +1076,26 @@ rc_deptree_update(void) } fclose(fp); } else { - fprintf(stderr, "fopen `%s': %s\n", - RC_DEPTREE_CACHE, strerror(errno)); + fprintf(stderr, "fopen '%s': %s\n", deptree_cache, strerror(errno)); retval = false; } + free(deptree_cache); /* Save our external config files to disk */ + xasprintf(&depconfig, "%s/depconfig", rc_service_dir()); if (TAILQ_FIRST(config)) { - if ((fp = fopen(RC_DEPCONFIG, "w"))) { + if ((fp = fopen(depconfig, "w"))) { TAILQ_FOREACH(s, config, entries) fprintf(fp, "%s\n", s->value); fclose(fp); } else { - fprintf(stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror(errno)); + fprintf(stderr, "fopen '%s': %s\n", depconfig, strerror(errno)); retval = false; } } else { - unlink(RC_DEPCONFIG); + unlink(depconfig); } + free(depconfig); rc_stringlist_free(config); rc_deptree_free(deptree); diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c index 6c0fcbe73..9dc2897df 100644 --- a/src/librc/librc-misc.c +++ b/src/librc/librc-misc.c @@ -327,7 +327,7 @@ static RC_STRINGLIST *rc_config_kcl(RC_STRINGLIST *config) return config; } -static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config) +static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config, char *dir) { DIR *dp; struct dirent *d; @@ -337,7 +337,7 @@ static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config) char path[PATH_MAX]; RC_STRING *line; - if ((dp = opendir(RC_CONF_D)) != NULL) { + if ((dp = opendir(dir)) != NULL) { rc_conf_d_files = rc_stringlist_new(); while ((d = readdir(dp)) != NULL) { if (fnmatch("*.conf", d->d_name, FNM_PATHNAME) == 0) { @@ -350,7 +350,7 @@ static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config) TAILQ_FOREACH(fname, rc_conf_d_files, entries) { if (!fname->value) continue; - sprintf(path, "%s/%s", RC_CONF_D, fname->value); + sprintf(path, "%s/%s", dir, fname->value); rc_conf_d_list = rc_config_list(path); TAILQ_FOREACH(line, rc_conf_d_list, entries) if (line->value) @@ -409,35 +409,52 @@ _free_rc_conf(void) rc_stringlist_free(rc_conf); } +static inline void +rc_conf_append(const char *file) +{ + RC_STRINGLIST *conf = rc_config_load(file); + TAILQ_CONCAT(rc_conf, conf, entries); + rc_stringlist_free(conf); +} + char * rc_conf_value(const char *setting) { - RC_STRINGLIST *old; RC_STRING *s; - char *p; - if (!rc_conf) { - rc_conf = rc_config_load(RC_CONF); - atexit(_free_rc_conf); + if (rc_conf) + return rc_config_value(rc_conf, setting); - /* Support old configs. */ - if (exists(RC_CONF_OLD)) { - old = rc_config_load(RC_CONF_OLD); - TAILQ_CONCAT(rc_conf, old, entries); - rc_stringlist_free(old); - } + rc_conf = rc_stringlist_new(); + atexit(_free_rc_conf); - rc_conf = rc_config_directory(rc_conf); - rc_conf = rc_config_kcl(rc_conf); + for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) { + char *conf; + xasprintf(&conf, "%s/%s", *dirs, "rc.conf"); + rc_conf_append(conf); + free(conf); + } - /* Convert old uppercase to lowercase */ - TAILQ_FOREACH(s, rc_conf, entries) { - p = s->value; - while (p && *p && *p != '=') { - if (isupper((unsigned char)*p)) - *p = tolower((unsigned char)*p); - p++; - } + /* Support old configs. */ + if (exists(RC_CONF_OLD)) + rc_conf_append(RC_CONF_OLD); + + for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) { + char *conf; + xasprintf(&conf, "%s/%s", *dirs, "rc.conf.d"); + rc_conf = rc_config_directory(rc_conf, conf); + free(conf); + } + + rc_conf = rc_config_kcl(rc_conf); + + /* Convert old uppercase to lowercase */ + TAILQ_FOREACH(s, rc_conf, entries) { + char *p = s->value; + while (p && *p && *p != '=') { + if (isupper((unsigned char)*p)) + *p = tolower((unsigned char)*p); + p++; } } diff --git a/src/librc/librc.c b/src/librc/librc.c index b54496410..4b86f69cf 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -39,8 +39,6 @@ # include #endif -#define RC_RUNLEVEL RC_SVCDIR "/softlevel" - #ifndef S_IXUGO # define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) #endif @@ -421,7 +419,7 @@ get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list, RC_STRINGLIS * We can now do exactly the above procedure for our chained * runlevels. */ - xasprintf(&path, "%s/%s", RC_RUNLEVELDIR, runlevel); + xasprintf(&path, "%s/%s", rc_runlevel_dir(), runlevel); dirs = ls_dir(path, LS_DIR); TAILQ_FOREACH(d, dirs, entries) { nextlevel = d->value; @@ -447,31 +445,44 @@ get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list, RC_STRINGLIS free(path); } +static bool +svcdir_subpath_exists(const char *subdir) +{ + char *path; + bool found; + xasprintf(&path, "%s/%s", rc_service_dir(), subdir); + found = exists(path); + free(path); + return found; +} + bool rc_runlevel_starting(void) { - return exists(RC_STARTING); + return svcdir_subpath_exists("rc.starting"); } bool rc_runlevel_stopping(void) { - return exists(RC_STOPPING); + return svcdir_subpath_exists("rc.stopping"); } RC_STRINGLIST *rc_runlevel_list(void) { - return ls_dir(RC_RUNLEVELDIR, LS_DIR); + return ls_dir(rc_runlevel_dir(), LS_DIR); } char * rc_runlevel_get(void) { FILE *fp; + char *softlevel; char *runlevel = NULL; size_t i; - if ((fp = fopen(RC_RUNLEVEL, "r"))) { + xasprintf(&softlevel, "%s/softlevel", rc_service_dir()); + if ((fp = fopen(softlevel, "r"))) { runlevel = xmalloc(sizeof(char) * PATH_MAX); if (fgets(runlevel, PATH_MAX, fp)) { i = strlen(runlevel) - 1; @@ -493,13 +504,19 @@ rc_runlevel_get(void) bool rc_runlevel_set(const char *runlevel) { - FILE *fp = fopen(RC_RUNLEVEL, "w"); + char *softlevel; + bool ret = false; + FILE *fp; - if (!fp) - return false; - fprintf(fp, "%s", runlevel); - fclose(fp); - return true; + xasprintf(&softlevel, "%s/softlevel", rc_service_dir()); + if ((fp = fopen(softlevel, "w"))) { + fprintf(fp, "%s", runlevel); + fclose(fp); + ret = true; + } + + free(softlevel); + return ret; } bool @@ -512,7 +529,7 @@ rc_runlevel_exists(const char *runlevel) if (!runlevel || strcmp(runlevel, "") == 0 || strcmp(runlevel, ".") == 0 || strcmp(runlevel, "..") == 0) return false; - xasprintf(&path, "%s/%s", RC_RUNLEVELDIR, runlevel); + xasprintf(&path, "%s/%s", rc_runlevel_dir(), runlevel); r = stat(path, &buf); free(path); if (r == 0 && S_ISDIR(buf.st_mode)) @@ -529,7 +546,7 @@ rc_runlevel_stack(const char *dst, const char *src) if (!rc_runlevel_exists(dst) || !rc_runlevel_exists(src)) return false; xasprintf(&s, "../%s", src); - xasprintf(&d, "%s/%s/%s", RC_RUNLEVELDIR, dst, src); + xasprintf(&d, "%s/%s/%s", rc_runlevel_dir(), dst, src); r = symlink(s, d); free(d); free(s); @@ -542,7 +559,7 @@ rc_runlevel_unstack(const char *dst, const char *src) char *path; int r; - xasprintf(&path, "%s/%s/%s", RC_RUNLEVELDIR, dst, src); + xasprintf(&path, "%s/%s/%s", rc_runlevel_dir(), dst, src); r = unlink(path); free(path); return (r == 0); @@ -560,6 +577,35 @@ rc_runlevel_stacks(const char *runlevel) return stack; } +static const char * const sysconfdirs[] = { +#ifdef RC_LOCAL_PREFIX + RC_LOCAL_PREFIX "/etc", +#endif + RC_SYSCONFDIR, +#ifdef RC_PKG_PREFIX + RC_PKG_PREFIX "/etc", +#endif + NULL +}; + +const char * const * +rc_sysconf_dirs(void) +{ + return sysconfdirs; +} + +const char * +rc_runlevel_dir(void) +{ + return RC_RUNLEVELDIR; +} + +const char * +rc_service_dir(void) +{ + return RC_SVCDIR; +} + static ssize_t safe_readlink(const char *path, char **buf, size_t bufsiz) { @@ -614,27 +660,12 @@ rc_service_resolve(const char *service) return buffer; } -#ifdef RC_LOCAL_INITDIR - /* Nope, so lets see if the user has written it */ - free(file); - xasprintf(&file, "%s/%s", RC_LOCAL_INITDIR, service); - if (stat(file, &buf) == 0) - return file; -#endif - - /* System scripts take precedence over 3rd party ones */ - free(file); - xasprintf(&file, "%s/%s", RC_INITDIR, service); - if (stat(file, &buf) == 0) - return file; - -#ifdef RC_PKG_INITDIR - /* Check RC_PKG_INITDIR */ - free(file); - xasprintf(&file, "%s/%s", RC_PKG_INITDIR, service); - if (stat(file, &buf) == 0) - return file; -#endif + for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) { + free(file); + xasprintf(&file, "%s/init.d/%s", *dirs, service); + if (stat(file, &buf) == 0) + return file; + } free(file); return NULL; @@ -754,8 +785,7 @@ rc_service_in_runlevel(const char *service, const char *runlevel) char *file; bool r; - xasprintf(&file, "%s/%s/%s", RC_RUNLEVELDIR, runlevel, - basename_c(service)); + xasprintf(&file, "%s/%s/%s", rc_runlevel_dir(), runlevel, basename_c(service)); r = exists(file); free(file); return r; @@ -769,6 +799,7 @@ rc_service_mark(const char *service, const RC_SERVICE state) int skip_state = -1; const char *base; char *init = rc_service_resolve(service); + const char *svcdir = rc_service_dir(); bool skip_wasinactive = false; int s; RC_STRINGLIST *dirs; @@ -785,8 +816,7 @@ rc_service_mark(const char *service, const RC_SERVICE state) return false; } - xasprintf(&file, "%s/%s/%s", RC_SVCDIR, - rc_parse_service_state(state), base); + xasprintf(&file, "%s/%s/%s", svcdir, rc_parse_service_state(state), base); if (exists(file)) unlink(file); i = symlink(init, file); @@ -813,16 +843,14 @@ rc_service_mark(const char *service, const RC_SERVICE state) s != RC_SERVICE_SCHEDULED) && (!skip_wasinactive || s != RC_SERVICE_WASINACTIVE)) { - xasprintf(&file, "%s/%s/%s", RC_SVCDIR, - rc_service_state_names[i].name, base); + xasprintf(&file, "%s/%s/%s", svcdir, rc_service_state_names[i].name, base); if (exists(file)) { if ((state == RC_SERVICE_STARTING || state == RC_SERVICE_STOPPING) && - s == RC_SERVICE_INACTIVE) + s == RC_SERVICE_INACTIVE) { - xasprintf(&was, "%s/%s/%s", RC_SVCDIR, - rc_parse_service_state(RC_SERVICE_WASINACTIVE), - base); + xasprintf(&was, "%s/%s/%s", svcdir, + rc_parse_service_state(RC_SERVICE_WASINACTIVE), base); i = symlink(init, was); free(was); if (i == -1) { @@ -847,18 +875,18 @@ rc_service_mark(const char *service, const RC_SERVICE state) state == RC_SERVICE_STOPPED || state == RC_SERVICE_INACTIVE) { - xasprintf(&file, "%s/%s/%s", RC_SVCDIR, "exclusive", base); + xasprintf(&file, "%s/%s/%s", svcdir, "exclusive", base); unlink(file); free(file); } /* Remove any options and daemons the service may have stored */ if (state == RC_SERVICE_STOPPED) { - xasprintf(&file, "%s/%s/%s", RC_SVCDIR, "options", base); + xasprintf(&file, "%s/%s/%s", svcdir, "options", base); rm_dir(file, true); free(file); - xasprintf(&file, "%s/%s/%s", RC_SVCDIR, "daemons", base); + xasprintf(&file, "%s/%s/%s", svcdir, "daemons", base); rm_dir(file, true); free(file); @@ -867,7 +895,7 @@ rc_service_mark(const char *service, const RC_SERVICE state) /* These are final states, so remove us from scheduled */ if (state == RC_SERVICE_STARTED || state == RC_SERVICE_STOPPED) { - xasprintf(&file, "%s/%s", RC_SVCDIR, "scheduled"); + xasprintf(&file, "%s/%s", svcdir, "scheduled"); dirs = ls_dir(file, 0); TAILQ_FOREACH(dir, dirs, entries) { xasprintf(&was, "%s/%s/%s", file, dir->value, base); @@ -897,10 +925,10 @@ rc_service_state(const char *service) RC_STRINGLIST *dirs; RC_STRING *dir; const char *base = basename_c(service); + const char *svcdir = rc_service_dir(); for (i = 0; rc_service_state_names[i].name; i++) { - xasprintf(&file, "%s/%s/%s", RC_SVCDIR, - rc_service_state_names[i].name, base); + xasprintf(&file, "%s/%s/%s", svcdir, rc_service_state_names[i].name, base); if (exists(file)) { if (rc_service_state_names[i].state <= 0x10) state = rc_service_state_names[i].state; @@ -915,11 +943,11 @@ rc_service_state(const char *service) state |= RC_SERVICE_CRASHED; } if (state & RC_SERVICE_STOPPED) { - dirs = ls_dir(RC_SVCDIR "/scheduled", 0); + char *sched_dir; + xasprintf(&sched_dir, "%s/scheduled", svcdir); + dirs = ls_dir(sched_dir, 0); TAILQ_FOREACH(dir, dirs, entries) { - xasprintf(&file, - "%s/scheduled/%s/%s", RC_SVCDIR, - dir->value, service); + xasprintf(&file, "%s/scheduled/%s/%s", svcdir, dir->value, service); i = exists(file); free(file); if (i) { @@ -928,6 +956,7 @@ rc_service_state(const char *service) } } rc_stringlist_free(dirs); + free(sched_dir); } return state; @@ -940,7 +969,7 @@ rc_service_value_get(const char *service, const char *option) size_t len = 0; char *file; - xasprintf(&file, "%s/options/%s/%s", RC_SVCDIR, service, option); + xasprintf(&file, "%s/options/%s/%s", rc_service_dir(), service, option); rc_getfile(file, &buffer, &len); free(file); @@ -954,7 +983,7 @@ rc_service_value_set(const char *service, const char *option, FILE *fp; char *file1, *file2; - xasprintf(&file1, "%s/options/%s", RC_SVCDIR, service); + xasprintf(&file1, "%s/options/%s", rc_service_dir(), service); if (mkdir(file1, 0755) != 0 && errno != EEXIST) { free(file1); return false; @@ -987,7 +1016,7 @@ rc_service_schedule_start(const char *service, const char *service_to_start) if (!service || !rc_service_exists(service_to_start)) return false; - xasprintf(&file1, "%s/scheduled/%s", RC_SVCDIR, basename_c(service)); + xasprintf(&file1, "%s/scheduled/%s", rc_service_dir(), basename_c(service)); if (mkdir(file1, 0755) != 0 && errno != EEXIST) { free(file1); return false; @@ -1008,7 +1037,7 @@ rc_service_schedule_clear(const char *service) char *dir; bool r; - xasprintf(&dir, "%s/scheduled/%s", RC_SVCDIR, basename_c(service)); + xasprintf(&dir, "%s/scheduled/%s", rc_service_dir(), basename_c(service)); r = rm_dir(dir, true); free(dir); if (!r && errno == ENOENT) @@ -1023,29 +1052,23 @@ rc_services_in_runlevel(const char *runlevel) RC_STRINGLIST *list = NULL; if (!runlevel) { -#ifdef RC_PKG_INITDIR - RC_STRINGLIST *pkg = ls_dir(RC_PKG_INITDIR, LS_INITD); -#endif -#ifdef RC_LOCAL_INITDIR - RC_STRINGLIST *local = ls_dir(RC_LOCAL_INITDIR, LS_INITD); -#endif + list = rc_stringlist_new(); + for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) { + char *initd; + RC_STRINGLIST *svcs; - list = ls_dir(RC_INITDIR, LS_INITD); + xasprintf(&initd, "%s/init.d", *dirs); + svcs = ls_dir(initd, LS_INITD); + TAILQ_CONCAT(list, svcs, entries); -#ifdef RC_PKG_INITDIR - TAILQ_CONCAT(list, pkg, entries); - rc_stringlist_free(pkg); -#endif -#ifdef RC_LOCAL_INITDIR - TAILQ_CONCAT(list, local, entries); - rc_stringlist_free(local); -#endif + rc_stringlist_free(svcs); + } return list; } /* These special levels never contain any services */ if (strcmp(runlevel, RC_LEVEL_SINGLE) != 0) { - xasprintf(&dir, "%s/%s", RC_RUNLEVELDIR, runlevel); + xasprintf(&dir, "%s/%s", rc_runlevel_dir(), runlevel); list = ls_dir(dir, LS_INITD); free(dir); } @@ -1080,9 +1103,7 @@ rc_services_in_state(RC_SERVICE state) RC_STRING *d; char *dir, *dir2; - xasprintf(&dir, "%s/%s", RC_SVCDIR, - rc_parse_service_state(state)); - + xasprintf(&dir, "%s/%s", rc_service_dir(), rc_parse_service_state(state)); if (state != RC_SERVICE_SCHEDULED) { dirs = ls_dir(dir, LS_INITD); free(dir); @@ -1151,7 +1172,7 @@ rc_service_add(const char *runlevel, const char *service) i = binit; } - xasprintf(&file, "%s/%s/%s", RC_RUNLEVELDIR, runlevel, + xasprintf(&file, "%s/%s/%s", rc_runlevel_dir(), runlevel, basename_c(service)); retval = (symlink(i, file) == 0); free(file); @@ -1166,7 +1187,7 @@ rc_service_delete(const char *runlevel, const char *service) char *file; int r; - xasprintf(&file, "%s/%s/%s", RC_RUNLEVELDIR, runlevel, + xasprintf(&file, "%s/%s/%s", rc_runlevel_dir(), runlevel, basename_c(service)); r = unlink(file); free(file); @@ -1176,19 +1197,23 @@ rc_service_delete(const char *runlevel, const char *service) RC_STRINGLIST * rc_services_scheduled_by(const char *service) { - RC_STRINGLIST *dirs = ls_dir(RC_SVCDIR "/scheduled", 0); RC_STRINGLIST *list = rc_stringlist_new(); + RC_STRINGLIST *dirs; RC_STRING *dir; + char *sched_dir; char *file; + xasprintf(&sched_dir, "%s/scheduled", rc_service_dir()); + dirs = ls_dir(sched_dir, 0); + TAILQ_FOREACH(dir, dirs, entries) { - xasprintf(&file, "%s/scheduled/%s/%s", RC_SVCDIR, dir->value, - service); + xasprintf(&file, "%s/%s/%s", sched_dir, dir->value, service); if (exists(file)) rc_stringlist_add(list, file); free(file); } rc_stringlist_free(dirs); + free(sched_dir); return list; } @@ -1198,7 +1223,7 @@ rc_services_scheduled(const char *service) char *dir; RC_STRINGLIST *list; - xasprintf(&dir, "%s/scheduled/%s", RC_SVCDIR, basename_c(service)); + xasprintf(&dir, "%s/scheduled/%s", rc_service_dir(), basename_c(service)); list = ls_dir(dir, LS_INITD); free(dir); return list; diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in index d90943b65..8fdd20806 100644 --- a/src/librc/rc.h.in +++ b/src/librc/rc.h.in @@ -123,6 +123,22 @@ typedef TAILQ_HEAD(rc_stringlist, rc_string) RC_STRINGLIST; #define RC_LEVEL_SINGLE "single" #define RC_LEVEL_SHUTDOWN "shutdown" +/*! Sets the root prefix for all librc operations + * it should be called before any other operation + * @param root path to prefix */ +void rc_set_root(const char *root); + +/*! Get all directories that make up sysconf + * That is, directories where to look up init.d and conf.d. + * @return NULL terminated array of directory paths. */ +const char * const *rc_sysconf_dirs(void); + +/*! @return Path to runlevel directory */ +const char *rc_runlevel_dir(void); + +/*! @return Path to service directory */ +const char *rc_service_dir(void); + /*! Return the current runlevel. * @return the current runlevel */ char *rc_runlevel_get(void); diff --git a/src/openrc-run/openrc-run.c b/src/openrc-run/openrc-run.c index 7c5d50a1b..08baad80c 100644 --- a/src/openrc-run/openrc-run.c +++ b/src/openrc-run/openrc-run.c @@ -54,8 +54,6 @@ #include "_usage.h" #include "helpers.h" -#define PREFIX_LOCK RC_SVCDIR "/prefix.lock" - #define WAIT_INTERVAL 20000000 /* usecs to poll the lock file */ #define WAIT_TIMEOUT 60 /* seconds until we timeout */ #define WARN_TIMEOUT 10 /* warn about this every N seconds */ @@ -165,7 +163,7 @@ unhotplug(void) { char *file = NULL; - xasprintf(&file, RC_SVCDIR "/hotplugged/%s", applet); + xasprintf(&file, "%s/hotplugged/%s", rc_service_dir(), applet); if (exists(file) && unlink(file) != 0) eerror("%s: unlink `%s': %s", applet, file, strerror(errno)); free(file); @@ -284,6 +282,7 @@ write_prefix(const char *buffer, size_t bytes, bool *prefixed) size_t i, j; const char *ec = ecolor(ECOLOR_HILITE); const char *ec_normal = ecolor(ECOLOR_NORMAL); + char *prefix_lock; ssize_t ret = 0; int fd = fileno(stdout), lock_fd = -1; @@ -291,7 +290,9 @@ write_prefix(const char *buffer, size_t bytes, bool *prefixed) * Lock the prefix. * open() may fail here when running as user, as RC_SVCDIR may not be writable. */ - lock_fd = open(PREFIX_LOCK, O_WRONLY | O_CREAT, 0664); + xasprintf(&prefix_lock, "%s/prefix.lock", rc_service_dir()); + lock_fd = open(prefix_lock, O_WRONLY | O_CREAT, 0664); + free(prefix_lock); if (lock_fd != -1) { while (flock(lock_fd, LOCK_EX) != 0) { @@ -334,6 +335,18 @@ write_prefix(const char *buffer, size_t bytes, bool *prefixed) return ret; } +static int +openrc_sh_exec(const char *openrc_sh, const char *arg1, const char *arg2) +{ + if (arg2) + einfov("Executing: %s %s %s %s %s", openrc_sh, openrc_sh, service, arg1, arg2); + else + einfov("Executing: %s %s %s %s", openrc_sh, openrc_sh, service, arg1); + execl(openrc_sh, openrc_sh, service, arg1, arg2, (char *) NULL); + eerror("%s: exec '%s': %s", service, openrc_sh, strerror(errno)); + _exit(EXIT_FAILURE); +} + static int svc_exec(const char *arg1, const char *arg2) { @@ -385,44 +398,20 @@ svc_exec(const char *arg1, const char *arg2) if (service_pid == -1) eerrorx("%s: fork: %s", service, strerror(errno)); if (service_pid == 0) { + char *openrc_sh; + xasprintf(&openrc_sh, "%s/openrc-run.sh", rc_service_dir()); + if (slave_tty >= 0) { dup2(slave_tty, STDOUT_FILENO); dup2(slave_tty, STDERR_FILENO); } - if (exists(RC_SVCDIR "/openrc-run.sh")) { - if (arg2) - einfov("Executing: %s %s %s %s %s", - RC_SVCDIR "/openrc-run.sh", RC_SVCDIR "/openrc-run.sh", - service, arg1, arg2); - else - einfov("Executing: %s %s %s %s", - RC_SVCDIR "/openrc-run.sh", RC_SVCDIR "/openrc-run.sh", - service, arg1); - execl(RC_SVCDIR "/openrc-run.sh", - RC_SVCDIR "/openrc-run.sh", - service, arg1, arg2, (char *) NULL); - eerror("%s: exec `" RC_SVCDIR "/openrc-run.sh': %s", - service, strerror(errno)); - _exit(EXIT_FAILURE); - } else { - if (arg2) - einfov("Executing: %s %s %s %s %s", - RC_LIBEXECDIR "/sh/openrc-run.sh", - RC_LIBEXECDIR "/sh/openrc-run.sh", - service, arg1, arg2); - else - einfov("Executing: %s %s %s %s", - RC_LIBEXECDIR "/sh/openrc-run.sh", - RC_LIBEXECDIR "/sh/openrc-run.sh", - service, arg1); - execl(RC_LIBEXECDIR "/sh/openrc-run.sh", - RC_LIBEXECDIR "/sh/openrc-run.sh", - service, arg1, arg2, (char *) NULL); - eerror("%s: exec `" RC_LIBEXECDIR "/sh/openrc-run.sh': %s", - service, strerror(errno)); - _exit(EXIT_FAILURE); - } + if (exists(openrc_sh)) + openrc_sh_exec(openrc_sh, arg1, arg2); + else + openrc_sh_exec(RC_LIBEXECDIR "/sh/openrc-run.sh", arg1, arg2); + + /* UNREACHABLE */ } buffer = xmalloc(sizeof(char) * BUFSIZ); @@ -508,7 +497,7 @@ svc_wait(const char *svc) forever = true; rc_stringlist_free(keywords); - xasprintf(&file, RC_SVCDIR "/exclusive/%s", basename_c(svc)); + xasprintf(&file, "%s/exclusive/%s", rc_service_dir(), basename_c(svc)); interval.tv_sec = 0; interval.tv_nsec = WAIT_INTERVAL; diff --git a/src/openrc/rc-logger.c b/src/openrc/rc-logger.c index 974147f99..96a3e6e57 100644 --- a/src/openrc/rc-logger.c +++ b/src/openrc/rc-logger.c @@ -46,7 +46,6 @@ #include "misc.h" #include "helpers.h" -#define TMPLOG RC_SVCDIR "/rc.log" #define DEFAULTLOG "/var/log/rc.log" static int signal_pipe[2] = { -1, -1 }; @@ -146,6 +145,7 @@ rc_logger_open(const char *level) FILE *log = NULL; FILE *plog = NULL; const char *logfile; + char *tmplog; int log_error = 0; if (!rc_conf_yesno("rc_logger")) @@ -184,7 +184,8 @@ rc_logger_open(const char *level) signal_pipe[1] = -1; runlevel = level; - if ((log = fopen(TMPLOG, "ae"))) + xasprintf(&tmplog, "%s/rc.log", rc_service_dir()); + if ((log = fopen(tmplog, "ae"))) write_time(log, "started"); else { free(logbuf); @@ -234,7 +235,7 @@ rc_logger_open(const char *level) break; } if (logbuf) { - if ((log = fopen(TMPLOG, "ae"))) { + if ((log = fopen(tmplog, "ae"))) { write_time(log, "started"); write_log(fileno(log), logbuf, logbuf_len); } @@ -249,13 +250,13 @@ rc_logger_open(const char *level) logfile = rc_conf_value("rc_log_path"); if (logfile == NULL) logfile = DEFAULTLOG; - if (!strcmp(logfile, TMPLOG)) { + if (!strcmp(logfile, tmplog)) { eerror("Cowardly refusing to concatenate a logfile into itself."); - eerrorx("Please change rc_log_path to something other than %s to get rid of this message", TMPLOG); + eerrorx("Please change rc_log_path to something other than %s to get rid of this message", tmplog); } if ((plog = fopen(logfile, "ae"))) { - if ((log = fopen(TMPLOG, "re"))) { + if ((log = fopen(tmplog, "re"))) { while ((bytes = fread(buffer, sizeof(*buffer), BUFSIZ, log)) > 0) { if (fwrite(buffer, sizeof(*buffer), bytes, plog) < bytes) { log_error = 1; @@ -266,7 +267,7 @@ rc_logger_open(const char *level) fclose(log); } else { log_error = 1; - eerror("Error: fopen(%s) failed: %s", TMPLOG, strerror(errno)); + eerror("Error: fopen(%s) failed: %s", tmplog, strerror(errno)); } fclose(plog); @@ -284,10 +285,13 @@ rc_logger_open(const char *level) /* Try to keep the temporary log in case of errors */ if (!log_error) { if (errno != EROFS && ((strcmp(level, RC_LEVEL_SHUTDOWN) != 0) && (strcmp(level, RC_LEVEL_SYSINIT) != 0))) - if (unlink(TMPLOG) == -1) - eerror("Error: unlink(%s) failed: %s", TMPLOG, strerror(errno)); - } else if (exists(TMPLOG)) - eerrorx("Warning: temporary logfile left behind: %s", TMPLOG); + if (unlink(tmplog) == -1) + eerror("Error: unlink(%s) failed: %s", tmplog, strerror(errno)); + } else if (exists(tmplog)) { + eerrorx("Warning: temporary logfile left behind: %s", tmplog); + } + + free(tmplog); exit(0); /* NOTREACHED */ diff --git a/src/openrc/rc.c b/src/openrc/rc.c index 5bee9e6cf..691dd821b 100644 --- a/src/openrc/rc.c +++ b/src/openrc/rc.c @@ -70,8 +70,6 @@ const char *usagestring = "" \ #define INITSH RC_LIBEXECDIR "/sh/init.sh" #define INITEARLYSH RC_LIBEXECDIR "/sh/init-early.sh" -#define INTERACTIVE RC_SVCDIR "/interactive" - #define DEVBOOT "/dev/.rcboot" const char *applet = NULL; @@ -95,16 +93,19 @@ clean_failed(void) DIR *dp; struct dirent *d; char *path; + char *failed_dir; + + xasprintf(&failed_dir, "%s/failed", rc_service_dir()); /* Clean the failed services state dir now */ - if ((dp = opendir(RC_SVCDIR "/failed"))) { + if ((dp = opendir(failed_dir))) { while ((d = readdir(dp))) { if (d->d_name[0] == '.' && (d->d_name[1] == '\0' || (d->d_name[1] == '.' && d->d_name[2] == '\0'))) continue; - xasprintf(&path, RC_SVCDIR "/failed/%s", d->d_name); + xasprintf(&path, "%s/%s", failed_dir, d->d_name); if (unlink(path)) eerror("%s: unlink `%s': %s", applet, path, strerror(errno)); @@ -112,12 +113,16 @@ clean_failed(void) } closedir(dp); } + + free(failed_dir); } static void cleanup(void) { RC_PID *p, *tmp; + const char *svcdir = rc_service_dir(); + static const char *subdirs[] = { "rc.starting", "rc.stopping" }; if (!rc_in_logger && !rc_in_plugin && applet && (strcmp(applet, "rc") == 0 || strcmp(applet, "openrc") == 0)) @@ -133,8 +138,13 @@ cleanup(void) } /* Clean runlevel start, stop markers */ - rmdir(RC_STARTING); - rmdir(RC_STOPPING); + for (size_t i = 0; i < ARRAY_SIZE(subdirs); i++) { + char *path; + xasprintf(&path, "%s/%s", svcdir, subdirs[i]); + rmdir(path); + free(path); + } + clean_failed(); rc_logger_close(); } @@ -211,9 +221,14 @@ want_interactive(void) static void mark_interactive(void) { - FILE *fp = fopen(INTERACTIVE, "w"); - if (fp) + FILE *fp; + char *dir; + + xasprintf(&dir, "%s/interactive", rc_service_dir()); + if ((fp = fopen(dir, "w"))) fclose(fp); + + free(dir); } static void @@ -653,9 +668,12 @@ do_start_services(const RC_STRINGLIST *start_services, bool parallel) bool interactive = false; RC_SERVICE state; bool crashed = false; + char *interactive_dir; + + xasprintf(&interactive_dir, "%s/interactive", rc_service_dir()); if (!rc_yesno(getenv("EINFO_QUIET"))) - interactive = exists(INTERACTIVE); + interactive = exists(interactive_dir); errno = 0; crashed = rc_conf_yesno("rc_crashed_start"); if (errno == ENOENT) @@ -710,14 +728,12 @@ do_start_services(const RC_STRINGLIST *start_services, bool parallel) /* Store our interactive status for boot */ if (interactive && - (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 || - strcmp(runlevel, getenv("RC_BOOTLEVEL")) == 0)) + (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 || + strcmp(runlevel, getenv("RC_BOOTLEVEL")) == 0)) mark_interactive(); - else { - if (exists(INTERACTIVE)) - unlink(INTERACTIVE); - } - + else + if (exists(interactive_dir)) + unlink(interactive_dir); } #ifdef RC_DEBUG @@ -756,6 +772,9 @@ int main(int argc, char **argv) RC_STRING *service; bool going_down = false; int depoptions = RC_DEP_STRICT | RC_DEP_TRACE; + const char *svcdir = rc_service_dir(); + char *rc_starting, *rc_stopping; + char *deptree_skewed; char *krunlevel = NULL; char *pidstr = NULL; int opt; @@ -795,8 +814,7 @@ int main(int argc, char **argv) /* complain about old configuration settings if they exist */ if (exists(RC_CONF_OLD)) { - ewarn("%s still exists on your system and should be removed.", - RC_CONF_OLD); + ewarn("%s still exists on your system and should be removed.", RC_CONF_OLD); ewarn("Please migrate to the appropriate settings in %s", RC_CONF); } @@ -956,17 +974,21 @@ int main(int argc, char **argv) /* Load our deptree */ if ((main_deptree = _rc_deptree_load(0, ®en)) == NULL) eerrorx("failed to load deptree"); - if (exists(RC_DEPTREE_SKEWED)) + + xasprintf(&deptree_skewed, "%s/clock-skewed", svcdir); + if (exists(deptree_skewed)) ewarn("WARNING: clock skew detected!"); + free(deptree_skewed); /* Clean the failed services state dir */ clean_failed(); - if (mkdir(RC_STOPPING, 0755) != 0) { + xasprintf(&rc_stopping, "%s/rc.stopping", svcdir); + if (mkdir(rc_stopping, 0755) != 0) { if (errno == EACCES) eerrorx("%s: superuser access required", applet); - eerrorx("%s: failed to create stopping dir `%s': %s", - applet, RC_STOPPING, strerror(errno)); + eerrorx("%s: failed to create stopping dir '%s': %s", + applet, rc_stopping, strerror(errno)); } /* Create a list of all services which we could stop (assuming @@ -1048,7 +1070,8 @@ int main(int argc, char **argv) going_down ? newlevel : runlevel); hook_out = 0; - rmdir(RC_STOPPING); + rmdir(rc_stopping); + free(rc_stopping); /* Store the new runlevel */ if (newlevel) { @@ -1065,7 +1088,10 @@ int main(int argc, char **argv) rc_logger_close(); #endif - mkdir(RC_STARTING, 0755); + xasprintf(&rc_starting, "%s/rc.starting", svcdir); + mkdir(rc_starting, 0755); + free(rc_starting); + rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, runlevel); hook_out = RC_HOOK_RUNLEVEL_START_OUT; @@ -1134,8 +1160,12 @@ int main(int argc, char **argv) * we need to delete them so that they are regenerated again in the * default runlevel as they may depend on things that are now * available */ - if (regen && strcmp(runlevel, bootlevel) == 0) - unlink(RC_DEPTREE_CACHE); + if (regen && strcmp(runlevel, bootlevel) == 0) { + char *deptree_cache; + xasprintf(&deptree_cache, "%s/deptree", svcdir); + unlink(deptree_cache); + free(deptree_cache); + } return EXIT_SUCCESS; } diff --git a/src/shared/misc.c b/src/shared/misc.c index 28f4e2352..f68d1d5e1 100644 --- a/src/shared/misc.c +++ b/src/shared/misc.c @@ -71,7 +71,7 @@ void env_filter(void) { RC_STRINGLIST *env_allow; - RC_STRINGLIST *profile; + RC_STRINGLIST *profile = rc_stringlist_new(); RC_STRINGLIST *env_list; RC_STRING *env; char *e; @@ -87,7 +87,18 @@ env_filter(void) rc_stringlist_free(env_allow); return; } - profile = rc_config_load(RC_PROFILE_ENV); + + for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) { + char *profile_path; + RC_STRINGLIST *profile_env; + + xasprintf(&profile_path, "%s/profile.env", *dirs); + profile_env = rc_config_load(profile_path); + TAILQ_CONCAT(profile, profile_env, entries); + + rc_stringlist_free(profile_env); + free(profile_path); + } /* Copy the env and work from this so we can manipulate it safely */ env_list = rc_stringlist_new(); @@ -143,7 +154,9 @@ env_config(void) char *npp; char *tok; const char *sys = rc_sys(); + const char *svcdir = rc_service_dir(); char *buffer = NULL; + char *tmpdir; size_t size = 0; /* Ensure our PATH is prefixed with the system locations first @@ -173,10 +186,12 @@ env_config(void) free(e); } + xasprintf(&tmpdir, "%s/tmp", svcdir); + setenv("RC_VERSION", VERSION, 1); setenv("RC_LIBEXECDIR", RC_LIBEXECDIR, 1); - setenv("RC_SVCDIR", RC_SVCDIR, 1); - setenv("RC_TMPDIR", RC_SVCDIR "/tmp", 1); + setenv("RC_SVCDIR", svcdir, 1); + setenv("RC_TMPDIR", tmpdir, 1); setenv("RC_BOOTLEVEL", RC_LEVEL_BOOT, 1); e = rc_runlevel_get(); setenv("RC_RUNLEVEL", e, 1); @@ -248,7 +263,7 @@ svc_lock(const char *applet, bool ignore_lock_failure) char *file = NULL; int fd; - xasprintf(&file, RC_SVCDIR "/exclusive/%s", applet); + xasprintf(&file, "%s/exclusive/%s", rc_service_dir(), applet); fd = open(file, O_WRONLY | O_CREAT | O_NONBLOCK, 0664); free(file); if (fd == -1) @@ -274,7 +289,7 @@ svc_unlock(const char *applet, int fd) { char *file = NULL; - xasprintf(&file, RC_SVCDIR "/exclusive/%s", applet); + xasprintf(&file, "%s/exclusive/%s", rc_service_dir(), applet); close(fd); unlink(file); free(file); @@ -382,18 +397,22 @@ RC_DEPTREE * _rc_deptree_load(int force, int *regen) int merrno; time_t t; char file[PATH_MAX]; + const char *svcdir = rc_service_dir(); struct stat st; struct utimbuf ut; FILE *fp; t = 0; if (rc_deptree_update_needed(&t, file) || force != 0) { + char *deptree_cache, *deptree_skewed; + xasprintf(&deptree_cache, "%s/deptree", svcdir); + /* Test if we have permission to update the deptree */ - fd = open(RC_DEPTREE_CACHE, O_WRONLY); + fd = open(deptree_cache, O_WRONLY); merrno = errno; errno = serrno; if (fd == -1 && merrno == EACCES) - return rc_deptree_load(); + goto out; close(fd); if (regen) @@ -403,29 +422,33 @@ RC_DEPTREE * _rc_deptree_load(int force, int *regen) eend (retval, "Failed to update the dependency tree"); if (retval == 0) { - if (stat(RC_DEPTREE_CACHE, &st) != 0) { - eerror("stat(%s): %s", RC_DEPTREE_CACHE, strerror(errno)); + if (stat(deptree_cache, &st) != 0) { + eerror("stat(%s): %s", deptree_cache, strerror(errno)); + free(deptree_cache); return NULL; } + xasprintf(&deptree_skewed, "%s/clock-skewed", svcdir); if (st.st_mtime < t) { - eerror("Clock skew detected with `%s'", file); - eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE - "' to %s", ctime(&t)); - fp = fopen(RC_DEPTREE_SKEWED, "w"); + eerror("Clock skew detected with '%s'", file); + eerrorn("Adjusting mtime of '%s' to %s", deptree_cache, ctime(&t)); + fp = fopen(deptree_skewed, "w"); if (fp != NULL) { fprintf(fp, "%s\n", file); fclose(fp); } ut.actime = t; ut.modtime = t; - utime(RC_DEPTREE_CACHE, &ut); + utime(deptree_cache, &ut); } else { - if (exists(RC_DEPTREE_SKEWED)) - unlink(RC_DEPTREE_SKEWED); + if (exists(deptree_skewed)) + unlink(deptree_skewed); } + free(deptree_skewed); } if (force == -1 && regen != NULL) *regen = retval; +out: + free(deptree_cache); } return rc_deptree_load(); } diff --git a/src/shared/misc.h b/src/shared/misc.h index b158a7860..3fafe6755 100644 --- a/src/shared/misc.h +++ b/src/shared/misc.h @@ -33,16 +33,7 @@ #define RC_LEVEL_BOOT "boot" #define RC_LEVEL_DEFAULT "default" -#define RC_DEPTREE_CACHE RC_SVCDIR "/deptree" -#define RC_DEPTREE_SKEWED RC_SVCDIR "/clock-skewed" #define RC_KRUNLEVEL RC_SVCDIR "/krunlevel" -#define RC_STARTING RC_SVCDIR "/rc.starting" -#define RC_STOPPING RC_SVCDIR "/rc.stopping" - -#define RC_SVCDIR_STARTING RC_SVCDIR "/starting" -#define RC_SVCDIR_INACTIVE RC_SVCDIR "/inactive" -#define RC_SVCDIR_STARTED RC_SVCDIR "/started" -#define RC_SVCDIR_COLDPLUGGED RC_SVCDIR "/coldplugged" char *rc_conf_value(const char *var); bool rc_conf_yesno(const char *var); diff --git a/src/supervise-daemon/supervise-daemon.c b/src/supervise-daemon/supervise-daemon.c index 364b1f1d5..e7ea76ae6 100644 --- a/src/supervise-daemon/supervise-daemon.c +++ b/src/supervise-daemon/supervise-daemon.c @@ -1086,7 +1086,7 @@ int main(int argc, char **argv) umask(numask); if (!pidfile) xasprintf(&pidfile, "/var/run/supervise-%s.pid", svcname); - xasprintf(&fifopath, "%s/supervise-%s.ctl", RC_SVCDIR, svcname); + xasprintf(&fifopath, "%s/supervise-%s.ctl", rc_service_dir(), svcname); if (mkfifo(fifopath, 0600) == -1 && errno != EEXIST) eerrorx("%s: unable to create control fifo: %s", applet, strerror(errno));