librc no longer uses libeinfo. deptree function names are now all under rc_deptree_

This commit is contained in:
Roy Marples 2007-09-29 16:42:08 +00:00
parent b153f67fe3
commit 837f43e163
11 changed files with 230 additions and 296 deletions

View File

@ -54,12 +54,12 @@ LDLIBS_LIBEINFO = $(LDLIBS)
LIBRCSOVER = 0
LIBRCSO = librc.so.$(LIBRCSOVER)
LIBRCOBJS = librc.o librc-depend.o librc-daemon.o librc-misc.o librc-strlist.o
LDLIBS_LIBRC = -leinfo
LDLIBS_LIBRC =
RCOBJS = checkown.o env-update.o fstabinfo.o mountinfo.o \
rc-depend.o rc-plugin.o rc-status.o rc-update.o runscript.o \
start-stop-daemon.o rc.o
LDLIBS_RC = $(LDLIBS_LIBRC) -lrc -lutil
LDLIBS_RC = $(LDLIBS_LIBRC) -leinfo -lrc -lutil
LIB_TARGETS = $(LIBEINFOSO) $(LIBRCSO)
SBIN_TARGETS = rc

View File

@ -7,6 +7,8 @@
* Released under the GPLv2
*/
#include "rc.h"
int checkown (int argc, char **argv);
int env_update (int argc, char **argv);
int fstabinfo (int argc, char **argv);
@ -17,3 +19,5 @@ int rc_update (int argc, char **argv);
int runscript (int argc, char **argv);
int start_stop_daemon (int argc, char **argv);
/* Handy function so we can wrap einfo around our deptree */
rc_depinfo_t *_rc_deptree_load (void);

View File

@ -79,16 +79,16 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
DIR *procdir;
struct dirent *entry;
int npids = 0;
int foundany = false;
pid_t p;
pid_t *pids = NULL;
pid_t *tmp = NULL;
char buffer[PATH_MAX];
struct stat sb;
pid_t runscript_pid = 0;
char *pp;
if ((procdir = opendir ("/proc")) == NULL)
eerrorx ("opendir `/proc': %s", strerror (errno));
return (NULL);
/*
We never match RC_RUNSCRIPT_PID if present so we avoid the below
@ -109,7 +109,6 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
while ((entry = readdir (procdir)) != NULL) {
if (sscanf (entry->d_name, "%d", &p) != 1)
continue;
foundany = true;
if (runscript_pid != 0 && runscript_pid == p)
continue;
@ -129,9 +128,14 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
if (exec && ! cmd && ! pid_is_exec (p, exec))
continue;
pids = realloc (pids, sizeof (pid_t) * (npids + 2));
if (! pids)
eerrorx ("memory exhausted");
tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
if (! tmp) {
free (pids);
closedir (procdir);
errno = ENOMEM;
return (NULL);
}
pids = tmp;
pids[npids] = p;
pids[npids + 1] = 0;
@ -139,9 +143,6 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
}
closedir (procdir);
if (! foundany)
eerrorx ("nothing in /proc");
return (pids);
}
librc_hidden_def(rc_find_pids)
@ -177,6 +178,7 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
int argc = 0;
char **argv;
pid_t *pids = NULL;
pid_t *tmp;
int npids = 0;
if ((kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL)
@ -210,15 +212,20 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
continue;
}
pids = realloc (pids, sizeof (pid_t) * (npids + 2));
if (! pids)
eerrorx ("memory exhausted");
tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
if (! tmp) {
free (pids);
kvm_close (kd);
errno = ENOMEM;
return (NULL);
}
pids = tmp;
pids[npids] = p;
pids[npids + 1] = 0;
npids++;
}
kvm_close(kd);
kvm_close (kd);
return (pids);
}
@ -238,13 +245,7 @@ static bool _match_daemon (const char *path, const char *file,
int lc = 0;
int m = 0;
if (! rc_exists (ffile)) {
free (ffile);
return (false);
}
if ((fp = fopen (ffile, "r")) == NULL) {
eerror ("fopen `%s': %s", ffile, strerror (errno));
free (ffile);
return (false);
}
@ -350,19 +351,14 @@ void rc_set_service_daemon (const char *service, const char *exec,
char buffer[10];
FILE *fp;
if (! rc_is_dir (dirpath))
if (mkdir (dirpath, 0755) != 0)
eerror ("mkdir `%s': %s", dirpath, strerror (errno));
snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1);
file = rc_strcatpaths (dirpath, buffer, (char *) NULL);
if ((fp = fopen (file, "w")) == NULL)
eerror ("fopen `%s': %s", file, strerror (errno));
else {
fprintf (fp, "%s\n%s\n%s\n", mexec, mname, mpidfile);
if (mkdir (dirpath, 0755) == 0 || errno == EEXIST) {
snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1);
file = rc_strcatpaths (dirpath, buffer, (char *) NULL);
if ((fp = fopen (file, "w")))
fprintf (fp, "%s\n%s\n%s\n", mexec, mname, mpidfile);
fclose (fp);
free (file);
}
free (file);
}
free (mexec);
@ -458,10 +454,8 @@ bool rc_service_daemons_crashed (const char *service)
path = rc_strcatpaths (dirpath, file, (char *) NULL);
fp = fopen (path, "r");
free (path);
if (! fp) {
eerror ("fopen `%s': %s", file, strerror (errno));
continue;
}
if (! fp)
break;
while ((fgets (buffer, RC_LINEBUFFER, fp))) {
int lb = strlen (buffer) - 1;
@ -499,13 +493,11 @@ bool rc_service_daemons_crashed (const char *service)
}
if ((fp = fopen (pidfile, "r")) == NULL) {
eerror ("fopen `%s': %s", pidfile, strerror (errno));
retval = true;
break;
}
if (fscanf (fp, "%d", &pid) != 1) {
eerror ("no pid found in `%s'", pidfile);
fclose (fp);
retval = true;
break;

View File

@ -41,7 +41,7 @@ static char *get_shell_value (char *string)
return (NULL);
}
void rc_free_deptree (rc_depinfo_t *deptree)
void rc_deptree_free (rc_depinfo_t *deptree)
{
rc_depinfo_t *di = deptree;
while (di)
@ -61,9 +61,9 @@ void rc_free_deptree (rc_depinfo_t *deptree)
di = dip;
}
}
librc_hidden_def(rc_free_deptree)
librc_hidden_def(rc_deptree_free)
rc_depinfo_t *rc_load_deptree (void)
rc_depinfo_t *rc_deptree_load (void)
{
FILE *fp;
rc_depinfo_t *deptree = NULL;
@ -75,9 +75,6 @@ rc_depinfo_t *rc_load_deptree (void)
char *e;
int i;
/* Update our deptree, but only if we need too */
rc_update_deptree (false);
if (! (fp = fopen (RC_DEPTREE, "r")))
return (NULL);
@ -150,9 +147,9 @@ rc_depinfo_t *rc_load_deptree (void)
return (deptree);
}
librc_hidden_def(rc_load_deptree)
librc_hidden_def(rc_deptree_load)
rc_depinfo_t *rc_get_depinfo (rc_depinfo_t *deptree, const char *service)
rc_depinfo_t *rc_deptree_depinfo (rc_depinfo_t *deptree, const char *service)
{
rc_depinfo_t *di;
@ -165,9 +162,9 @@ rc_depinfo_t *rc_get_depinfo (rc_depinfo_t *deptree, const char *service)
return (NULL);
}
librc_hidden_def(rc_get_depinfo)
librc_hidden_def(rc_deptree_depinfo)
rc_deptype_t *rc_get_deptype (rc_depinfo_t *depinfo, const char *type)
rc_deptype_t *rc_deptree_deptype (rc_depinfo_t *depinfo, const char *type)
{
rc_deptype_t *dt;
@ -180,7 +177,7 @@ rc_deptype_t *rc_get_deptype (rc_depinfo_t *depinfo, const char *type)
return (NULL);
}
librc_hidden_def(rc_get_deptype)
librc_hidden_def(rc_deptree_deptype)
static bool valid_service (const char *runlevel, const char *service)
{
@ -263,7 +260,7 @@ static char **get_provided (rc_depinfo_t *deptree, rc_depinfo_t *depinfo,
if (rc_service_exists (depinfo->service))
return (NULL);
dt = rc_get_deptype (depinfo, "providedby");
dt = rc_deptree_deptype (depinfo, "providedby");
if (! dt)
return (NULL);
@ -382,7 +379,7 @@ static void visit_service (rc_depinfo_t *deptree, char **types,
STRLIST_FOREACH (types, item, i)
{
if ((dt = rc_get_deptype (depinfo, item)))
if ((dt = rc_deptree_deptype (depinfo, item)))
{
STRLIST_FOREACH (dt->services, service, j)
{
@ -392,12 +389,12 @@ static void visit_service (rc_depinfo_t *deptree, char **types,
continue;
}
di = rc_get_depinfo (deptree, service);
di = rc_deptree_depinfo (deptree, service);
if ((provides = get_provided (deptree, di, runlevel, options)))
{
STRLIST_FOREACH (provides, lp, k)
{
di = rc_get_depinfo (deptree, lp);
di = rc_deptree_depinfo (deptree, lp);
if (di && (strcmp (item, "ineed") == 0 ||
strcmp (item, "needsme") == 0 ||
valid_service (runlevel, di->service)))
@ -417,11 +414,12 @@ static void visit_service (rc_depinfo_t *deptree, char **types,
}
/* Now visit the stuff we provide for */
if (options & RC_DEP_TRACE && (dt = rc_get_deptype (depinfo, "iprovide")))
if (options & RC_DEP_TRACE &&
(dt = rc_deptree_deptype (depinfo, "iprovide")))
{
STRLIST_FOREACH (dt->services, service, i)
{
if ((di = rc_get_depinfo (deptree, service)))
if ((di = rc_deptree_depinfo (deptree, service)))
if ((provides = get_provided (deptree, di, runlevel, options)))
{
STRLIST_FOREACH (provides, lp, j)
@ -440,13 +438,13 @@ static void visit_service (rc_depinfo_t *deptree, char **types,
are also the service calling us or we are provided by something */
svcname = getenv("SVCNAME");
if (! svcname || strcmp (svcname, depinfo->service) != 0)
if (! rc_get_deptype (depinfo, "providedby"))
if (! rc_deptree_deptype (depinfo, "providedby"))
rc_strlist_add (&sorted->list, depinfo->service);
}
char **rc_get_depends (rc_depinfo_t *deptree,
char **types, char **services,
const char *runlevel, int options)
char **rc_deptree_depends (rc_depinfo_t *deptree,
char **types, char **services,
const char *runlevel, int options)
{
struct lhead sorted;
struct lhead visited;
@ -466,17 +464,17 @@ char **rc_get_depends (rc_depinfo_t *deptree,
STRLIST_FOREACH (services, service, i)
{
di = rc_get_depinfo (deptree, service);
di = rc_deptree_depinfo (deptree, service);
visit_service (deptree, types, &sorted, &visited, di, runlevel, options);
}
rc_strlist_free (visited.list);
return (sorted.list);
}
librc_hidden_def(rc_get_depends)
librc_hidden_def(rc_deptree_depends)
char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
int options)
char **rc_deptree_order_services (rc_depinfo_t *deptree, const char *runlevel,
int options)
{
char **list = NULL;
char **types = NULL;
@ -530,8 +528,8 @@ char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
rc_strlist_add (&types, "ineed");
rc_strlist_add (&types, "iuse");
rc_strlist_add (&types, "iafter");
services = rc_get_depends (deptree, types, list, runlevel,
RC_DEP_STRICT | RC_DEP_TRACE | options);
services = rc_deptree_depends (deptree, types, list, runlevel,
RC_DEP_STRICT | RC_DEP_TRACE | options);
rc_strlist_free (list);
rc_strlist_free (types);
@ -540,7 +538,7 @@ char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
return (services);
}
librc_hidden_def(rc_order_services)
librc_hidden_def(rc_deptree_order_services)
static bool is_newer_than (const char *file, const char *target)
{
@ -611,6 +609,39 @@ static const char *depdirs[] =
NULL
};
bool rc_deptree_update_needed (void)
{
bool newer = false;
char **config;
char *service;
int i;
/* Create base directories if needed */
for (i = 0; depdirs[i]; i++)
if (mkdir (depdirs[i], 0755) != 0 && errno != EEXIST)
fprintf (stderr, "mkdir `%s': %s", depdirs[i], strerror (errno));
/* Quick test to see if anything we use has changed */
if (! is_newer_than (RC_DEPTREE, RC_INITDIR) ||
! is_newer_than (RC_DEPTREE, RC_CONFDIR) ||
! is_newer_than (RC_DEPTREE, "/etc/rc.conf"))
return (true);
/* Some init scripts dependencies change depending on config files
* outside of baselayout, like syslog-ng, so we check those too. */
config = rc_get_list (RC_DEPCONFIG);
STRLIST_FOREACH (config, service, i) {
if (! is_newer_than (RC_DEPTREE, service)) {
newer = true;
break;
}
}
rc_strlist_free (config);
return (newer);
}
librc_hidden_def(rc_deptree_update_needed)
/* This is a 5 phase operation
Phase 1 is a shell script which loads each init script and config in turn
and echos their dependency info to stdout
@ -619,7 +650,7 @@ static const char *depdirs[] =
Phase 4 scans that depinfo object and puts in backlinks
Phase 5 saves the depinfo object to disk
*/
int rc_update_deptree (bool force)
int rc_deptree_update (void)
{
char *depends;
char *service;
@ -642,41 +673,6 @@ int rc_update_deptree (bool force)
int k;
bool already_added;
/* Create base directories if needed */
for (i = 0; depdirs[i]; i++)
if (! rc_is_dir (depdirs[i]))
if (mkdir (depdirs[i], 0755) != 0)
eerrorx ("mkdir `%s': %s", depdirs[i], strerror (errno));
/* Quick test to see if anything we use has changed */
if (! force &&
is_newer_than (RC_DEPTREE, RC_INITDIR) &&
is_newer_than (RC_DEPTREE, RC_CONFDIR) &&
is_newer_than (RC_DEPTREE, "/etc/rc.conf"))
{
bool newer = false;
/* Some init scripts dependencies change depending on config files
* outside of baselayout, like syslog-ng, so we check those too. */
if (! rc_exists (RC_DEPCONFIG))
return 0;
config = rc_get_list (RC_DEPCONFIG);
STRLIST_FOREACH (config, service, i) {
if (! is_newer_than (RC_DEPTREE, service)) {
newer = true;
break;
}
}
rc_strlist_free (config);
config = NULL;
if (! newer)
return (0);
}
ebegin ("Caching service dependencies");
/* Some init scripts need RC_LIBDIR to source stuff
Ideally we should be setting our full env instead */
if (! getenv ("RC_LIBDIR"))
@ -684,7 +680,7 @@ int rc_update_deptree (bool force)
/* Phase 1 */
if (! (fp = popen (GENDEP, "r")))
eerrorx ("popen: %s", strerror (errno));
return (-1);
deptree = rc_xmalloc (sizeof (rc_depinfo_t));
memset (deptree, 0, sizeof (rc_depinfo_t));
@ -783,7 +779,7 @@ int rc_update_deptree (bool force)
/* Phase 3 - add our providors to the tree */
for (depinfo = deptree; depinfo; depinfo = depinfo->next)
{
if ((deptype = rc_get_deptype (depinfo, "iprovide")))
if ((deptype = rc_deptree_deptype (depinfo, "iprovide")))
STRLIST_FOREACH (deptype->services, service, i)
{
for (di = deptree; di; di = di->next)
@ -807,19 +803,20 @@ int rc_update_deptree (bool force)
{
for (i = 0; deppairs[i].depend; i++)
{
deptype = rc_get_deptype (depinfo, deppairs[i].depend);
deptype = rc_deptree_deptype (depinfo, deppairs[i].depend);
if (! deptype)
continue;
STRLIST_FOREACH (deptype->services, service, j)
{
di = rc_get_depinfo (deptree, service);
di = rc_deptree_depinfo (deptree, service);
if (! di)
{
if (strcmp (deptype->type, "ineed") == 0)
{
eerror ("Service `%s' needs non existant service `%s'",
depinfo->service, service);
fprintf (stderr,
"Service `%s' needs non existant service `%s'",
depinfo->service, service);
retval = -1;
}
continue;
@ -869,10 +866,7 @@ int rc_update_deptree (bool force)
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, "w")))
eerror ("fopen `%s': %s", RC_DEPTREE, strerror (errno));
else
{
if ((fp = fopen (RC_DEPTREE, "w"))) {
i = 0;
for (depinfo = deptree; depinfo; depinfo = depinfo->next)
{
@ -890,24 +884,22 @@ int rc_update_deptree (bool force)
i++;
}
fclose (fp);
}
} else
fprintf (stderr, "fopen `%s': %s", RC_DEPTREE, strerror (errno));
/* Save our external config files to disk */
if (config) {
if (! (fp = fopen (RC_DEPCONFIG, "w")))
eerror ("fopen `%s': %s", RC_DEPCONFIG, strerror (errno));
else
{
if ((fp = fopen (RC_DEPCONFIG, "w"))) {
STRLIST_FOREACH (config, service, i)
fprintf (fp, "%s\n", service);
fclose (fp);
}
} else
fprintf (stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror (errno));
rc_strlist_free (config);
}
rc_free_deptree (deptree);
rc_deptree_free (deptree);
eend (retval, "Failed to update the service dependency tree");
return (retval);
}
librc_hidden_def(rc_update_deptree)
librc_hidden_def(rc_deptree_update)

View File

@ -6,7 +6,7 @@
#include "librc.h"
#define ERRX eerrorx("out of memory");
#define ERRX fprintf (stderr, "out of memory\n"); exit (1)
#define PROFILE_ENV "/etc/profile.env"
#define SYS_WHITELIST RC_LIBDIR "/conf.d/env_whitelist"
@ -26,7 +26,7 @@ void *rc_xmalloc (size_t size)
if (value)
return (value);
ERRX
ERRX;
}
librc_hidden_def(rc_xmalloc)
@ -37,7 +37,7 @@ void *rc_xrealloc (void *ptr, size_t size)
if (value)
return (value);
ERRX
ERRX;
}
librc_hidden_def(rc_xrealloc)
@ -53,7 +53,7 @@ char *rc_xstrdup (const char *str)
if (value)
return (value);
ERRX
ERRX;
}
librc_hidden_def(rc_xstrdup)
@ -217,14 +217,9 @@ char **rc_ls_dir (const char *dir, int options)
struct dirent *d;
char **list = NULL;
if (! dir)
if ((dp = opendir (dir)) == NULL)
return (NULL);
if ((dp = opendir (dir)) == NULL) {
eerror ("failed to opendir `%s': %s", dir, strerror (errno));
return (NULL);
}
errno = 0;
while (((d = readdir (dp)) != NULL) && errno == 0) {
if (d->d_name[0] != '.') {
@ -248,12 +243,6 @@ char **rc_ls_dir (const char *dir, int options)
}
closedir (dp);
if (errno != 0) {
eerror ("failed to readdir `%s': %s", dir, strerror (errno));
rc_strlist_free (list);
return (NULL);
}
return (list);
}
librc_hidden_def(rc_ls_dir)
@ -263,14 +252,9 @@ bool rc_rm_dir (const char *pathname, bool top)
DIR *dp;
struct dirent *d;
if (! pathname)
if ((dp = opendir (pathname)) == NULL)
return (false);
if ((dp = opendir (pathname)) == NULL) {
eerror ("failed to opendir `%s': %s", pathname, strerror (errno));
return (false);
}
errno = 0;
while (((d = readdir (dp)) != NULL) && errno == 0) {
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0) {
@ -284,7 +268,6 @@ bool rc_rm_dir (const char *pathname, bool top)
}
} else {
if (unlink (tmp)) {
eerror ("failed to unlink `%s': %s", tmp, strerror (errno));
free (tmp);
closedir (dp);
return (false);
@ -293,14 +276,10 @@ bool rc_rm_dir (const char *pathname, bool top)
free (tmp);
}
}
if (errno != 0)
eerror ("failed to readdir `%s': %s", pathname, strerror (errno));
closedir (dp);
if (top && rmdir (pathname) != 0) {
eerror ("failed to rmdir `%s': %s", pathname, strerror (errno));
return false;
}
if (top && rmdir (pathname) != 0)
return (false);
return (true);
}
@ -321,14 +300,9 @@ char **rc_get_config (const char *file)
char *entry;
char *newline;
if (! file)
if (! (fp = fopen (file, "r")))
return (NULL);
if (! (fp = fopen (file, "r"))) {
ewarn ("rc_get_config `%s': %s", file, strerror (errno));
return (NULL);
}
while (fgets (buffer, RC_LINEBUFFER, fp)) {
p = buffer;
@ -419,10 +393,8 @@ char **rc_get_list (const char *file)
char *token;
char **list = NULL;
if (! (fp = fopen (file, "r"))) {
ewarn ("rc_get_list `%s': %s", file, strerror (errno));
if (! (fp = fopen (file, "r")))
return (NULL);
}
while (fgets (buffer, RC_LINEBUFFER, fp)) {
p = buffer;
@ -465,7 +437,7 @@ char **rc_filter_env (void)
whitelist = rc_get_list (SYS_WHITELIST);
if (! whitelist)
ewarn ("system environment whitelist (" SYS_WHITELIST ") missing");
fprintf (stderr, "system environment whitelist (" SYS_WHITELIST ") missing\n");
env = rc_get_list (USR_WHITELIST);
rc_strlist_join (&whitelist, env);
@ -557,18 +529,13 @@ static bool file_regex (const char *file, const char *regex)
bool retval = false;
int result;
if (! rc_exists (file))
if (! (fp = fopen (file, "r")))
return (false);
if (! (fp = fopen (file, "r"))) {
ewarn ("file_regex `%s': %s", file, strerror (errno));
return (false);
}
if ((result = regcomp (&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
fclose (fp);
regerror (result, &re, buffer, sizeof (buffer));
eerror ("file_regex: %s", buffer);
fprintf (stderr, "file_regex: %s", buffer);
return (false);
}
@ -652,23 +619,19 @@ char **rc_make_env (void)
rc_strlist_add (&env, line);
free (line);
if (rc_exists (RC_KSOFTLEVEL)) {
if (! (fp = fopen (RC_KSOFTLEVEL, "r")))
eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno));
else {
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);
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);
@ -679,8 +642,7 @@ char **rc_make_env (void)
memset (sys, 0, sizeof (sys));
if (rc_is_dir ("/proc/xen")) {
fp = fopen ("/proc/xen/capabilities", "r");
if (fp) {
if ((fp = fopen ("/proc/xen/capabilities", "r"))) {
fclose (fp);
if (file_regex ("/proc/xen/capabilities", "control_d"))
snprintf (sys, sizeof (sys), "XENU");

View File

@ -104,13 +104,15 @@ char *rc_get_runlevel (void)
}
librc_hidden_def(rc_get_runlevel)
void rc_set_runlevel (const char *runlevel)
bool rc_set_runlevel (const char *runlevel)
{
FILE *fp = fopen (SOFTLEVEL, "w");
if (! fp)
eerrorx ("failed to open `" SOFTLEVEL "': %s", strerror (errno));
return (false);
fprintf (fp, "%s", runlevel);
fclose (fp);
return (true);
}
librc_hidden_def(rc_set_runlevel)
@ -200,17 +202,13 @@ char **rc_service_options (const char *service)
char *p = buffer;
FILE *fp;
if (! rc_service_exists (service))
if (! (svc = rc_resolve_service (service)))
return (NULL);
svc = rc_resolve_service (service);
snprintf (cmd, sizeof (cmd), ". '%s'; echo \"${opts}\"", svc);
if (! (fp = popen (cmd, "r"))) {
eerror ("popen `%s': %s", svc, strerror (errno));
free (svc);
free (svc);
if (! (fp = popen (cmd, "r")))
return (NULL);
}
if (fgets (buffer, RC_LINEBUFFER, fp)) {
if (buffer[strlen (buffer) - 1] == '\n')
@ -232,22 +230,17 @@ char *rc_service_description (const char *service, const char *option)
FILE *fp;
int i;
if (! rc_service_exists (service))
if (! (svc = rc_resolve_service (service)))
return (NULL);
svc = rc_resolve_service (service);
if (! option)
option = "";
snprintf (cmd, sizeof (cmd), ". '%s'; echo \"${description%s%s}\"",
svc, option ? "_" : "", option);
if (! (fp = popen (cmd, "r"))) {
eerror ("popen `%s': %s", svc, strerror (errno));
free (svc);
return (NULL);
}
free (svc);
if (! (fp = popen (cmd, "r")))
return (NULL);
while (fgets (buffer, RC_LINEBUFFER, fp)) {
if (! desc) {
@ -315,7 +308,6 @@ bool rc_mark_service (const char *service, const rc_service_state_t state)
unlink (file);
i = symlink (init, file);
if (i != 0) {
eerror ("symlink `%s' to `%s': %s", init, file, strerror (errno));
free (file);
free (init);
free (svc);
@ -353,18 +345,11 @@ bool rc_mark_service (const char *service, const rc_service_state_t state)
rc_parse_service_state (RC_SERVICE_WASINACTIVE),
base, (char *) NULL);
if (symlink (init, wasfile) != 0)
eerror ("symlink `%s' to `%s': %s", init, wasfile,
strerror (errno));
symlink (init, wasfile);
skip_wasinactive = true;
free (wasfile);
}
errno = 0;
if (unlink (file) != 0 && errno != ENOENT)
eerror ("failed to delete `%s': %s", file,
strerror (errno));
unlink (file);
}
free (file);
}
@ -376,9 +361,7 @@ bool rc_mark_service (const char *service, const rc_service_state_t state)
state == RC_SERVICE_INACTIVE)
{
file = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL);
if (rc_exists (file))
if (unlink (file) != 0)
eerror ("unlink `%s': %s", file, strerror (errno));
unlink (file);
free (file);
}
@ -408,9 +391,7 @@ bool rc_mark_service (const char *service, const rc_service_state_t state)
STRLIST_FOREACH (dirs, dir, i) {
char *bdir = rc_strcatpaths (sdir, dir, (char *) NULL);
file = rc_strcatpaths (bdir, base, (char *) NULL);
if (rc_exists (file))
if (unlink (file) != 0)
eerror ("unlink `%s': %s", file, strerror (errno));
unlink (file);
free (file);
/* Try and remove the dir - we don't care about errors */
@ -468,18 +449,14 @@ char *rc_get_service_option (const char *service, const char *option)
(char *) NULL);
char *value = NULL;
if (rc_exists (file)) {
if ((fp = fopen (file, "r")) == NULL)
eerror ("fopen `%s': %s", file, strerror (errno));
else {
memset (buffer, 0, sizeof (buffer));
if (fgets (buffer, RC_LINEBUFFER, fp))
value = rc_xstrdup (buffer);
fclose (fp);
}
if ((fp = fopen (file, "r"))) {
memset (buffer, 0, sizeof (buffer));
if (fgets (buffer, RC_LINEBUFFER, fp))
value = rc_xstrdup (buffer);
fclose (fp);
}
free (file);
return (value);
}
librc_hidden_def(rc_get_service_option)
@ -494,16 +471,13 @@ bool rc_set_service_option (const char *service, const char *option,
if (! rc_is_dir (path)) {
if (mkdir (path, 0755) != 0) {
eerror ("mkdir `%s': %s", path, strerror (errno));
free (path);
free (file);
return (false);
}
}
if ((fp = fopen (file, "w")) == NULL)
eerror ("fopen `%s': %s", file, strerror (errno));
else {
if ((fp = fopen (file, "w"))) {
if (value)
fprintf (fp, "%s", value);
fclose (fp);
@ -537,7 +511,6 @@ static pid_t _exec_service (const char *service, const char *arg)
free (svc);
if (mkfifo (fifo, 0600) != 0 && errno != EEXIST) {
eerror ("unable to create fifo `%s': %s", fifo, strerror (errno));
free (fifo);
free (file);
return (-1);
@ -545,7 +518,7 @@ static pid_t _exec_service (const char *service, const char *arg)
if ((pid = vfork ()) == 0) {
execl (file, file, arg, (char *) NULL);
eerror ("unable to exec `%s': %s", file, strerror (errno));
fprintf (stderr, "unable to exec `%s': %s\n", file, strerror (errno));
unlink (fifo);
_exit (EXIT_FAILURE);
}
@ -554,7 +527,7 @@ static pid_t _exec_service (const char *service, const char *arg)
free (file);
if (pid == -1)
eerror ("vfork: %s", strerror (errno));
fprintf (stderr, "vfork: %s\n", strerror (errno));
return (pid);
}
@ -593,17 +566,18 @@ pid_t rc_start_service (const char *service)
}
librc_hidden_def(rc_start_service)
void rc_schedule_start_service (const char *service,
bool rc_schedule_start_service (const char *service,
const char *service_to_start)
{
char *dir;
char *init;
char *file;
char *svc;
bool retval;
/* service may be a provided service, like net */
if (! service || ! rc_service_exists (service_to_start))
return;
return (false);
svc = rc_xstrdup (service);
dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (svc),
@ -611,21 +585,20 @@ void rc_schedule_start_service (const char *service,
free (svc);
if (! rc_is_dir (dir))
if (mkdir (dir, 0755) != 0) {
eerror ("mkdir `%s': %s", dir, strerror (errno));
free (dir);
return;
return (false);
}
init = rc_resolve_service (service_to_start);
svc = rc_xstrdup (service_to_start);
file = rc_strcatpaths (dir, basename (svc), (char *) NULL);
free (svc);
if (! rc_exists (file) && symlink (init, file) != 0)
eerror ("symlink `%s' to `%s': %s", init, file, strerror (errno));
retval = (rc_exists (file) || symlink (init, file) == 0);
free (init);
free (file);
free (dir);
return (retval);
}
librc_hidden_def(rc_schedule_start_service)
@ -674,10 +647,8 @@ bool rc_wait_service (const char *service)
}
if (nanosleep (&ts, NULL) == -1) {
if (errno != EINTR) {
eerror ("nanosleep: %s", strerror (errno));
if (errno != EINTR)
break;
}
}
if (! forever)
@ -703,11 +674,7 @@ char **rc_services_in_runlevel (const char *runlevel)
return (NULL);
dir = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
if (! rc_is_dir (dir))
eerror ("runlevel `%s' does not exist", runlevel);
else
list = rc_ls_dir (dir, RC_LS_INITD);
list = rc_ls_dir (dir, RC_LS_INITD);
free (dir);
return (list);
}

View File

@ -42,7 +42,6 @@
#include <kvm.h>
#endif
#include "einfo.h"
#include "librc-depend.h"
#include "rc.h"
#include "rc-misc.h"
@ -53,16 +52,20 @@
#define librc_hidden_def(x) hidden_def(x)
librc_hidden_proto(rc_allow_plug)
librc_hidden_proto(rc_deptree_depends)
librc_hidden_proto(rc_deptree_depinfo)
librc_hidden_proto(rc_deptree_deptype)
librc_hidden_proto(rc_deptree_free)
librc_hidden_proto(rc_deptree_load)
librc_hidden_proto(rc_deptree_order_services)
librc_hidden_proto(rc_deptree_update)
librc_hidden_proto(rc_deptree_update_needed)
librc_hidden_proto(rc_env_bool)
librc_hidden_proto(rc_exists)
librc_hidden_proto(rc_filter_env)
librc_hidden_proto(rc_find_pids)
librc_hidden_proto(rc_free_deptree)
librc_hidden_proto(rc_get_config)
librc_hidden_proto(rc_get_config_entry)
librc_hidden_proto(rc_get_depends)
librc_hidden_proto(rc_get_depinfo)
librc_hidden_proto(rc_get_deptype)
librc_hidden_proto(rc_get_list)
librc_hidden_proto(rc_get_runlevel)
librc_hidden_proto(rc_get_runlevels)
@ -71,11 +74,9 @@ librc_hidden_proto(rc_is_dir)
librc_hidden_proto(rc_is_exec)
librc_hidden_proto(rc_is_file)
librc_hidden_proto(rc_is_link)
librc_hidden_proto(rc_load_deptree)
librc_hidden_proto(rc_ls_dir)
librc_hidden_proto(rc_make_env)
librc_hidden_proto(rc_mark_service)
librc_hidden_proto(rc_order_services)
librc_hidden_proto(rc_resolve_service)
librc_hidden_proto(rc_rm_dir)
librc_hidden_proto(rc_runlevel_exists)
@ -111,7 +112,6 @@ librc_hidden_proto(rc_strlist_delete)
librc_hidden_proto(rc_strlist_free)
librc_hidden_proto(rc_strlist_join)
librc_hidden_proto(rc_strlist_reverse)
librc_hidden_proto(rc_update_deptree)
librc_hidden_proto(rc_wait_service)
librc_hidden_proto(rc_waitpid)
librc_hidden_proto(rc_xmalloc)

View File

@ -19,6 +19,18 @@
#include "rc-misc.h"
#include "strlist.h"
rc_depinfo_t *_rc_deptree_load (void) {
if (rc_deptree_update_needed ()) {
int retval;
ebegin ("Caching service dependencies");
retval = rc_deptree_update ();
eend (retval, "Failed to update the dependency tree");
}
return (rc_deptree_load ());
}
int rc_depend (int argc, char **argv)
{
char **types = NULL;
@ -39,8 +51,9 @@ int rc_depend (int argc, char **argv)
for (i = 1; i < argc; i++) {
if (strcmp (argv[i], "--update") == 0) {
if (! update) {
rc_update_deptree (true);
update = true;
ebegin ("Caching service dependencies");
update = (rc_deptree_update () == 0);
eend (update ? 0 : -1, "Failed to update the dependency tree");
}
continue;
}
@ -59,10 +72,10 @@ int rc_depend (int argc, char **argv)
argv[i]++;
rc_strlist_add (&types, argv[i]);
} else {
if ((deptree = rc_load_deptree ()) == NULL)
if ((deptree = _rc_deptree_load ()) == NULL)
eerrorx ("failed to load deptree");
di = rc_get_depinfo (deptree, argv[i]);
di = rc_deptree_depinfo (deptree, argv[i]);
if (! di)
eerror ("no dependency info for service `%s'", argv[i]);
else
@ -72,7 +85,7 @@ int rc_depend (int argc, char **argv)
if (! services) {
rc_strlist_free (types);
rc_free_deptree (deptree);
rc_deptree_free (deptree);
if (update)
return (EXIT_SUCCESS);
eerrorx ("no services specified");
@ -84,7 +97,7 @@ int rc_depend (int argc, char **argv)
rc_strlist_add (&types, "iuse");
}
depends = rc_get_depends (deptree, types, services, runlevel, options);
depends = rc_deptree_depends (deptree, types, services, runlevel, options);
if (depends) {
STRLIST_FOREACH (depends, service, i) {
@ -103,7 +116,7 @@ int rc_depend (int argc, char **argv)
rc_strlist_free (types);
rc_strlist_free (services);
rc_strlist_free (depends);
rc_free_deptree (deptree);
rc_deptree_free (deptree);
return (EXIT_SUCCESS);
}

View File

@ -104,7 +104,7 @@ static void cleanup (void)
rc_strlist_free (coldplugged_services);
rc_strlist_free (stop_services);
rc_strlist_free (start_services);
rc_free_deptree (deptree);
rc_deptree_free (deptree);
rc_strlist_free (types);
/* Clean runlevel start, stop markers */
@ -1021,7 +1021,7 @@ int main (int argc, char **argv)
}
/* Load our deptree now */
if ((deptree = rc_load_deptree ()) == NULL)
if ((deptree = _rc_deptree_load ()) == NULL)
eerrorx ("failed to load deptree");
/* Clean the failed services state dir now */
@ -1112,7 +1112,7 @@ int main (int argc, char **argv)
rc_strlist_add (&types, "iuse");
rc_strlist_add (&types, "iafter");
deporder = rc_get_depends (deptree, types, stop_services,
deporder = rc_deptree_depends (deptree, types, stop_services,
runlevel, depoptions | RC_DEP_STOP);
rc_strlist_free (stop_services);
@ -1231,7 +1231,7 @@ int main (int argc, char **argv)
/* We got this far! Or last check is to see if any any service that
going to be started depends on us */
rc_strlist_add (&stopdeps, service);
deporder = rc_get_depends (deptree, types, stopdeps,
deporder = rc_deptree_depends (deptree, types, stopdeps,
runlevel, RC_DEP_STRICT);
rc_strlist_free (stopdeps);
stopdeps = NULL;
@ -1300,7 +1300,7 @@ int main (int argc, char **argv)
rc_strlist_add (&types, "ineed");
rc_strlist_add (&types, "iuse");
rc_strlist_add (&types, "iafter");
deporder = rc_get_depends (deptree, types, start_services,
deporder = rc_deptree_depends (deptree, types, start_services,
runlevel, depoptions | RC_DEP_START);
rc_strlist_free (types);
types = NULL;

View File

@ -114,7 +114,7 @@ int rc_waitpid (pid_t pid);
/*! Schedule a service to be started when another service starts
* @param service that starts the scheduled service when started
* @param service_to_start service that will be started */
void rc_schedule_start_service (const char *service,
bool rc_schedule_start_service (const char *service,
const char *service_to_start);
/*! Return a NULL terminated list of services that are scheduled to start
* when the given service has started
@ -171,7 +171,7 @@ char *rc_get_runlevel (void);
/*! Set the runlevel.
* This just changes the stored runlevel and does not start or stop any services.
* @param runlevel to store */
void rc_set_runlevel (const char *runlevel);
bool rc_set_runlevel (const char *runlevel);
/*! Checks if the runlevel exists or not
* @param runlevel to check
@ -254,25 +254,29 @@ typedef void *rc_depinfo_t;
/*! Update the cached dependency tree if it's older than any init script,
* its configuration file or an external configuration file the init script
* has specified.
* @param force an update
* @return 0 if successful, otherwise -1 */
int rc_update_deptree (bool force);
int rc_deptree_update (void);
/*! Check if the cached dependency tree is older than any init script,
* its configuration file or an external configuration file the init script
* has specified.
* @return true if it needs updating, otherwise false */
bool rc_deptree_update_needed (void);
/*! Load the cached dependency tree and return a pointer to it.
* This pointer should be freed with rc_free_deptree when done.
* This pointer should be freed with rc_deptree_free when done.
* @return pointer to the dependency tree */
rc_depinfo_t *rc_load_deptree (void);
rc_depinfo_t *rc_deptree_load (void);
/*! Get a services depedency information from a loaded tree
* @param deptree to search
* @param service to find
* @return service dependency information */
rc_depinfo_t *rc_get_depinfo (rc_depinfo_t *deptree, const char *service);
rc_depinfo_t *rc_deptree_depinfo (rc_depinfo_t *deptree, const char *service);
/*! Get a depenency type from the service dependency information
* @param depinfo service dependency to search
* @param type to find
* @return service dependency type information */
rc_deptype_t *rc_get_deptype (rc_depinfo_t *depinfo, const char *type);
char **rc_get_depends (rc_depinfo_t *deptree, char **types,
char **services, const char *runlevel, int options);
rc_deptype_t *rc_deptree_deptype (rc_depinfo_t *depinfo, const char *type);
char **rc_deptree_depends (rc_depinfo_t *deptree, char **types,
char **services, const char *runlevel, int options);
/*! List all the services that should be stoppned and then started, in order,
* for the given runlevel, including sysinit and boot services where
* approriate.
@ -280,11 +284,11 @@ char **rc_get_depends (rc_depinfo_t *deptree, char **types,
* @param runlevel to change into
* @param options to pass
* @return NULL terminated list of services in order */
char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
int options);
char **rc_deptree_order_services (rc_depinfo_t *deptree, const char *runlevel,
int options);
/*! Free a deptree and its information
* @param deptree to free */
void rc_free_deptree (rc_depinfo_t *deptree);
void rc_deptree_free (rc_depinfo_t *deptree);
/*! @name Plugins
* For each plugin loaded we will call rc_plugin_hook with the below

View File

@ -259,7 +259,7 @@ static void cleanup (void)
}
rc_plugin_unload ();
rc_free_deptree (deptree);
rc_deptree_free (deptree);
rc_strlist_free (services);
rc_strlist_free (types);
rc_strlist_free (svclist);
@ -578,7 +578,7 @@ static void svc_start (bool deps)
depoptions |= RC_DEP_START;
if (deps) {
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
if (! deptree && ((deptree = _rc_deptree_load ()) == NULL))
eerrorx ("failed to load deptree");
rc_strlist_free (types);
@ -588,7 +588,7 @@ static void svc_start (bool deps)
svclist = NULL;
rc_strlist_add (&svclist, applet);
rc_strlist_free (services);
services = rc_get_depends (deptree, types, svclist, softlevel, 0);
services = rc_deptree_depends (deptree, types, svclist, softlevel, 0);
if (services) {
eerrorn ("ERROR: `%s' needs ", applet);
STRLIST_FOREACH (services, svc, i) {
@ -605,12 +605,12 @@ static void svc_start (bool deps)
types = NULL;
rc_strlist_add (&types, "ineed");
rc_strlist_free (need_services);
need_services = rc_get_depends (deptree, types, svclist,
need_services = rc_deptree_depends (deptree, types, svclist,
softlevel, depoptions);
rc_strlist_add (&types, "iuse");
rc_strlist_free (use_services);
use_services = rc_get_depends (deptree, types, svclist,
use_services = rc_deptree_depends (deptree, types, svclist,
softlevel, depoptions);
if (! rc_runlevel_starting ()) {
@ -624,7 +624,7 @@ static void svc_start (bool deps)
/* Now wait for them to start */
rc_strlist_add (&types, "iafter");
services = rc_get_depends (deptree, types, svclist,
services = rc_deptree_depends (deptree, types, svclist,
softlevel, depoptions);
/* We use tmplist to hold our scheduled by list */
@ -686,7 +686,7 @@ static void svc_start (bool deps)
svclist = NULL;
rc_strlist_add (&svclist, svc);
rc_strlist_free (providelist);
providelist = rc_get_depends (deptree, types, svclist,
providelist = rc_deptree_depends (deptree, types, svclist,
softlevel, depoptions);
STRLIST_FOREACH (providelist, svc2, j)
rc_schedule_start_service (svc2, service);
@ -766,7 +766,7 @@ static void svc_start (bool deps)
svclist = NULL;
rc_strlist_add (&svclist, applet);
rc_strlist_free (tmplist);
tmplist = rc_get_depends (deptree, types, svclist, softlevel, depoptions);
tmplist = rc_deptree_depends (deptree, types, svclist, softlevel, depoptions);
STRLIST_FOREACH (tmplist, svc2, j) {
rc_strlist_free (services);
@ -822,7 +822,7 @@ static void svc_stop (bool deps)
if (rc_runlevel_stopping ())
depoptions |= RC_DEP_STOP;
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
if (! deptree && ((deptree = _rc_deptree_load ()) == NULL))
eerrorx ("failed to load deptree");
rc_strlist_free (types);
@ -834,7 +834,7 @@ static void svc_stop (bool deps)
rc_strlist_free (tmplist);
tmplist = NULL;
rc_strlist_free (services);
services = rc_get_depends (deptree, types, svclist,
services = rc_deptree_depends (deptree, types, svclist,
softlevel, depoptions);
rc_strlist_reverse (services);
STRLIST_FOREACH (services, svc, i) {
@ -885,7 +885,7 @@ static void svc_stop (bool deps)
This is important when a runlevel stops */
rc_strlist_add (&types, "usesme");
rc_strlist_add (&types, "ibefore");
services = rc_get_depends (deptree, types, svclist,
services = rc_deptree_depends (deptree, types, svclist,
softlevel, depoptions);
STRLIST_FOREACH (services, svc, i) {
if (rc_service_state (svc) & RC_SERVICE_STOPPED)
@ -1189,7 +1189,7 @@ int runscript (int argc, char **argv)
if (rc_env_bool ("RC_DEPEND_STRICT"))
depoptions |= RC_DEP_STRICT;
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
if (! deptree && ((deptree = _rc_deptree_load ()) == NULL))
eerrorx ("failed to load deptree");
rc_strlist_free (types);
@ -1199,7 +1199,7 @@ int runscript (int argc, char **argv)
svclist = NULL;
rc_strlist_add (&svclist, applet);
rc_strlist_free (services);
services = rc_get_depends (deptree, types, svclist,
services = rc_deptree_depends (deptree, types, svclist,
softlevel, depoptions);
STRLIST_FOREACH (services, svc, i)
printf ("%s%s", i == 1 ? "" : " ", svc);