librc no longer uses libeinfo. deptree function names are now all under rc_deptree_
This commit is contained in:
parent
b153f67fe3
commit
837f43e163
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
|
97
src/librc.c
97
src/librc.c
@ -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);
|
||||
}
|
||||
|
16
src/librc.h
16
src/librc.h
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
10
src/rc.c
10
src/rc.c
@ -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;
|
||||
|
30
src/rc.h
30
src/rc.h
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user