diff options
Diffstat (limited to 'src/librc')
| -rw-r--r-- | src/librc/librc-daemon.c | 39 | ||||
| -rw-r--r-- | src/librc/librc-depend.c | 92 | ||||
| -rw-r--r-- | src/librc/librc-misc.c | 8 | ||||
| -rw-r--r-- | src/librc/librc.c | 568 | ||||
| -rw-r--r-- | src/librc/rc.h.in | 46 | 
5 files changed, 317 insertions, 436 deletions
diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c index 10bf883a..d44013e5 100644 --- a/src/librc/librc-daemon.c +++ b/src/librc/librc-daemon.c @@ -405,12 +405,7 @@ rc_service_daemon_set(const char *service, const char *exec,  	RC_STRINGLIST *match;  	int i = 0;  	FILE *fp; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	if (!exec && !pidfile) { @@ -420,11 +415,7 @@ rc_service_daemon_set(const char *service, const char *exec,  	xasprintf(&dirpath, "%s/daemons/%s", svcdir, basename_c(service)); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(svcdir); -	} -#endif +	free(svcdir);  	/* Regardless, erase any existing daemon info */  	if ((dp = opendir(dirpath))) { @@ -490,12 +481,7 @@ rc_service_started_daemon(const char *service,  	bool retval = false;  	DIR *dp;  	struct dirent *d; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	if (!service || !exec)  		return false; @@ -503,11 +489,7 @@ rc_service_started_daemon(const char *service,  	xasprintf(&dirpath, "%s/daemons/%s", svcdir, basename_c(service));  	match = _match_list(exec, argv, NULL); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(svcdir); -	} -#endif +	free(svcdir);  	if (indx > 0) {  		xasprintf(&file, "%03d", indx); @@ -557,21 +539,12 @@ rc_service_daemons_crashed(const char *service)  	size_t i;  	char *ch_root;  	char *spidfile; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	path += snprintf(dirpath, sizeof(dirpath), "%s/daemons/%s",  	    svcdir, basename_c(service)); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(svcdir); -	} -#endif +	free(svcdir);  	if (!(dp = opendir(dirpath)))  		return false; diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c index dfb275bf..7b974193 100644 --- a/src/librc/librc-depend.c +++ b/src/librc/librc-depend.c @@ -123,25 +123,19 @@ get_deptype(const RC_DEPINFO *depinfo, const char *type)  RC_DEPTREE *  rc_deptree_load(void) { -	char *cache = RC_DEPTREE_CACHE; -#ifdef RC_USER_SERVICES -	char *user_svcdir; +	char *cache = NULL; +	char *svcdir;  	RC_DEPTREE *tree; -	if (rc_is_user()) { -		user_svcdir = rc_user_svcdir(); -		xasprintf(&cache, "%s/%s", user_svcdir, RC_DEPTREE_CACHE_FILE); - -		tree = rc_deptree_load_file(cache); +	svcdir = rc_svcdir(); +	xasprintf(&cache, "%s/%s", svcdir, RC_DEPTREE_CACHE_FILE); -		free(cache); -		free(user_svcdir); +	tree = rc_deptree_load_file(cache); -		return tree; -	} -#endif +	free(cache); +	free(svcdir); -	return rc_deptree_load_file(cache); +	return tree;  }  RC_DEPTREE * @@ -713,18 +707,15 @@ rc_deptree_update_needed(time_t *newest, char *file)  	int i;  	struct stat buf;  	time_t mtime; -	char *depconfig = RC_DEPCONFIG, *cache = RC_DEPTREE_CACHE; +	char *depconfig = NULL; +	char *cache = NULL;  	char *depdir = NULL; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	char *user_sysconfdir, *tmp; +	char *svcdir = NULL; +	char *sysconfdir, *tmp; -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -		user_sysconfdir = rc_user_sysconfdir(); -		xasprintf(&cache, "%s/%s", svcdir, RC_DEPTREE_CACHE_FILE); -	} -#endif +	svcdir = rc_svcdir(); +	sysconfdir = rc_sysconfdir(); +	xasprintf(&cache, "%s/%s", svcdir, RC_DEPTREE_CACHE_FILE);  	/* Create base directories if needed */  	for (i = 0; depdirs[i]; i++) { @@ -767,33 +758,28 @@ rc_deptree_update_needed(time_t *newest, char *file)  		newer |= !deep_mtime_check(RC_SYS_USER_INITDIR,true,&mtime,file);  		newer |= !deep_mtime_check(RC_SYS_USER_CONFDIR,true,&mtime,file); -		xasprintf(&tmp, "%s/%s", user_sysconfdir, RC_USER_INITDIR_FOLDER); +		xasprintf(&tmp, "%s/%s", sysconfdir, RC_INITDIR_FOLDER);  		newer |= !deep_mtime_check(tmp,true,&mtime,file);  		free(tmp); -		xasprintf(&tmp, "%s/%s", user_sysconfdir, RC_USER_CONFDIR_FOLDER); +		xasprintf(&tmp, "%s/%s", sysconfdir, RC_CONFDIR_FOLDER);  		newer |= !deep_mtime_check(tmp,true,&mtime,file);  		free(tmp); -		free(user_sysconfdir); +		free(sysconfdir);  	}  #endif      newer |= !deep_mtime_check(RC_CONF,true,&mtime,file);  	/* Some init scripts dependencies change depending on config files  	 * outside of baselayout, like syslog-ng, so we check those too. */ -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		xasprintf(&depconfig, "%s/%s", svcdir, RC_DEPCONFIG_FILE); -		free(svcdir); -	} -#endif +	xasprintf(&depconfig, "%s/%s", svcdir, RC_DEPCONFIG_FILE); +	free(svcdir); +  	config = rc_config_list(depconfig); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(depconfig); -	} -#endif + +	free(depconfig); +  	TAILQ_FOREACH(s, config, entries) {  		newer |= !deep_mtime_check(s->value, true, &mtime, file);  	} @@ -830,11 +816,10 @@ rc_deptree_update(void)  	char *line = NULL;  	size_t len = 0;  	char *depend, *depends, *service, *type, *nosys, *onosys; -	char *cache = RC_DEPTREE_CACHE; -	char *depconfig = RC_DEPCONFIG; -#ifdef RC_USER_SERVICES -	char *user_svcdir; -#endif +	char *cache = NULL; +	char *depconfig = NULL; +	char *svcdir = NULL; +  	size_t i, k, l;  	bool retval = true;  	const char *sys = rc_sys(); @@ -1116,14 +1101,11 @@ rc_deptree_update(void)  	   names don't have any non shell variable characters in  	   */ -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		user_svcdir = rc_user_svcdir(); -		xasprintf(&cache, "%s/%s", user_svcdir, RC_DEPTREE_CACHE_FILE); -		xasprintf(&depconfig, "%s/%s", user_svcdir, RC_DEPCONFIG_FILE); -		free(user_svcdir); -	} -#endif +	svcdir = rc_svcdir(); +	xasprintf(&cache, "%s/%s", svcdir, RC_DEPTREE_CACHE_FILE); +	xasprintf(&depconfig, "%s/%s", svcdir, RC_DEPCONFIG_FILE); +	free(svcdir); +  	if ((fp = fopen(cache, "w"))) {  		i = 0;  		TAILQ_FOREACH(depinfo, deptree, entries) { @@ -1162,12 +1144,8 @@ rc_deptree_update(void)  		unlink(depconfig);  	} -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(cache); -		free(depconfig); -	} -#endif +	free(cache); +	free(depconfig);  	rc_stringlist_free(config);  	free(deptree); diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c index 2dab1249..766c9b35 100644 --- a/src/librc/librc-misc.c +++ b/src/librc/librc-misc.c @@ -374,10 +374,10 @@ static RC_STRINGLIST * rc_user_config_directory(RC_STRINGLIST *config)  	RC_STRINGLIST *rc_conf_d_list;  	char path[PATH_MAX];  	RC_STRING *line; -	char *sysconf = rc_user_sysconfdir(); +	char *sysconf = rc_sysconfdir();  	char *user_conf_d; -	xasprintf(&user_conf_d, "%s/%s", sysconf, RC_USER_CONF_D); +	xasprintf(&user_conf_d, "%s/%s", sysconf, RC_CONF_D);  	if ((dp = opendir(user_conf_d)) != NULL) {  		while ((d = readdir(dp)) != NULL) { @@ -471,8 +471,8 @@ rc_conf_value(const char *setting)  #ifdef RC_USER_SERVICES  		if (rc_is_user()) { -			user_sysconf = rc_user_sysconfdir(); -			xasprintf(&userconf, "%s/%s", user_sysconf, RC_USER_CONF); +			user_sysconf = rc_sysconfdir(); +			xasprintf(&userconf, "%s/%s", user_sysconf, RC_CONF_FILE);  			user = rc_config_load(userconf);  			TAILQ_CONCAT(rc_conf, user, entries); diff --git a/src/librc/librc.c b/src/librc/librc.c index 598207cc..938e0ace 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -369,6 +369,8 @@ rc_set_user(void)  {  	char *path, *tmp; +	setenv("RC_USER_SERVICES", "YES", 1); +  	/* Setting the sysconf path to XDG_CONFIG_HOME, or ~/.config/, so subdirectories would go:  	* ~/.config/openrc/init.d  	* ~/.config/openrc/conf.d @@ -376,48 +378,51 @@ rc_set_user(void)  	* ~/.config/openrc/rc.conf  	* ~/.lcaol/share/openrc/  	* */ -	path = rc_user_sysconfdir(); +	path = rc_sysconfdir();  	if (mkdir(path, 0700) != 0 && errno != EEXIST) {  		eerrorx("mkdir: %s", strerror(errno));  	} -	xasprintf(&tmp, "%s/%s", path, RC_USER_INITDIR_FOLDER); +	xasprintf(&tmp, "%s/%s", path, RC_INITDIR_FOLDER);  	if (mkdir(tmp, 0700) != 0 && errno != EEXIST) {  		eerrorx("mkdir: %s", strerror(errno));  	}  	free(tmp); -	xasprintf(&tmp, "%s/%s", path, RC_USER_CONFDIR_FOLDER); +	xasprintf(&tmp, "%s/%s", path, RC_CONFDIR_FOLDER);  	if (mkdir(tmp, 0700) != 0 && errno != EEXIST) {  		eerrorx("mkdir: %s", strerror(errno));  	}  	free(tmp); -	xasprintf(&tmp, "%s/%s", path, RC_USER_RUNLEVELS_FOLDER); +	xasprintf(&tmp, "%s/%s", path, RC_RUNLEVELDIR_FOLDER);  	if (mkdir(tmp, 0700) != 0 && errno != EEXIST) {  		eerrorx("mkdir: %s", strerror(errno));  	}  	free(tmp); -	xasprintf(&tmp, "%s/%s/%s", path, RC_USER_RUNLEVELS_FOLDER, RC_LEVEL_DEFAULT); +	xasprintf(&tmp, "%s/%s/%s", path, RC_RUNLEVELDIR_FOLDER, RC_LEVEL_DEFAULT); +	if (mkdir(tmp, 0700) != 0 && errno != EEXIST) { +		eerrorx("mkdir: %s", strerror(errno)); +	} +	free(tmp); +	xasprintf(&tmp, "%s/%s/%s", path, RC_RUNLEVELDIR_FOLDER, RC_LEVEL_USERNONE);  	if (mkdir(tmp, 0700) != 0 && errno != EEXIST) {  		eerrorx("mkdir: %s", strerror(errno));  	}  	free(tmp);  	free(path); -	path = rc_user_datadir(); +	path = rc_cachedir();  	if (mkdir(path, 0700) != 0 && errno != EEXIST) {  		eerrorx("mkdir: %s", strerror(errno));  	}  	free(path); -	path = rc_user_svcdir(); +	path = rc_svcdir();  	if (mkdir(path, 0700) != 0 && errno != EEXIST) {  		eerrorx("mkdir: %s", strerror(errno));  	}  	free(path); - -	setenv("RC_USER_SERVICES", "YES", 1);  } -const char * +static const char *  rc_user_home(void)  {  	struct passwd *user_passwd; @@ -430,44 +435,6 @@ rc_user_home(void)  	return user_passwd->pw_dir;  } -char * -rc_user_sysconfdir(void) -{ -	char *env, *path = NULL; - -	if ((env = getenv("XDG_CONFIG_HOME"))) { -		xasprintf(&path, "%s/openrc", env); -	} else { -		xasprintf(&path, "%s/.config/openrc", rc_user_home()); -	} -	return path; -} - -char * -rc_user_datadir(void) -{ -	char *env, *path = NULL; - -	if ((env = getenv("XDG_DATA_HOME"))) { -		xasprintf(&path, "%s/openrc", env); -	} else { -		xasprintf(&path, "%s/.local/share/openrc", rc_user_home()); -	} -	return path; -} - -char * -rc_user_svcdir(void) -{ -	char *env, *path = NULL; -	if ((env = getenv("XDG_RUNTIME_DIR"))) { -		xasprintf(&path, "%s/%s", env, RC_USER_RUNTIME_FOLDER); -	} else { -		xasprintf(&path, "/tmp/%s/%d/", RC_USER_RUNTIME_FOLDER, getuid()); -	} -	return path; -} -  #endif  const char * @@ -510,7 +477,8 @@ get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list, RC_STRINGLIS  	RC_STRINGLIST *dirs;  	RC_STRING *d, *parent;  	const char *nextlevel; -	char *runlevel_dir = RC_RUNLEVELDIR; +	char *runleveldir = NULL; +	char *sysconfdir = NULL;  	/*  	 * If we haven't been passed a runlevel or a level list, or @@ -532,15 +500,11 @@ get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list, RC_STRINGLIS  	 * We can now do exactly the above procedure for our chained  	 * runlevels.  	 */ -#ifdef RC_USER_SERVICES -		if (rc_is_user()) { -			char *user_sysconf = rc_user_sysconfdir(); -			xasprintf(&runlevel_dir, "%s/%s", user_sysconf, RC_USER_RUNLEVELS_FOLDER); -			free(user_sysconf); -		} -#endif +	sysconfdir = rc_sysconfdir(); +	xasprintf(&runleveldir, "%s/%s", sysconfdir, RC_RUNLEVELDIR_FOLDER); +	free(sysconfdir); -	snprintf(path, sizeof(path), "%s/%s", runlevel_dir, runlevel); +	snprintf(path, sizeof(path), "%s/%s", runleveldir, runlevel);  	dirs = ls_dir(path, LS_DIR);  	TAILQ_FOREACH(d, dirs, entries) {  		nextlevel = d->value; @@ -564,58 +528,56 @@ get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list, RC_STRINGLIS  	}  	rc_stringlist_free(dirs); -#ifdef RC_USER_SERVICES -		if (rc_is_user()) { -			free(runlevel_dir); -		} -#endif +	free(runleveldir);  }  bool  rc_runlevel_starting(void)  { -	char *rc_starting = RC_STARTING; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *user_svcdir = rc_user_svcdir(); -		xasprintf(&rc_starting, "%s/%s", user_svcdir, RC_STARTING_FOLDER); -		free(user_svcdir); -	} -#endif -	return exists(rc_starting); +	char *rc_starting = NULL; +	char *svcdir = rc_svcdir(); +	bool retval; + +	xasprintf(&rc_starting, "%s/%s", svcdir, RC_STARTING_FOLDER); +	free(svcdir); + +	retval = exists(rc_starting); + +	free(rc_starting); + +	return retval;  }  bool  rc_runlevel_stopping(void)  { -	char *rc_stopping = RC_STOPPING; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *user_svcdir = rc_user_svcdir(); -		xasprintf(&rc_stopping, "%s/%s", user_svcdir, RC_STOPPING_FOLDER); -		free(user_svcdir); -	} -#endif -	return exists(rc_stopping); +	char *rc_stopping = NULL; +	char *svcdir = rc_svcdir(); +	bool retval; + +	xasprintf(&rc_stopping, "%s/%s", svcdir, RC_STOPPING_FOLDER); + +	free(svcdir); + +	retval = exists(rc_stopping); + +	free(rc_stopping); + +	return retval;  }  RC_STRINGLIST *rc_runlevel_list(void)  { -	char *runlevel_dir = RC_RUNLEVELDIR; +	char *runleveldir = NULL;  	RC_STRINGLIST *runlevels; -#ifdef RC_USER_SERVICES -	char *user_sysconfdir; -	if (rc_is_user()) { -		user_sysconfdir = rc_user_sysconfdir(); -		xasprintf(&runlevel_dir, "%s/%s", user_sysconfdir, RC_USER_RUNLEVELS_FOLDER); -	} -#endif -	 runlevels = ls_dir(runlevel_dir, LS_DIR); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(runlevel_dir); -	} -#endif +	char *sysconfdir = rc_sysconfdir(); + +	xasprintf(&runleveldir, "%s/%s", sysconfdir, RC_RUNLEVELDIR_FOLDER); + +	 runlevels = ls_dir(runleveldir, LS_DIR); + +	free(sysconfdir); +	free(runleveldir);  	return runlevels;  } @@ -623,16 +585,12 @@ char *  rc_runlevel_get(void)  {  	FILE *fp; -	char *runlevel = NULL, *runlevel_path = RC_RUNLEVEL; +	char *runlevel = NULL, *runlevel_path = NULL;  	size_t i; +	char *svcdir = rc_svcdir(); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *path = rc_user_svcdir(); -		xasprintf(&runlevel_path, "%s/%s", path, RC_RUNLEVEL_FOLDER); -		free(path); -	} -#endif +	xasprintf(&runlevel_path, "%s/%s", svcdir, RC_RUNLEVEL_FOLDER); +	free(svcdir);  	if ((fp = fopen(runlevel_path, "r"))) {  		runlevel = xmalloc(sizeof(char) * PATH_MAX); @@ -645,12 +603,7 @@ rc_runlevel_get(void)  		fclose(fp);  	} -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(runlevel_path); -	} -#endif - +	free(runlevel_path);  	if (!runlevel || !*runlevel) {  		free(runlevel); @@ -663,30 +616,24 @@ rc_runlevel_get(void)  bool  rc_runlevel_set(const char *runlevel)  { -	char *runlevel_path = RC_RUNLEVEL; +	char *svcdir = rc_svcdir(); +	char *softlevel = NULL;  	FILE *fp; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *path = rc_user_svcdir(); -		xasprintf(&runlevel_path, "%s/%s", path, RC_RUNLEVEL_FOLDER); -		free(path); -	} -#endif +	xasprintf(&softlevel, "%s/%s", svcdir, RC_RUNLEVEL_FOLDER); +	free(svcdir); -	fp = fopen(runlevel_path, "w"); +	fp = fopen(softlevel, "w"); -	if (!fp) +	if (!fp) { +		free(softlevel);  		return false; +	}  	fprintf(fp, "%s", runlevel);  	fclose(fp); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(runlevel_path); -	} -#endif +	free(softlevel);  	return true;  } @@ -694,23 +641,17 @@ bool  rc_runlevel_exists(const char *runlevel)  {  	char path[PATH_MAX]; +	char *sysconfdir = rc_sysconfdir();  	struct stat buf;  	if (!runlevel || strcmp(runlevel, "") == 0 || strcmp(runlevel, ".") == 0 ||  		strcmp(runlevel, "..") == 0)  		return false; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *user_path = rc_user_sysconfdir(); -		snprintf(path, sizeof(path), "%s/%s/%s", -				user_path, RC_USER_RUNLEVELS_FOLDER, runlevel); -	} else { -#endif -		snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel); -#ifdef RC_USER_SERVICES -	} -#endif +	snprintf(path, sizeof(path), "%s/%s/%s", +			sysconfdir, RC_RUNLEVELDIR_FOLDER, runlevel); + +	free(sysconfdir);  	if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode))  		return true; @@ -721,27 +662,21 @@ bool  rc_runlevel_stack(const char *dst, const char *src)  {  	char d[PATH_MAX], s[PATH_MAX]; -	char *runlevel_dir = RC_RUNLEVELDIR; +	char *sysconfdir = NULL; +	char *runleveldir = NULL;  	if (!rc_runlevel_exists(dst) || !rc_runlevel_exists(src))  		return false; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *user_sysconf = rc_user_sysconfdir(); -		xasprintf(&runlevel_dir, "%s/%s", user_sysconf, RC_USER_RUNLEVELS_FOLDER); -		free(user_sysconf); -	} -#endif +	sysconfdir = rc_sysconfdir(); + +	xasprintf(&runleveldir, "%s/%s", sysconfdir, RC_RUNLEVELDIR_FOLDER); +	free(sysconfdir);  	snprintf(s, sizeof(s), "../%s", src); -	snprintf(d, sizeof(s), "%s/%s/%s", runlevel_dir, dst, src); +	snprintf(d, sizeof(s), "%s/%s/%s", runleveldir, dst, src); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(runlevel_dir); -	} -#endif +	free(runleveldir);  	return (symlink(s, d) == 0 ? true : false);  } @@ -750,23 +685,16 @@ bool  rc_runlevel_unstack(const char *dst, const char *src)  {  	char path[PATH_MAX]; -	char *runlevel_dir = RC_RUNLEVELDIR; +	char *sysconfdir = rc_sysconfdir(); +	char *runleveldir = NULL; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *user_sysconf = rc_user_sysconfdir(); -		xasprintf(&runlevel_dir, "%s/%s", user_sysconf, RC_USER_RUNLEVELS_FOLDER); -		free(user_sysconf); -	} -#endif +	xasprintf(&runleveldir, "%s/%s", sysconfdir, RC_RUNLEVELDIR_FOLDER); +	free(sysconfdir); -	snprintf(path, sizeof(path), "%s/%s/%s", runlevel_dir, dst, src); +	snprintf(path, sizeof(path), "%s/%s/%s", runleveldir, dst, src); + +	free(runleveldir); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(runlevel_dir); -	} -#endif  	return (unlink(path) == 0 ? true : false);  } @@ -788,22 +716,18 @@ rc_service_resolve(const char *service)  {  	char buffer[PATH_MAX];  	char file[PATH_MAX]; -	char *svcdir = RC_SVCDIR; +	char *svcdir = NULL;  	int r;  	struct stat buf; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif -  	if (!service)  		return NULL;  	if (service[0] == '/')  		return xstrdup(service); +	svcdir = rc_svcdir(); +  	/* First check started services */  	snprintf(file, sizeof(file), "%s/%s/%s", svcdir, "started", service);  	if (lstat(file, &buf) || !S_ISLNK(buf.st_mode)) { @@ -813,11 +737,7 @@ rc_service_resolve(const char *service)  			*file = '\0';  	} -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(svcdir); -	} -#endif +	free(svcdir);  	if (*file) {  		memset(buffer, 0, sizeof(buffer)); @@ -830,10 +750,10 @@ rc_service_resolve(const char *service)  	/* If we're in user services mode, try user services*/  	if (rc_is_user()) {  		/* User defined services have preference to system provided */ -		char *user_sysconfdir = rc_user_sysconfdir(); +		char *sysconfdir = rc_sysconfdir();  		snprintf(file, sizeof(file), "%s/%s/%s", -				user_sysconfdir, RC_USER_INITDIR_FOLDER, service); -		free(user_sysconfdir); +				sysconfdir, RC_INITDIR_FOLDER, service); +		free(sysconfdir);  		if (stat(file, &buf) == 0)  			return xstrdup(file); @@ -978,23 +898,15 @@ bool  rc_service_in_runlevel(const char *service, const char *runlevel)  {  	char file[PATH_MAX]; -	char *runlevel_dir = RC_RUNLEVELDIR; +	char *runleveldir = NULL; +	char *sysconfdir = rc_sysconfdir(); +	xasprintf(&runleveldir, "%s/%s", sysconfdir, RC_RUNLEVELDIR_FOLDER); +	free(sysconfdir); -#ifdef RC_USER_SERVICES -		if (rc_is_user()) { -			char *user_sysconf = rc_user_sysconfdir(); -			xasprintf(&runlevel_dir, "%s/%s", user_sysconf, RC_USER_RUNLEVELS_FOLDER); -			free(user_sysconf); -		} -#endif  	snprintf(file, sizeof(file), "%s/%s/%s", -	    runlevel_dir, runlevel, basename_c(service)); +	    runleveldir, runlevel, basename_c(service)); -#ifdef RC_USER_SERVICES -		if (rc_is_user()) { -			free(runlevel_dir); -		} -#endif +	free(runleveldir);  	return exists(file);  } @@ -1013,16 +925,13 @@ rc_service_mark(const char *service, const RC_SERVICE state)  	RC_STRINGLIST *dirs;  	RC_STRING *dir;  	int serrno; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = NULL;  	if (!init)  		return false; +	svcdir = rc_svcdir(); +  	base = basename_c(service);  	if (state != RC_SERVICE_STOPPED) {  		if (!exists(init)) { @@ -1032,17 +941,20 @@ rc_service_mark(const char *service, const RC_SERVICE state)  		snprintf(file, sizeof(file), "%s/%s/%s",  		    svcdir,rc_parse_service_state(state), base); +  		if (exists(file))  			unlink(file);  		i = symlink(init, file);  		if (i != 0) {  			free(init); +			free(svcdir);  			return false;  		}  		skip_state = state;  	}  	if (state == RC_SERVICE_HOTPLUGGED || state == RC_SERVICE_FAILED) { +		free(svcdir);  		free(init);  		return true;  	} @@ -1071,12 +983,14 @@ rc_service_mark(const char *service, const RC_SERVICE state)  					    base);  					if (symlink(init, was) == -1) {  						free(init); +						free(svcdir);  						return false;  					}  					skip_wasinactive = true;  				}  				if (unlink(file) == -1) {  					free(init); +					free(svcdir);  					return false;  				}  			} @@ -1124,6 +1038,7 @@ rc_service_mark(const char *service, const RC_SERVICE state)  		rc_stringlist_free(dirs);  	}  	free(init); +	free(svcdir);  	return true;  } @@ -1136,12 +1051,7 @@ rc_service_state(const char *service)  	RC_STRINGLIST *dirs;  	RC_STRING *dir;  	const char *base = basename_c(service); -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	for (i = 0; rc_service_state_names[i].name; i++) {  		snprintf(file, sizeof(file), "%s/%s/%s", @@ -1175,6 +1085,7 @@ rc_service_state(const char *service)  		rc_stringlist_free(dirs);  	} +	free(svcdir);  	return state;  } @@ -1184,17 +1095,14 @@ rc_service_value_get(const char *service, const char *option)  	char *buffer = NULL;  	size_t len = 0;  	char file[PATH_MAX]; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	snprintf(file, sizeof(file), "%s/options/%s/%s",  	    svcdir, service, option);  	rc_getfile(file, &buffer, &len); +	free(svcdir); +  	return buffer;  } @@ -1205,14 +1113,10 @@ rc_service_value_set(const char *service, const char *option,  	FILE *fp;  	char file[PATH_MAX];  	char *p = file; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	p += snprintf(file, sizeof(file), "%s/options/%s", svcdir, service); +	free(svcdir);  	if (mkdir(file, 0755) != 0 && errno != EEXIST)  		return false; @@ -1236,19 +1140,17 @@ rc_service_schedule_start(const char *service, const char *service_to_start)  	char *p = file;  	char *init;  	bool retval; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = NULL;  	/* service may be a provided service, like net */  	if (!service || !rc_service_exists(service_to_start))  		return false; +	svcdir = rc_svcdir(); +  	p += snprintf(file, sizeof(file), "%s/scheduled/%s",  	    svcdir, basename_c(service)); +	free(svcdir);  	if (mkdir(file, 0755) != 0 && errno != EEXIST)  		return false; @@ -1264,15 +1166,11 @@ bool  rc_service_schedule_clear(const char *service)  {  	char dir[PATH_MAX]; -	char *svcdir = RC_SVCDIR; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	snprintf(dir, sizeof(dir), "%s/scheduled/%s",  	    svcdir, basename_c(service)); +	free(svcdir);  	if (!rm_dir(dir, true) && errno == ENOENT)  		return true;  	return false; @@ -1283,7 +1181,8 @@ rc_services_in_runlevel(const char *runlevel)  {  	char dir[PATH_MAX];  	RC_STRINGLIST *list = NULL; -	char *runlevel_dir = RC_RUNLEVELDIR; +	char *runleveldir = NULL; +	char *sysconfdir = rc_sysconfdir();  	if (!runlevel) {  #ifdef RC_PKG_INITDIR @@ -1293,67 +1192,56 @@ rc_services_in_runlevel(const char *runlevel)  		RC_STRINGLIST *local = ls_dir(RC_LOCAL_INITDIR, LS_INITD);  #endif  #ifdef RC_USER_SERVICES -	RC_STRINGLIST *local_user; -	RC_STRINGLIST *sys_user; -	char *user_sysconf; -	char *user_initdir; -	if (rc_is_user()) { -		user_sysconf = rc_user_sysconfdir(); -		xasprintf(&user_initdir, "%s/%s", user_sysconf, RC_USER_INITDIR_FOLDER); +		RC_STRINGLIST *local_user; +		RC_STRINGLIST *sys_user; +		char *initdir = NULL; -		local_user = ls_dir(user_initdir, LS_INITD); -		sys_user = ls_dir(RC_SYS_USER_INITDIR, LS_INITD); - -		list = rc_stringlist_new(); -	} else { +		if (rc_is_user()) { +			xasprintf(&initdir, "%s/%s", sysconfdir, RC_INITDIR_FOLDER); + +			local_user = ls_dir(initdir, LS_INITD); +			sys_user = ls_dir(RC_SYS_USER_INITDIR, LS_INITD); + +			list = rc_stringlist_new(); +			TAILQ_CONCAT(list, local_user, entries); +			TAILQ_CONCAT(list, sys_user, entries); +			rc_stringlist_free(local_user); +			rc_stringlist_free(sys_user); +			free(initdir); +		} else {  #endif -		list = ls_dir(RC_INITDIR, LS_INITD); - -#ifdef RC_USER_SERVICES -	} -#endif +			list = ls_dir(RC_INITDIR, LS_INITD);  #ifdef RC_PKG_INITDIR -		TAILQ_CONCAT(list, pkg, entries); -		rc_stringlist_free(pkg); +			TAILQ_CONCAT(list, pkg, entries); +			rc_stringlist_free(pkg);  #endif +  #ifdef RC_LOCAL_INITDIR -		TAILQ_CONCAT(list, local, entries); -		rc_stringlist_free(local); +			TAILQ_CONCAT(list, local, entries); +			rc_stringlist_free(local);  #endif +  #ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		TAILQ_CONCAT(list, local_user, entries); -		TAILQ_CONCAT(list, sys_user, entries); -		rc_stringlist_free(local_user); -		rc_stringlist_free(sys_user); -		free(user_sysconf); -		free(user_initdir); -	} +		}  #endif +		free(sysconfdir);  		return list;  	}  	/* These special levels never contain any services */  	if (strcmp(runlevel, RC_LEVEL_SINGLE) != 0) { -#ifdef RC_USER_SERVICES -		if (rc_is_user()) { -			char *user_sysconf = rc_user_sysconfdir(); -			xasprintf(&runlevel_dir, "%s/%s", user_sysconf, RC_USER_RUNLEVELS_FOLDER); -			free(user_sysconf); -		} -#endif -		snprintf(dir, sizeof(dir), "%s/%s", runlevel_dir, runlevel); -		list = ls_dir(dir, LS_INITD); -#ifdef RC_USER_SERVICES -		if (rc_is_user()) { -			free(runlevel_dir); -		} -#endif +		xasprintf(&runleveldir, "%s/%s", sysconfdir, RC_RUNLEVELDIR_FOLDER); + +		snprintf(dir, sizeof(dir), "%s/%s", runleveldir, runlevel); +		list = ls_dir(dir, LS_INITD); +		free(runleveldir);  	} + +	free(sysconfdir);  	if (!list)  		list = rc_stringlist_new();  	return list; @@ -1385,17 +1273,13 @@ rc_services_in_state(RC_SERVICE state)  	RC_STRING *d;  	char dir[PATH_MAX];  	char *p = dir; -	char *svcdir = RC_SVCDIR; - -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	p += snprintf(dir, sizeof(dir), "%s/%s",  	    svcdir, rc_parse_service_state(state)); +	free(svcdir); +  	if (state != RC_SERVICE_SCHEDULED)  		return ls_dir(dir, LS_INITD); @@ -1414,11 +1298,6 @@ rc_services_in_state(RC_SERVICE state)  	}  	rc_stringlist_free(dirs); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(svcdir); -	} -#endif  	return list;  } @@ -1431,35 +1310,30 @@ rc_service_add(const char *runlevel, const char *service)  	char file[PATH_MAX];  	char path[MAXPATHLEN] = { '\0' };  	char binit[PATH_MAX]; -	char *runlevel_dir = RC_RUNLEVELDIR; +	char *runleveldir = NULL;  	char *i; -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *user_sysconf = rc_user_sysconfdir(); -		xasprintf(&runlevel_dir, "%s/%s", user_sysconf, RC_USER_RUNLEVELS_FOLDER); -		free(user_sysconf); -	} -#endif +	char *sysconfdir = rc_sysconfdir(); + +	xasprintf(&runleveldir, "%s/%s", sysconfdir, RC_RUNLEVELDIR_FOLDER); +	free(sysconfdir);  	if (!rc_runlevel_exists(runlevel)) { +		free(runleveldir);  		errno = ENOENT;  		return false;  	}  	if (rc_service_in_runlevel(service, runlevel)) { +		free(runleveldir);  		errno = EEXIST;  		return false;  	}  	i = init = rc_service_resolve(service);  	snprintf(file, sizeof(file), "%s/%s/%s", -	    runlevel_dir, runlevel, basename_c(service)); +	    runleveldir, runlevel, basename_c(service)); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(runlevel_dir); -	} -#endif +	free(runleveldir);  	/* We need to ensure that only things in /etc/init.d are added  	 * to the boot runlevel */ @@ -1486,24 +1360,16 @@ bool  rc_service_delete(const char *runlevel, const char *service)  {  	char file[PATH_MAX]; -	char *runlevel_dir = RC_RUNLEVELDIR; +	char *runleveldir = NULL; +	char *sysconfdir = rc_sysconfdir(); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		char *user_sysconf = rc_user_sysconfdir(); -		xasprintf(&runlevel_dir, "%s/%s", user_sysconf, RC_USER_RUNLEVELS_FOLDER); -		free(user_sysconf); -	} -#endif +	xasprintf(&runleveldir, "%s/%s", sysconfdir, RC_RUNLEVELDIR_FOLDER); +	free(sysconfdir);  	snprintf(file, sizeof(file), "%s/%s/%s", -	    runlevel_dir, runlevel, basename_c(service)); +	    runleveldir, runlevel, basename_c(service)); -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		free(runlevel_dir); -	} -#endif +	free(runleveldir);  	if (unlink(file) == 0)  		return true; @@ -1518,13 +1384,7 @@ rc_services_scheduled_by(const char *service)  	RC_STRING *dir;  	char file[PATH_MAX];  	char *scheduled; -	char *svcdir = RC_SVCDIR; - -#ifdef RC_USER_SERVICES -	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); -	} -#endif +	char *svcdir = rc_svcdir();  	xasprintf(&scheduled, "%s/%s", svcdir, "/scheduled");  	dirs = ls_dir(scheduled, 0); @@ -1536,6 +1396,7 @@ rc_services_scheduled_by(const char *service)  			rc_stringlist_add(list, file);  	}  	rc_stringlist_free(dirs); +	free(svcdir);  	return list;  } @@ -1543,15 +1404,76 @@ RC_STRINGLIST *  rc_services_scheduled(const char *service)  {  	char dir[PATH_MAX]; -	char *svcdir = RC_SVCDIR; +	char *svcdir = rc_svcdir(); + +	snprintf(dir, sizeof(dir), "%s/scheduled/%s", +	    svcdir, basename_c(service)); + +	free(svcdir); +	return ls_dir(dir, LS_INITD); +} + +char * +rc_sysconfdir(void) +{ +	char *path = NULL; +#ifdef RC_USER_SERVICES +	char *env = NULL; +	if (rc_is_user()) { +		if ((env = getenv("XDG_CONFIG_HOME"))) { +			xasprintf(&path, "%s/%s", env, RC_USER_CONF_FOLDER); +		} else { +			xasprintf(&path, "%s/.config/openrc", rc_user_home()); +		} +	} else { +#endif +		path = xstrdup(RC_SYSCONFDIR); +#ifdef RC_USER_SERVICES +	} +#endif +	return path; +} +char * +rc_svcdir(void) +{ +	char *path = NULL;  #ifdef RC_USER_SERVICES +	char *env; +  	if (rc_is_user()) { -		svcdir = rc_user_svcdir(); +		if ((env = getenv("XDG_RUNTIME_DIR"))) { +			xasprintf(&path, "%s/%s", env, RC_USER_CONF_FOLDER); +		} else { +			xasprintf(&path, "/tmp/%s/%d/", RC_USER_CONF_FOLDER, getuid()); +		} +	} else { +#endif +		path = xstrdup(RC_SVCDIR); +#ifdef RC_USER_SERVICES  	}  #endif +	return path; +} -	snprintf(dir, sizeof(dir), "%s/scheduled/%s", -	    svcdir, basename_c(service)); -	return ls_dir(dir, LS_INITD); +char * +rc_cachedir(void) +{ +	char *path = NULL; +#ifdef RC_USER_SERVICES +	char *env = NULL; +	if (rc_is_user()) { +		if ((env = getenv("XDG_CACHE_HOME"))) { +			xasprintf(&path, "%s/%s", env, RC_USER_CONF_FOLDER); +		} else { +			xasprintf(&path, "%s/.cache/openrc", rc_user_home()); +		} +	} else { +#endif +		/* Not sure if cache path for system would be useful */ +		path = xstrdup(""); +#ifdef RC_USER_SERVICES +	} +#endif +	return path;  } diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in index d177ee4b..f35c9110 100644 --- a/src/librc/rc.h.in +++ b/src/librc/rc.h.in @@ -34,42 +34,38 @@ extern "C" {  #else  #define RC_SVCDIR               RC_LIBEXECDIR "/init.d"  #endif -#define RC_RUNLEVELDIR          RC_SYSCONFDIR "/runlevels" -#define RC_INITDIR              RC_SYSCONFDIR "/init.d" -#define RC_CONFDIR              RC_SYSCONFDIR "/conf.d" +#define RC_RUNLEVELDIR_FOLDER   "/runlevels" +#define RC_RUNLEVELDIR          RC_SYSCONFDIR RC_RUNLEVELDIR_FOLDER +#define RC_INITDIR_FOLDER      "/init.d" +#define RC_INITDIR              RC_SYSCONFDIR RC_INITDIR_FOLDER +#define RC_CONFDIR_FOLDER       "/conf.d" +#define RC_CONFDIR              RC_SYSCONFDIR RC_CONFDIR_FOLDER  #define RC_PLUGINDIR            RC_LIBDIR "/plugins" -#define RC_INIT_FIFO RC_SVCDIR"/init.ctl" +#define RC_INIT_FIFO       RC_SVCDIR"/init.ctl"  #define RC_PROFILE_ENV     RC_SYSCONFDIR "/profile.env"  #define RC_SYS_WHITELIST   RC_LIBEXECDIR "/conf.d/env_whitelist"  #define RC_USR_WHITELIST   RC_SYSCONFDIR "/conf.d/env_whitelist" -#define RC_CONF         RC_SYSCONFDIR "/rc.conf" -#define RC_CONF_D         RC_SYSCONFDIR "/rc.conf.d" -#define RC_CONF_OLD     RC_SYSCONFDIR "/conf.d/rc" +#define RC_CONF_FILE       "/rc.conf" +#define RC_CONF            RC_SYSCONFDIR RC_CONF_FILE +#define RC_CONF_D_FOLDER   "/rc.conf.d" +#define RC_CONF_D          RC_SYSCONFDIR RC_CONF_D_FOLDER +#define RC_CONF_OLD        RC_SYSCONFDIR "/conf.d/rc"  #ifdef RC_USER_SERVICES  #define RC_SYS_USER_INITDIR              RC_INITDIR "/user.d"  #define RC_SYS_USER_CONFDIR              RC_CONFDIR "/user.d" -#define RC_USER_INITDIR_FOLDER           "/init.d" -#define RC_USER_CONFDIR_FOLDER           "/conf.d" -#define RC_USER_RUNLEVELS_FOLDER         "/runlevels" -#define RC_USER_RUNTIME_FOLDER           "/openrc" +#define RC_USER_CONF_FOLDER              "/openrc" - -#define RC_USER_CONF                     "/rc.conf" -#define RC_USER_CONF_D                   "/rc.conf.d" +/*! @name Reserved runlevel names */ +#define RC_LEVEL_USERNONE    "none"  /*! Is openrc being ran in usermode?   * @return true if yes, otherwise false */  bool rc_is_user(void);  void rc_set_user(void); - -const char *rc_user_home(void); -char *rc_user_sysconfdir(void); -char *rc_user_svcdir(void); -char *rc_user_datadir(void);  #endif  #define RC_PATH_PREFIX     RC_LIBEXECDIR "/bin:/bin:/sbin:/usr/bin:/usr/sbin" @@ -340,6 +336,18 @@ RC_STRINGLIST *rc_services_scheduled(const char *);   * @return true if all daemons started are still running, otherwise false */  bool rc_service_daemons_crashed(const char *); +/*! Returns the system config directory, in either system or user mode + * @return allocated path string */ +char *rc_sysconfdir(void); + +/*! Returns the services directory, in either system or user mode + * @return allocated path string */ +char *rc_svcdir(void); + +/*! Returns the cache directory, in either system or user mode + * @return allocated path string */ +char *rc_cachedir(void); +  /*! @name System types   * OpenRC can support some special sub system types, normally virtualization.   * Some services cannot work in these systems, or we do something else. */  | 
