Move rc_env_filter and rc_env_config out of librc and into rc
This commit is contained in:
@ -57,8 +57,8 @@ LIBRCOBJS = librc.o librc-depend.o librc-daemon.o librc-misc.o librc-strlist.o
|
|||||||
LDLIBS_LIBRC =
|
LDLIBS_LIBRC =
|
||||||
|
|
||||||
RCOBJS = checkown.o env-update.o fstabinfo.o mountinfo.o \
|
RCOBJS = checkown.o env-update.o fstabinfo.o mountinfo.o \
|
||||||
rc-depend.o rc-plugin.o rc-status.o rc-update.o runscript.o \
|
rc-depend.o rc-misc.o rc-plugin.o rc-status.o rc-update.o \
|
||||||
start-stop-daemon.o rc.o
|
runscript.o start-stop-daemon.o rc.o
|
||||||
LDLIBS_RC = -leinfo -lrc -lutil
|
LDLIBS_RC = -leinfo -lrc -lutil
|
||||||
|
|
||||||
LIB_TARGETS = $(LIBEINFOSO) $(LIBRCSO)
|
LIB_TARGETS = $(LIBEINFOSO) $(LIBRCSO)
|
||||||
|
287
src/librc-misc.c
287
src/librc-misc.c
@ -6,15 +6,6 @@
|
|||||||
|
|
||||||
#include "librc.h"
|
#include "librc.h"
|
||||||
|
|
||||||
|
|
||||||
#define PROFILE_ENV "/etc/profile.env"
|
|
||||||
#define SYS_WHITELIST RC_LIBDIR "/conf.d/env_whitelist"
|
|
||||||
#define USR_WHITELIST "/etc/conf.d/env_whitelist"
|
|
||||||
#define RC_CONFIG "/etc/conf.d/rc"
|
|
||||||
|
|
||||||
#define PATH_PREFIX RC_LIBDIR "/bin:/bin:/sbin:/usr/bin:/usr/sbin"
|
|
||||||
|
|
||||||
|
|
||||||
bool rc_env_bool (const char *var)
|
bool rc_env_bool (const char *var)
|
||||||
{
|
{
|
||||||
char *v;
|
char *v;
|
||||||
@ -228,281 +219,3 @@ char **rc_config_list (const char *file)
|
|||||||
return (list);
|
return (list);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_config_list)
|
librc_hidden_def(rc_config_list)
|
||||||
|
|
||||||
char **rc_env_filter (void)
|
|
||||||
{
|
|
||||||
char **env = NULL;
|
|
||||||
char **whitelist = NULL;
|
|
||||||
char *env_name = NULL;
|
|
||||||
char **profile = NULL;
|
|
||||||
int count = 0;
|
|
||||||
bool got_path = false;
|
|
||||||
char *env_var;
|
|
||||||
int env_len;
|
|
||||||
char *p;
|
|
||||||
char *token;
|
|
||||||
char *sep;
|
|
||||||
char *e;
|
|
||||||
int pplen = strlen (PATH_PREFIX);
|
|
||||||
|
|
||||||
whitelist = rc_config_list (SYS_WHITELIST);
|
|
||||||
if (! whitelist)
|
|
||||||
fprintf (stderr, "system environment whitelist (" SYS_WHITELIST ") missing\n");
|
|
||||||
|
|
||||||
env = rc_config_list (USR_WHITELIST);
|
|
||||||
rc_strlist_join (&whitelist, env);
|
|
||||||
rc_strlist_free (env);
|
|
||||||
env = NULL;
|
|
||||||
|
|
||||||
if (! whitelist)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
if (rc_exists (PROFILE_ENV))
|
|
||||||
profile = rc_config_load (PROFILE_ENV);
|
|
||||||
|
|
||||||
STRLIST_FOREACH (whitelist, env_name, count) {
|
|
||||||
char *space = strchr (env_name, ' ');
|
|
||||||
if (space)
|
|
||||||
*space = 0;
|
|
||||||
|
|
||||||
env_var = getenv (env_name);
|
|
||||||
|
|
||||||
if (! env_var && profile) {
|
|
||||||
env_len = strlen (env_name) + strlen ("export ") + 1;
|
|
||||||
p = rc_xmalloc (sizeof (char *) * env_len);
|
|
||||||
snprintf (p, env_len, "export %s", env_name);
|
|
||||||
env_var = rc_config_value (profile, p);
|
|
||||||
free (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! env_var)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Ensure our PATH is prefixed with the system locations first
|
|
||||||
for a little extra security */
|
|
||||||
if (strcmp (env_name, "PATH") == 0 &&
|
|
||||||
strncmp (PATH_PREFIX, env_var, pplen) != 0)
|
|
||||||
{
|
|
||||||
got_path = true;
|
|
||||||
env_len = strlen (env_name) + strlen (env_var) + pplen + 2;
|
|
||||||
e = p = rc_xmalloc (sizeof (char *) * env_len);
|
|
||||||
p += snprintf (e, env_len, "%s=%s", env_name, PATH_PREFIX);
|
|
||||||
|
|
||||||
/* Now go through the env var and only add bits not in our PREFIX */
|
|
||||||
sep = env_var;
|
|
||||||
while ((token = strsep (&sep, ":"))) {
|
|
||||||
char *np = rc_xstrdup (PATH_PREFIX);
|
|
||||||
char *npp = np;
|
|
||||||
char *tok = NULL;
|
|
||||||
while ((tok = strsep (&npp, ":")))
|
|
||||||
if (strcmp (tok, token) == 0)
|
|
||||||
break;
|
|
||||||
if (! tok)
|
|
||||||
p += snprintf (p, env_len - (p - e), ":%s", token);
|
|
||||||
free (np);
|
|
||||||
}
|
|
||||||
*p++ = 0;
|
|
||||||
} else {
|
|
||||||
env_len = strlen (env_name) + strlen (env_var) + 2;
|
|
||||||
e = rc_xmalloc (sizeof (char *) * env_len);
|
|
||||||
snprintf (e, env_len, "%s=%s", env_name, env_var);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc_strlist_add (&env, e);
|
|
||||||
free (e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We filtered the env but didn't get a PATH? Very odd.
|
|
||||||
However, we do need a path, so use a default. */
|
|
||||||
if (! got_path) {
|
|
||||||
env_len = strlen ("PATH=") + strlen (PATH_PREFIX) + 2;
|
|
||||||
p = rc_xmalloc (sizeof (char *) * env_len);
|
|
||||||
snprintf (p, env_len, "PATH=%s", PATH_PREFIX);
|
|
||||||
rc_strlist_add (&env, p);
|
|
||||||
free (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc_strlist_free (whitelist);
|
|
||||||
rc_strlist_free (profile);
|
|
||||||
|
|
||||||
return (env);
|
|
||||||
}
|
|
||||||
librc_hidden_def(rc_env_filter)
|
|
||||||
|
|
||||||
/* Other systems may need this at some point, but for now it's Linux only */
|
|
||||||
#ifdef __linux__
|
|
||||||
static bool file_regex (const char *file, const char *regex)
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
char buffer[RC_LINEBUFFER];
|
|
||||||
regex_t re;
|
|
||||||
bool retval = false;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (! (fp = fopen (file, "r")))
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
if ((result = regcomp (&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
|
|
||||||
fclose (fp);
|
|
||||||
regerror (result, &re, buffer, sizeof (buffer));
|
|
||||||
fprintf (stderr, "file_regex: %s", buffer);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fgets (buffer, RC_LINEBUFFER, fp)) {
|
|
||||||
if (regexec (&re, buffer, 0, NULL, 0) == 0)
|
|
||||||
{
|
|
||||||
retval = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose (fp);
|
|
||||||
regfree (&re);
|
|
||||||
|
|
||||||
return (retval);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char **rc_env_config (void)
|
|
||||||
{
|
|
||||||
char **env = NULL;
|
|
||||||
char *line;
|
|
||||||
int i;
|
|
||||||
char *p;
|
|
||||||
char **config;
|
|
||||||
char *e;
|
|
||||||
#ifdef __linux__
|
|
||||||
char sys[6];
|
|
||||||
#endif
|
|
||||||
struct utsname uts;
|
|
||||||
bool has_net_fs_list = false;
|
|
||||||
FILE *fp;
|
|
||||||
char buffer[PATH_MAX];
|
|
||||||
char *runlevel = rc_runlevel_get ();
|
|
||||||
|
|
||||||
/* Don't trust environ for softlevel yet */
|
|
||||||
snprintf (buffer, PATH_MAX, "%s.%s", RC_CONFIG, runlevel);
|
|
||||||
if (rc_exists (buffer))
|
|
||||||
config = rc_config_load (buffer);
|
|
||||||
else
|
|
||||||
config = rc_config_load (RC_CONFIG);
|
|
||||||
|
|
||||||
STRLIST_FOREACH (config, line, i) {
|
|
||||||
p = strchr (line, '=');
|
|
||||||
if (! p)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
*p = 0;
|
|
||||||
e = getenv (line);
|
|
||||||
if (! e) {
|
|
||||||
*p = '=';
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
} else {
|
|
||||||
int len = strlen (line) + strlen (e) + 2;
|
|
||||||
char *new = rc_xmalloc (sizeof (char *) * len);
|
|
||||||
snprintf (new, len, "%s=%s", line, e);
|
|
||||||
rc_strlist_add (&env, new);
|
|
||||||
free (new);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rc_strlist_free (config);
|
|
||||||
|
|
||||||
/* One char less to drop the trailing / */
|
|
||||||
i = strlen ("RC_LIBDIR=") + strlen (RC_LIBDIR) + 1;
|
|
||||||
line = rc_xmalloc (sizeof (char *) * i);
|
|
||||||
snprintf (line, i, "RC_LIBDIR=" RC_LIBDIR);
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
free (line);
|
|
||||||
|
|
||||||
/* One char less to drop the trailing / */
|
|
||||||
i = strlen ("RC_SVCDIR=") + strlen (RC_SVCDIR) + 1;
|
|
||||||
line = rc_xmalloc (sizeof (char *) * i);
|
|
||||||
snprintf (line, i, "RC_SVCDIR=" RC_SVCDIR);
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
free (line);
|
|
||||||
|
|
||||||
rc_strlist_add (&env, "RC_BOOTLEVEL=" RC_LEVEL_BOOT);
|
|
||||||
|
|
||||||
i = strlen ("RC_SOFTLEVEL=") + strlen (runlevel) + 1;
|
|
||||||
line = rc_xmalloc (sizeof (char *) * i);
|
|
||||||
snprintf (line, i, "RC_SOFTLEVEL=%s", runlevel);
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
free (line);
|
|
||||||
|
|
||||||
if ((fp = fopen (RC_KSOFTLEVEL, "r"))) {
|
|
||||||
memset (buffer, 0, sizeof (buffer));
|
|
||||||
if (fgets (buffer, sizeof (buffer), fp)) {
|
|
||||||
i = strlen (buffer) - 1;
|
|
||||||
if (buffer[i] == '\n')
|
|
||||||
buffer[i] = 0;
|
|
||||||
i += strlen ("RC_DEFAULTLEVEL=") + 2;
|
|
||||||
line = rc_xmalloc (sizeof (char *) * i);
|
|
||||||
snprintf (line, i, "RC_DEFAULTLEVEL=%s", buffer);
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
free (line);
|
|
||||||
}
|
|
||||||
fclose (fp);
|
|
||||||
} else
|
|
||||||
rc_strlist_add (&env, "RC_DEFAULTLEVEL=" RC_LEVEL_DEFAULT);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
/* Linux can run some funky stuff like Xen, VServer, UML, etc
|
|
||||||
We store this special system in RC_SYS so our scripts run fast */
|
|
||||||
memset (sys, 0, sizeof (sys));
|
|
||||||
|
|
||||||
if (rc_exists ("/proc/xen")) {
|
|
||||||
if ((fp = fopen ("/proc/xen/capabilities", "r"))) {
|
|
||||||
fclose (fp);
|
|
||||||
if (file_regex ("/proc/xen/capabilities", "control_d"))
|
|
||||||
snprintf (sys, sizeof (sys), "XENU");
|
|
||||||
}
|
|
||||||
if (! sys[0])
|
|
||||||
snprintf (sys, sizeof (sys), "XEN0");
|
|
||||||
} else if (file_regex ("/proc/cpuinfo", "UML")) {
|
|
||||||
snprintf (sys, sizeof (sys), "UML");
|
|
||||||
} else if (file_regex ("/proc/self/status",
|
|
||||||
"(s_context|VxID|envID):[[:space:]]*[1-9]"))
|
|
||||||
{
|
|
||||||
snprintf (sys, sizeof (sys), "VPS");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sys[0]) {
|
|
||||||
i = strlen ("RC_SYS=") + strlen (sys) + 2;
|
|
||||||
line = rc_xmalloc (sizeof (char *) * i);
|
|
||||||
snprintf (line, i, "RC_SYS=%s", sys);
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
free (line);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Only add a NET_FS list if not defined */
|
|
||||||
STRLIST_FOREACH (env, line, i)
|
|
||||||
if (strncmp (line, "RC_NET_FS_LIST=", strlen ("RC_NET_FS_LIST=")) == 0) {
|
|
||||||
has_net_fs_list = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! has_net_fs_list) {
|
|
||||||
i = strlen ("RC_NET_FS_LIST=") + strlen (RC_NET_FS_LIST_DEFAULT) + 1;
|
|
||||||
line = rc_xmalloc (sizeof (char *) * i);
|
|
||||||
snprintf (line, i, "RC_NET_FS_LIST=%s", RC_NET_FS_LIST_DEFAULT);
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
free (line);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some scripts may need to take a different code path if Linux/FreeBSD, etc
|
|
||||||
To save on calling uname, we store it in an environment variable */
|
|
||||||
if (uname (&uts) == 0) {
|
|
||||||
i = strlen ("RC_UNAME=") + strlen (uts.sysname) + 2;
|
|
||||||
line = rc_xmalloc (sizeof (char *) * i);
|
|
||||||
snprintf (line, i, "RC_UNAME=%s", uts.sysname);
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
free (line);
|
|
||||||
}
|
|
||||||
|
|
||||||
free (runlevel);
|
|
||||||
return (env);
|
|
||||||
}
|
|
||||||
librc_hidden_def(rc_env_config)
|
|
||||||
|
@ -13,13 +13,8 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/utsname.h>
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <sys/sysinfo.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -61,9 +56,6 @@ librc_hidden_proto(rc_deptree_order_services)
|
|||||||
librc_hidden_proto(rc_deptree_update)
|
librc_hidden_proto(rc_deptree_update)
|
||||||
librc_hidden_proto(rc_deptree_update_needed)
|
librc_hidden_proto(rc_deptree_update_needed)
|
||||||
librc_hidden_proto(rc_env_bool)
|
librc_hidden_proto(rc_env_bool)
|
||||||
librc_hidden_proto(rc_env_config)
|
|
||||||
librc_hidden_proto(rc_env_filter)
|
|
||||||
librc_hidden_proto(rc_exists)
|
|
||||||
librc_hidden_proto(rc_find_pids)
|
librc_hidden_proto(rc_find_pids)
|
||||||
librc_hidden_proto(rc_runlevel_exists)
|
librc_hidden_proto(rc_runlevel_exists)
|
||||||
librc_hidden_proto(rc_runlevel_get)
|
librc_hidden_proto(rc_runlevel_get)
|
||||||
|
303
src/rc-misc.c
Normal file
303
src/rc-misc.c
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/*
|
||||||
|
librc-misc.c
|
||||||
|
rc misc functions
|
||||||
|
Copyright 2007 Gentoo Foundation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "rc.h"
|
||||||
|
#include "rc-misc.h"
|
||||||
|
#include "strlist.h"
|
||||||
|
|
||||||
|
#define PROFILE_ENV "/etc/profile.env"
|
||||||
|
#define SYS_WHITELIST RC_LIBDIR "/conf.d/env_whitelist"
|
||||||
|
#define USR_WHITELIST "/etc/conf.d/env_whitelist"
|
||||||
|
#define RC_CONFIG "/etc/conf.d/rc"
|
||||||
|
|
||||||
|
#define PATH_PREFIX RC_LIBDIR "/bin:/bin:/sbin:/usr/bin:/usr/sbin"
|
||||||
|
|
||||||
|
char **env_filter (void)
|
||||||
|
{
|
||||||
|
char **env = NULL;
|
||||||
|
char **whitelist = NULL;
|
||||||
|
char *env_name = NULL;
|
||||||
|
char **profile = NULL;
|
||||||
|
int count = 0;
|
||||||
|
bool got_path = false;
|
||||||
|
char *env_var;
|
||||||
|
int env_len;
|
||||||
|
char *p;
|
||||||
|
char *token;
|
||||||
|
char *sep;
|
||||||
|
char *e;
|
||||||
|
int pplen = strlen (PATH_PREFIX);
|
||||||
|
|
||||||
|
whitelist = rc_config_list (SYS_WHITELIST);
|
||||||
|
if (! whitelist)
|
||||||
|
fprintf (stderr, "system environment whitelist (" SYS_WHITELIST ") missing\n");
|
||||||
|
|
||||||
|
env = rc_config_list (USR_WHITELIST);
|
||||||
|
rc_strlist_join (&whitelist, env);
|
||||||
|
rc_strlist_free (env);
|
||||||
|
env = NULL;
|
||||||
|
|
||||||
|
if (! whitelist)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if (rc_exists (PROFILE_ENV))
|
||||||
|
profile = rc_config_load (PROFILE_ENV);
|
||||||
|
|
||||||
|
STRLIST_FOREACH (whitelist, env_name, count) {
|
||||||
|
char *space = strchr (env_name, ' ');
|
||||||
|
if (space)
|
||||||
|
*space = 0;
|
||||||
|
|
||||||
|
env_var = getenv (env_name);
|
||||||
|
|
||||||
|
if (! env_var && profile) {
|
||||||
|
env_len = strlen (env_name) + strlen ("export ") + 1;
|
||||||
|
p = rc_xmalloc (sizeof (char *) * env_len);
|
||||||
|
snprintf (p, env_len, "export %s", env_name);
|
||||||
|
env_var = rc_config_value (profile, p);
|
||||||
|
free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! env_var)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Ensure our PATH is prefixed with the system locations first
|
||||||
|
for a little extra security */
|
||||||
|
if (strcmp (env_name, "PATH") == 0 &&
|
||||||
|
strncmp (PATH_PREFIX, env_var, pplen) != 0)
|
||||||
|
{
|
||||||
|
got_path = true;
|
||||||
|
env_len = strlen (env_name) + strlen (env_var) + pplen + 2;
|
||||||
|
e = p = rc_xmalloc (sizeof (char *) * env_len);
|
||||||
|
p += snprintf (e, env_len, "%s=%s", env_name, PATH_PREFIX);
|
||||||
|
|
||||||
|
/* Now go through the env var and only add bits not in our PREFIX */
|
||||||
|
sep = env_var;
|
||||||
|
while ((token = strsep (&sep, ":"))) {
|
||||||
|
char *np = rc_xstrdup (PATH_PREFIX);
|
||||||
|
char *npp = np;
|
||||||
|
char *tok = NULL;
|
||||||
|
while ((tok = strsep (&npp, ":")))
|
||||||
|
if (strcmp (tok, token) == 0)
|
||||||
|
break;
|
||||||
|
if (! tok)
|
||||||
|
p += snprintf (p, env_len - (p - e), ":%s", token);
|
||||||
|
free (np);
|
||||||
|
}
|
||||||
|
*p++ = 0;
|
||||||
|
} else {
|
||||||
|
env_len = strlen (env_name) + strlen (env_var) + 2;
|
||||||
|
e = rc_xmalloc (sizeof (char *) * env_len);
|
||||||
|
snprintf (e, env_len, "%s=%s", env_name, env_var);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc_strlist_add (&env, e);
|
||||||
|
free (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We filtered the env but didn't get a PATH? Very odd.
|
||||||
|
However, we do need a path, so use a default. */
|
||||||
|
if (! got_path) {
|
||||||
|
env_len = strlen ("PATH=") + strlen (PATH_PREFIX) + 2;
|
||||||
|
p = rc_xmalloc (sizeof (char *) * env_len);
|
||||||
|
snprintf (p, env_len, "PATH=%s", PATH_PREFIX);
|
||||||
|
rc_strlist_add (&env, p);
|
||||||
|
free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc_strlist_free (whitelist);
|
||||||
|
rc_strlist_free (profile);
|
||||||
|
|
||||||
|
return (env);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Other systems may need this at some point, but for now it's Linux only */
|
||||||
|
#ifdef __linux__
|
||||||
|
static bool file_regex (const char *file, const char *regex)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char buffer[RC_LINEBUFFER];
|
||||||
|
regex_t re;
|
||||||
|
bool retval = false;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (! (fp = fopen (file, "r")))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if ((result = regcomp (&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
|
||||||
|
fclose (fp);
|
||||||
|
regerror (result, &re, buffer, sizeof (buffer));
|
||||||
|
fprintf (stderr, "file_regex: %s", buffer);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets (buffer, RC_LINEBUFFER, fp)) {
|
||||||
|
if (regexec (&re, buffer, 0, NULL, 0) == 0)
|
||||||
|
{
|
||||||
|
retval = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose (fp);
|
||||||
|
regfree (&re);
|
||||||
|
|
||||||
|
return (retval);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char **env_config (void)
|
||||||
|
{
|
||||||
|
char **env = NULL;
|
||||||
|
char *line;
|
||||||
|
int i;
|
||||||
|
char *p;
|
||||||
|
char **config;
|
||||||
|
char *e;
|
||||||
|
#ifdef __linux__
|
||||||
|
char sys[6];
|
||||||
|
#endif
|
||||||
|
struct utsname uts;
|
||||||
|
bool has_net_fs_list = false;
|
||||||
|
FILE *fp;
|
||||||
|
char buffer[PATH_MAX];
|
||||||
|
char *runlevel = rc_runlevel_get ();
|
||||||
|
|
||||||
|
/* Don't trust environ for softlevel yet */
|
||||||
|
snprintf (buffer, PATH_MAX, "%s.%s", RC_CONFIG, runlevel);
|
||||||
|
if (rc_exists (buffer))
|
||||||
|
config = rc_config_load (buffer);
|
||||||
|
else
|
||||||
|
config = rc_config_load (RC_CONFIG);
|
||||||
|
|
||||||
|
STRLIST_FOREACH (config, line, i) {
|
||||||
|
p = strchr (line, '=');
|
||||||
|
if (! p)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*p = 0;
|
||||||
|
e = getenv (line);
|
||||||
|
if (! e) {
|
||||||
|
*p = '=';
|
||||||
|
rc_strlist_add (&env, line);
|
||||||
|
} else {
|
||||||
|
int len = strlen (line) + strlen (e) + 2;
|
||||||
|
char *new = rc_xmalloc (sizeof (char *) * len);
|
||||||
|
snprintf (new, len, "%s=%s", line, e);
|
||||||
|
rc_strlist_add (&env, new);
|
||||||
|
free (new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc_strlist_free (config);
|
||||||
|
|
||||||
|
/* One char less to drop the trailing / */
|
||||||
|
i = strlen ("RC_LIBDIR=") + strlen (RC_LIBDIR) + 1;
|
||||||
|
line = rc_xmalloc (sizeof (char *) * i);
|
||||||
|
snprintf (line, i, "RC_LIBDIR=" RC_LIBDIR);
|
||||||
|
rc_strlist_add (&env, line);
|
||||||
|
free (line);
|
||||||
|
|
||||||
|
/* One char less to drop the trailing / */
|
||||||
|
i = strlen ("RC_SVCDIR=") + strlen (RC_SVCDIR) + 1;
|
||||||
|
line = rc_xmalloc (sizeof (char *) * i);
|
||||||
|
snprintf (line, i, "RC_SVCDIR=" RC_SVCDIR);
|
||||||
|
rc_strlist_add (&env, line);
|
||||||
|
free (line);
|
||||||
|
|
||||||
|
rc_strlist_add (&env, "RC_BOOTLEVEL=" RC_LEVEL_BOOT);
|
||||||
|
|
||||||
|
i = strlen ("RC_SOFTLEVEL=") + strlen (runlevel) + 1;
|
||||||
|
line = rc_xmalloc (sizeof (char *) * i);
|
||||||
|
snprintf (line, i, "RC_SOFTLEVEL=%s", runlevel);
|
||||||
|
rc_strlist_add (&env, line);
|
||||||
|
free (line);
|
||||||
|
|
||||||
|
if ((fp = fopen (RC_KSOFTLEVEL, "r"))) {
|
||||||
|
memset (buffer, 0, sizeof (buffer));
|
||||||
|
if (fgets (buffer, sizeof (buffer), fp)) {
|
||||||
|
i = strlen (buffer) - 1;
|
||||||
|
if (buffer[i] == '\n')
|
||||||
|
buffer[i] = 0;
|
||||||
|
i += strlen ("RC_DEFAULTLEVEL=") + 2;
|
||||||
|
line = rc_xmalloc (sizeof (char *) * i);
|
||||||
|
snprintf (line, i, "RC_DEFAULTLEVEL=%s", buffer);
|
||||||
|
rc_strlist_add (&env, line);
|
||||||
|
free (line);
|
||||||
|
}
|
||||||
|
fclose (fp);
|
||||||
|
} else
|
||||||
|
rc_strlist_add (&env, "RC_DEFAULTLEVEL=" RC_LEVEL_DEFAULT);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
/* Linux can run some funky stuff like Xen, VServer, UML, etc
|
||||||
|
We store this special system in RC_SYS so our scripts run fast */
|
||||||
|
memset (sys, 0, sizeof (sys));
|
||||||
|
|
||||||
|
if (rc_exists ("/proc/xen")) {
|
||||||
|
if ((fp = fopen ("/proc/xen/capabilities", "r"))) {
|
||||||
|
fclose (fp);
|
||||||
|
if (file_regex ("/proc/xen/capabilities", "control_d"))
|
||||||
|
snprintf (sys, sizeof (sys), "XENU");
|
||||||
|
}
|
||||||
|
if (! sys[0])
|
||||||
|
snprintf (sys, sizeof (sys), "XEN0");
|
||||||
|
} else if (file_regex ("/proc/cpuinfo", "UML")) {
|
||||||
|
snprintf (sys, sizeof (sys), "UML");
|
||||||
|
} else if (file_regex ("/proc/self/status",
|
||||||
|
"(s_context|VxID|envID):[[:space:]]*[1-9]"))
|
||||||
|
{
|
||||||
|
snprintf (sys, sizeof (sys), "VPS");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sys[0]) {
|
||||||
|
i = strlen ("RC_SYS=") + strlen (sys) + 2;
|
||||||
|
line = rc_xmalloc (sizeof (char *) * i);
|
||||||
|
snprintf (line, i, "RC_SYS=%s", sys);
|
||||||
|
rc_strlist_add (&env, line);
|
||||||
|
free (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Only add a NET_FS list if not defined */
|
||||||
|
STRLIST_FOREACH (env, line, i)
|
||||||
|
if (strncmp (line, "RC_NET_FS_LIST=", strlen ("RC_NET_FS_LIST=")) == 0) {
|
||||||
|
has_net_fs_list = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! has_net_fs_list) {
|
||||||
|
i = strlen ("RC_NET_FS_LIST=") + strlen (RC_NET_FS_LIST_DEFAULT) + 1;
|
||||||
|
line = rc_xmalloc (sizeof (char *) * i);
|
||||||
|
snprintf (line, i, "RC_NET_FS_LIST=%s", RC_NET_FS_LIST_DEFAULT);
|
||||||
|
rc_strlist_add (&env, line);
|
||||||
|
free (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some scripts may need to take a different code path if Linux/FreeBSD, etc
|
||||||
|
To save on calling uname, we store it in an environment variable */
|
||||||
|
if (uname (&uts) == 0) {
|
||||||
|
i = strlen ("RC_UNAME=") + strlen (uts.sysname) + 2;
|
||||||
|
line = rc_xmalloc (sizeof (char *) * i);
|
||||||
|
snprintf (line, i, "RC_UNAME=%s", uts.sysname);
|
||||||
|
rc_strlist_add (&env, line);
|
||||||
|
free (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
free (runlevel);
|
||||||
|
return (env);
|
||||||
|
}
|
@ -87,4 +87,7 @@ static inline bool rc_exists (const char *pathname)
|
|||||||
return (stat (pathname, &buf) == 0);
|
return (stat (pathname, &buf) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char **env_filter (void);
|
||||||
|
char **env_config (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
6
src/rc.c
6
src/rc.c
@ -485,7 +485,7 @@ static void sulogin (bool cont)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
newenv = rc_env_filter ();
|
newenv = env_filter ();
|
||||||
|
|
||||||
if (cont) {
|
if (cont) {
|
||||||
int status = 0;
|
int status = 0;
|
||||||
@ -839,8 +839,8 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
/* Ensure our environment is pure
|
/* Ensure our environment is pure
|
||||||
Also, add our configuration to it */
|
Also, add our configuration to it */
|
||||||
env = rc_env_filter ();
|
env = env_filter ();
|
||||||
tmplist = rc_env_config ();
|
tmplist = env_config ();
|
||||||
rc_strlist_join (&env, tmplist);
|
rc_strlist_join (&env, tmplist);
|
||||||
rc_strlist_free (tmplist);
|
rc_strlist_free (tmplist);
|
||||||
|
|
||||||
|
8
src/rc.h
8
src/rc.h
@ -334,14 +334,6 @@ char **rc_config_load (const char *file);
|
|||||||
/*! Return the value of the entry from a key=value list. */
|
/*! Return the value of the entry from a key=value list. */
|
||||||
char *rc_config_value (char **list, const char *entry);
|
char *rc_config_value (char **list, const char *entry);
|
||||||
|
|
||||||
/*! Return a NULL terminated string list of variables allowed through
|
|
||||||
* from the current environemnt. */
|
|
||||||
char **rc_env_filter (void);
|
|
||||||
|
|
||||||
/*! Return a NULL terminated string list of enviroment variables made from
|
|
||||||
* our configuration files. */
|
|
||||||
char **rc_env_config (void);
|
|
||||||
|
|
||||||
/*! Check if an environment variable is a boolean and return it's value.
|
/*! Check if an environment variable is a boolean and return it's value.
|
||||||
* If variable is not a boolean then we set errno to be ENOENT when it does
|
* If variable is not a boolean then we set errno to be ENOENT when it does
|
||||||
* not exist or EINVAL if it's not a boolean.
|
* not exist or EINVAL if it's not a boolean.
|
||||||
|
@ -10,8 +10,6 @@ global:
|
|||||||
rc_deptree_update;
|
rc_deptree_update;
|
||||||
rc_deptree_update_needed;
|
rc_deptree_update_needed;
|
||||||
rc_env_bool;
|
rc_env_bool;
|
||||||
rc_env_config;
|
|
||||||
rc_env_filter;
|
|
||||||
rc_environ_fd;
|
rc_environ_fd;
|
||||||
rc_find_pids;
|
rc_find_pids;
|
||||||
rc_runlevel_exists;
|
rc_runlevel_exists;
|
||||||
|
@ -1046,8 +1046,8 @@ int runscript (int argc, char **argv)
|
|||||||
if ((softlevel = rc_xstrdup (getenv ("RC_SOFTLEVEL"))) == NULL) {
|
if ((softlevel = rc_xstrdup (getenv ("RC_SOFTLEVEL"))) == NULL) {
|
||||||
/* Ensure our environment is pure
|
/* Ensure our environment is pure
|
||||||
Also, add our configuration to it */
|
Also, add our configuration to it */
|
||||||
tmplist = rc_env_config ();
|
tmplist = env_config ();
|
||||||
env = rc_env_filter ();
|
env = env_filter ();
|
||||||
rc_strlist_join (&env, tmplist);
|
rc_strlist_join (&env, tmplist);
|
||||||
rc_strlist_free (tmplist);
|
rc_strlist_free (tmplist);
|
||||||
tmplist = NULL;
|
tmplist = NULL;
|
||||||
|
Reference in New Issue
Block a user