From f239ac39ab80c2279d5b9ce42b58f8d6a1833780 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 21 Apr 2014 05:04:58 +0200 Subject: run mdsinitrc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/config.h | 20 ++++++++++- src/mds-server.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/mds-server.h | 10 ++++++ 3 files changed, 132 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/config.h b/src/config.h index abab904..6d38a14 100644 --- a/src/config.h +++ b/src/config.h @@ -51,6 +51,14 @@ #endif +/** + * The system's directory for site-specific configurations + */ +#ifndef SYSCONFDIR +#define SYSCONFDIR "/etc" +#endif + + /** * The root directory of all runtime data stored by MDS */ @@ -143,12 +151,22 @@ /** - * The minimum time that most have elapsed for respawning to be allowed. + * The minimum time that most have elapsed + * for respawning to be allowed */ #ifndef RESPAWN_TIME_LIMIT_SECONDS #define RESPAWN_TIME_LIMIT_SECONDS 5 #endif +/** + * The dot-prefixless basename of the initrc + * file that the master server executes + */ +#ifndef INITRC_FILE +#define INITRC_FILE "mdsinitrc" +#endif + + #endif diff --git a/src/mds-server.c b/src/mds-server.c index 3c76fec..c829ecc 100644 --- a/src/mds-server.c +++ b/src/mds-server.c @@ -24,6 +24,7 @@ #include #include #include +#include /** @@ -46,11 +47,12 @@ static char** argv; */ int main(int argc_, char** argv_) { - char* unparsed_args[ARGC_LIMIT + LIBEXEC_ARGC_EXTRA_LIMIT + 1]; - int i; int is_respawn = -1; int socket_fd = -1; - int unparsed_args_ptr = 0; + int unparsed_args_ptr = 1; + char* unparsed_args[ARGC_LIMIT + LIBEXEC_ARGC_EXTRA_LIMIT + 1]; + int i; + pid_t pid; argc = argc_; @@ -142,6 +144,104 @@ int main(int argc_, char** argv_) } + if (is_respawn == 0) + { + /* Run mdsinitrc. */ + pid = fork(); + if (pid == (pid_t)-1) + { + perror(*argv); + return 1; + } + if (pid == 0) /* Child process exec:s, the parent continues without waiting for it. */ + { + char pathname[PATH_MAX]; + struct passwd* pwd; + char* env; + char* home; + unparsed_args[0] = pathname; + + /* Test $XDG_CONFIG_HOME. */ + if ((env = getenv_nonempty("XDG_CONFIG_HOME")) != NULL) + { + snprintf(pathname, sizeof(pathname) / sizeof(char), "%s/.%s", env, INITRC_FILE); + execv(unparsed_args[0], unparsed_args); + } + + /* Test $HOME. */ + if ((env = getenv_nonempty("HOME")) != NULL) + { + snprintf(pathname, sizeof(pathname) / sizeof(char), "%s/.config/%s", env, INITRC_FILE); + execv(unparsed_args[0], unparsed_args); + + snprintf(pathname, sizeof(pathname) / sizeof(char), "%s/.%s", env, INITRC_FILE); + execv(unparsed_args[0], unparsed_args); + } + + /* Test ~. */ + pwd = getpwuid(getuid()); /* Ignore error. */ + if (pwd != NULL) + { + home = pwd->pw_dir; + if ((home != NULL) && (*home != '\0')) + { + snprintf(pathname, sizeof(pathname) / sizeof(char), "%s/.config/%s", home, INITRC_FILE); + execv(unparsed_args[0], unparsed_args); + + snprintf(pathname, sizeof(pathname) / sizeof(char), "%s/.%s", home, INITRC_FILE); + execv(unparsed_args[0], unparsed_args); + } + } + + /* Test $XDG_CONFIG_DIRS. */ + if ((env = getenv_nonempty("XDG_CONFIG_DIRS")) != NULL) + { + char* begin = env; + char* end; + int len; + for (;;) + { + end = strchrnul(begin, ':'); + len = (int)(end - begin); + if (len > 0) + { + snprintf(pathname, sizeof(pathname) / sizeof(char), "%.*s/%s", len, begin, INITRC_FILE); + execv(unparsed_args[0], unparsed_args); + } + if (*end == '\0') + break; + begin = end + 1; + } + } + + /* Test /etc. */ + snprintf(pathname, sizeof(pathname) / sizeof(char), "%s/%s", SYSCONFDIR, INITRC_FILE); + execv(unparsed_args[0], unparsed_args); + + /* Everything failed. */ + fprintf(stderr, + "%s: unable to run %s file, you might as well kill me.\n", + *argv, INITRC_FILE); + return 1; + } + } + + return 0; } + +/** + * Read an environment variable, but handle it as undefined if empty + * + * @param var The environment variable's name + * @return The environment variable's value, `NULL` if empty or not defined + */ +char* getenv_nonempty(const char* var) +{ + char* rc = getenv(var); + if ((rc == NULL) || (*rc == '\0')) + return NULL; + return rc; +} + diff --git a/src/mds-server.h b/src/mds-server.h index 4b558dd..c27498a 100644 --- a/src/mds-server.h +++ b/src/mds-server.h @@ -18,5 +18,15 @@ #ifndef MDS_MDS_SERVER_H #define MDS_MDS_SERVER_H + +/** + * Read an environment variable, but handle it as undefined if empty + * + * @param var The environment variable's name + * @return The environment variable's value, `NULL` if empty or not defined + */ +char* getenv_nonempty(const char* var); + + #endif -- cgit v1.2.3-70-g09d2