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
|
LIBRCSOVER = 0
|
||||||
LIBRCSO = librc.so.$(LIBRCSOVER)
|
LIBRCSO = librc.so.$(LIBRCSOVER)
|
||||||
LIBRCOBJS = librc.o librc-depend.o librc-daemon.o librc-misc.o librc-strlist.o
|
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 \
|
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-plugin.o rc-status.o rc-update.o runscript.o \
|
||||||
start-stop-daemon.o rc.o
|
start-stop-daemon.o rc.o
|
||||||
LDLIBS_RC = $(LDLIBS_LIBRC) -lrc -lutil
|
LDLIBS_RC = $(LDLIBS_LIBRC) -leinfo -lrc -lutil
|
||||||
|
|
||||||
LIB_TARGETS = $(LIBEINFOSO) $(LIBRCSO)
|
LIB_TARGETS = $(LIBEINFOSO) $(LIBRCSO)
|
||||||
SBIN_TARGETS = rc
|
SBIN_TARGETS = rc
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
* Released under the GPLv2
|
* Released under the GPLv2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "rc.h"
|
||||||
|
|
||||||
int checkown (int argc, char **argv);
|
int checkown (int argc, char **argv);
|
||||||
int env_update (int argc, char **argv);
|
int env_update (int argc, char **argv);
|
||||||
int fstabinfo (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 runscript (int argc, char **argv);
|
||||||
int start_stop_daemon (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;
|
DIR *procdir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
int npids = 0;
|
int npids = 0;
|
||||||
int foundany = false;
|
|
||||||
pid_t p;
|
pid_t p;
|
||||||
pid_t *pids = NULL;
|
pid_t *pids = NULL;
|
||||||
|
pid_t *tmp = NULL;
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
pid_t runscript_pid = 0;
|
pid_t runscript_pid = 0;
|
||||||
char *pp;
|
char *pp;
|
||||||
|
|
||||||
if ((procdir = opendir ("/proc")) == NULL)
|
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
|
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) {
|
while ((entry = readdir (procdir)) != NULL) {
|
||||||
if (sscanf (entry->d_name, "%d", &p) != 1)
|
if (sscanf (entry->d_name, "%d", &p) != 1)
|
||||||
continue;
|
continue;
|
||||||
foundany = true;
|
|
||||||
|
|
||||||
if (runscript_pid != 0 && runscript_pid == p)
|
if (runscript_pid != 0 && runscript_pid == p)
|
||||||
continue;
|
continue;
|
||||||
@ -129,9 +128,14 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
|
|||||||
if (exec && ! cmd && ! pid_is_exec (p, exec))
|
if (exec && ! cmd && ! pid_is_exec (p, exec))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pids = realloc (pids, sizeof (pid_t) * (npids + 2));
|
tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
|
||||||
if (! pids)
|
if (! tmp) {
|
||||||
eerrorx ("memory exhausted");
|
free (pids);
|
||||||
|
closedir (procdir);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
pids = tmp;
|
||||||
|
|
||||||
pids[npids] = p;
|
pids[npids] = p;
|
||||||
pids[npids + 1] = 0;
|
pids[npids + 1] = 0;
|
||||||
@ -139,9 +143,6 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
|
|||||||
}
|
}
|
||||||
closedir (procdir);
|
closedir (procdir);
|
||||||
|
|
||||||
if (! foundany)
|
|
||||||
eerrorx ("nothing in /proc");
|
|
||||||
|
|
||||||
return (pids);
|
return (pids);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_find_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;
|
int argc = 0;
|
||||||
char **argv;
|
char **argv;
|
||||||
pid_t *pids = NULL;
|
pid_t *pids = NULL;
|
||||||
|
pid_t *tmp;
|
||||||
int npids = 0;
|
int npids = 0;
|
||||||
|
|
||||||
if ((kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pids = realloc (pids, sizeof (pid_t) * (npids + 2));
|
tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
|
||||||
if (! pids)
|
if (! tmp) {
|
||||||
eerrorx ("memory exhausted");
|
free (pids);
|
||||||
|
kvm_close (kd);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
pids = tmp;
|
||||||
|
|
||||||
pids[npids] = p;
|
pids[npids] = p;
|
||||||
pids[npids + 1] = 0;
|
pids[npids + 1] = 0;
|
||||||
npids++;
|
npids++;
|
||||||
}
|
}
|
||||||
kvm_close(kd);
|
kvm_close (kd);
|
||||||
|
|
||||||
return (pids);
|
return (pids);
|
||||||
}
|
}
|
||||||
@ -238,13 +245,7 @@ static bool _match_daemon (const char *path, const char *file,
|
|||||||
int lc = 0;
|
int lc = 0;
|
||||||
int m = 0;
|
int m = 0;
|
||||||
|
|
||||||
if (! rc_exists (ffile)) {
|
|
||||||
free (ffile);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((fp = fopen (ffile, "r")) == NULL) {
|
if ((fp = fopen (ffile, "r")) == NULL) {
|
||||||
eerror ("fopen `%s': %s", ffile, strerror (errno));
|
|
||||||
free (ffile);
|
free (ffile);
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@ -350,19 +351,14 @@ void rc_set_service_daemon (const char *service, const char *exec,
|
|||||||
char buffer[10];
|
char buffer[10];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if (! rc_is_dir (dirpath))
|
if (mkdir (dirpath, 0755) == 0 || errno == EEXIST) {
|
||||||
if (mkdir (dirpath, 0755) != 0)
|
snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1);
|
||||||
eerror ("mkdir `%s': %s", dirpath, strerror (errno));
|
file = rc_strcatpaths (dirpath, buffer, (char *) NULL);
|
||||||
|
if ((fp = fopen (file, "w")))
|
||||||
snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1);
|
fprintf (fp, "%s\n%s\n%s\n", mexec, mname, mpidfile);
|
||||||
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);
|
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
free (file);
|
||||||
}
|
}
|
||||||
free (file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free (mexec);
|
free (mexec);
|
||||||
@ -458,10 +454,8 @@ bool rc_service_daemons_crashed (const char *service)
|
|||||||
path = rc_strcatpaths (dirpath, file, (char *) NULL);
|
path = rc_strcatpaths (dirpath, file, (char *) NULL);
|
||||||
fp = fopen (path, "r");
|
fp = fopen (path, "r");
|
||||||
free (path);
|
free (path);
|
||||||
if (! fp) {
|
if (! fp)
|
||||||
eerror ("fopen `%s': %s", file, strerror (errno));
|
break;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((fgets (buffer, RC_LINEBUFFER, fp))) {
|
while ((fgets (buffer, RC_LINEBUFFER, fp))) {
|
||||||
int lb = strlen (buffer) - 1;
|
int lb = strlen (buffer) - 1;
|
||||||
@ -499,13 +493,11 @@ bool rc_service_daemons_crashed (const char *service)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((fp = fopen (pidfile, "r")) == NULL) {
|
if ((fp = fopen (pidfile, "r")) == NULL) {
|
||||||
eerror ("fopen `%s': %s", pidfile, strerror (errno));
|
|
||||||
retval = true;
|
retval = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fscanf (fp, "%d", &pid) != 1) {
|
if (fscanf (fp, "%d", &pid) != 1) {
|
||||||
eerror ("no pid found in `%s'", pidfile);
|
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
retval = true;
|
retval = true;
|
||||||
break;
|
break;
|
||||||
|
@ -41,7 +41,7 @@ static char *get_shell_value (char *string)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rc_free_deptree (rc_depinfo_t *deptree)
|
void rc_deptree_free (rc_depinfo_t *deptree)
|
||||||
{
|
{
|
||||||
rc_depinfo_t *di = deptree;
|
rc_depinfo_t *di = deptree;
|
||||||
while (di)
|
while (di)
|
||||||
@ -61,9 +61,9 @@ void rc_free_deptree (rc_depinfo_t *deptree)
|
|||||||
di = dip;
|
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;
|
FILE *fp;
|
||||||
rc_depinfo_t *deptree = NULL;
|
rc_depinfo_t *deptree = NULL;
|
||||||
@ -75,9 +75,6 @@ rc_depinfo_t *rc_load_deptree (void)
|
|||||||
char *e;
|
char *e;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Update our deptree, but only if we need too */
|
|
||||||
rc_update_deptree (false);
|
|
||||||
|
|
||||||
if (! (fp = fopen (RC_DEPTREE, "r")))
|
if (! (fp = fopen (RC_DEPTREE, "r")))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
@ -150,9 +147,9 @@ rc_depinfo_t *rc_load_deptree (void)
|
|||||||
|
|
||||||
return (deptree);
|
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;
|
rc_depinfo_t *di;
|
||||||
|
|
||||||
@ -165,9 +162,9 @@ rc_depinfo_t *rc_get_depinfo (rc_depinfo_t *deptree, const char *service)
|
|||||||
|
|
||||||
return (NULL);
|
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;
|
rc_deptype_t *dt;
|
||||||
|
|
||||||
@ -180,7 +177,7 @@ rc_deptype_t *rc_get_deptype (rc_depinfo_t *depinfo, const char *type)
|
|||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_get_deptype)
|
librc_hidden_def(rc_deptree_deptype)
|
||||||
|
|
||||||
static bool valid_service (const char *runlevel, const char *service)
|
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))
|
if (rc_service_exists (depinfo->service))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
dt = rc_get_deptype (depinfo, "providedby");
|
dt = rc_deptree_deptype (depinfo, "providedby");
|
||||||
if (! dt)
|
if (! dt)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
@ -382,7 +379,7 @@ static void visit_service (rc_depinfo_t *deptree, char **types,
|
|||||||
|
|
||||||
STRLIST_FOREACH (types, item, i)
|
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)
|
STRLIST_FOREACH (dt->services, service, j)
|
||||||
{
|
{
|
||||||
@ -392,12 +389,12 @@ static void visit_service (rc_depinfo_t *deptree, char **types,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
di = rc_get_depinfo (deptree, service);
|
di = rc_deptree_depinfo (deptree, service);
|
||||||
if ((provides = get_provided (deptree, di, runlevel, options)))
|
if ((provides = get_provided (deptree, di, runlevel, options)))
|
||||||
{
|
{
|
||||||
STRLIST_FOREACH (provides, lp, k)
|
STRLIST_FOREACH (provides, lp, k)
|
||||||
{
|
{
|
||||||
di = rc_get_depinfo (deptree, lp);
|
di = rc_deptree_depinfo (deptree, lp);
|
||||||
if (di && (strcmp (item, "ineed") == 0 ||
|
if (di && (strcmp (item, "ineed") == 0 ||
|
||||||
strcmp (item, "needsme") == 0 ||
|
strcmp (item, "needsme") == 0 ||
|
||||||
valid_service (runlevel, di->service)))
|
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 */
|
/* 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)
|
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)))
|
if ((provides = get_provided (deptree, di, runlevel, options)))
|
||||||
{
|
{
|
||||||
STRLIST_FOREACH (provides, lp, j)
|
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 */
|
are also the service calling us or we are provided by something */
|
||||||
svcname = getenv("SVCNAME");
|
svcname = getenv("SVCNAME");
|
||||||
if (! svcname || strcmp (svcname, depinfo->service) != 0)
|
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);
|
rc_strlist_add (&sorted->list, depinfo->service);
|
||||||
}
|
}
|
||||||
|
|
||||||
char **rc_get_depends (rc_depinfo_t *deptree,
|
char **rc_deptree_depends (rc_depinfo_t *deptree,
|
||||||
char **types, char **services,
|
char **types, char **services,
|
||||||
const char *runlevel, int options)
|
const char *runlevel, int options)
|
||||||
{
|
{
|
||||||
struct lhead sorted;
|
struct lhead sorted;
|
||||||
struct lhead visited;
|
struct lhead visited;
|
||||||
@ -466,17 +464,17 @@ char **rc_get_depends (rc_depinfo_t *deptree,
|
|||||||
|
|
||||||
STRLIST_FOREACH (services, service, i)
|
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);
|
visit_service (deptree, types, &sorted, &visited, di, runlevel, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_strlist_free (visited.list);
|
rc_strlist_free (visited.list);
|
||||||
return (sorted.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,
|
char **rc_deptree_order_services (rc_depinfo_t *deptree, const char *runlevel,
|
||||||
int options)
|
int options)
|
||||||
{
|
{
|
||||||
char **list = NULL;
|
char **list = NULL;
|
||||||
char **types = 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, "ineed");
|
||||||
rc_strlist_add (&types, "iuse");
|
rc_strlist_add (&types, "iuse");
|
||||||
rc_strlist_add (&types, "iafter");
|
rc_strlist_add (&types, "iafter");
|
||||||
services = rc_get_depends (deptree, types, list, runlevel,
|
services = rc_deptree_depends (deptree, types, list, runlevel,
|
||||||
RC_DEP_STRICT | RC_DEP_TRACE | options);
|
RC_DEP_STRICT | RC_DEP_TRACE | options);
|
||||||
rc_strlist_free (list);
|
rc_strlist_free (list);
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
|
|
||||||
@ -540,7 +538,7 @@ char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
|
|||||||
|
|
||||||
return (services);
|
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)
|
static bool is_newer_than (const char *file, const char *target)
|
||||||
{
|
{
|
||||||
@ -611,6 +609,39 @@ static const char *depdirs[] =
|
|||||||
NULL
|
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
|
/* This is a 5 phase operation
|
||||||
Phase 1 is a shell script which loads each init script and config in turn
|
Phase 1 is a shell script which loads each init script and config in turn
|
||||||
and echos their dependency info to stdout
|
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 4 scans that depinfo object and puts in backlinks
|
||||||
Phase 5 saves the depinfo object to disk
|
Phase 5 saves the depinfo object to disk
|
||||||
*/
|
*/
|
||||||
int rc_update_deptree (bool force)
|
int rc_deptree_update (void)
|
||||||
{
|
{
|
||||||
char *depends;
|
char *depends;
|
||||||
char *service;
|
char *service;
|
||||||
@ -642,41 +673,6 @@ int rc_update_deptree (bool force)
|
|||||||
int k;
|
int k;
|
||||||
bool already_added;
|
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
|
/* Some init scripts need RC_LIBDIR to source stuff
|
||||||
Ideally we should be setting our full env instead */
|
Ideally we should be setting our full env instead */
|
||||||
if (! getenv ("RC_LIBDIR"))
|
if (! getenv ("RC_LIBDIR"))
|
||||||
@ -684,7 +680,7 @@ int rc_update_deptree (bool force)
|
|||||||
|
|
||||||
/* Phase 1 */
|
/* Phase 1 */
|
||||||
if (! (fp = popen (GENDEP, "r")))
|
if (! (fp = popen (GENDEP, "r")))
|
||||||
eerrorx ("popen: %s", strerror (errno));
|
return (-1);
|
||||||
|
|
||||||
deptree = rc_xmalloc (sizeof (rc_depinfo_t));
|
deptree = rc_xmalloc (sizeof (rc_depinfo_t));
|
||||||
memset (deptree, 0, 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 */
|
/* Phase 3 - add our providors to the tree */
|
||||||
for (depinfo = deptree; depinfo; depinfo = depinfo->next)
|
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)
|
STRLIST_FOREACH (deptype->services, service, i)
|
||||||
{
|
{
|
||||||
for (di = deptree; di; di = di->next)
|
for (di = deptree; di; di = di->next)
|
||||||
@ -807,19 +803,20 @@ int rc_update_deptree (bool force)
|
|||||||
{
|
{
|
||||||
for (i = 0; deppairs[i].depend; i++)
|
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)
|
if (! deptype)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
STRLIST_FOREACH (deptype->services, service, j)
|
STRLIST_FOREACH (deptype->services, service, j)
|
||||||
{
|
{
|
||||||
di = rc_get_depinfo (deptree, service);
|
di = rc_deptree_depinfo (deptree, service);
|
||||||
if (! di)
|
if (! di)
|
||||||
{
|
{
|
||||||
if (strcmp (deptype->type, "ineed") == 0)
|
if (strcmp (deptype->type, "ineed") == 0)
|
||||||
{
|
{
|
||||||
eerror ("Service `%s' needs non existant service `%s'",
|
fprintf (stderr,
|
||||||
depinfo->service, service);
|
"Service `%s' needs non existant service `%s'",
|
||||||
|
depinfo->service, service);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -869,10 +866,7 @@ int rc_update_deptree (bool force)
|
|||||||
This works and should be entirely shell parseable provided that depend
|
This works and should be entirely shell parseable provided that depend
|
||||||
names don't have any non shell variable characters in
|
names don't have any non shell variable characters in
|
||||||
*/
|
*/
|
||||||
if (! (fp = fopen (RC_DEPTREE, "w")))
|
if ((fp = fopen (RC_DEPTREE, "w"))) {
|
||||||
eerror ("fopen `%s': %s", RC_DEPTREE, strerror (errno));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (depinfo = deptree; depinfo; depinfo = depinfo->next)
|
for (depinfo = deptree; depinfo; depinfo = depinfo->next)
|
||||||
{
|
{
|
||||||
@ -890,24 +884,22 @@ int rc_update_deptree (bool force)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
}
|
} else
|
||||||
|
fprintf (stderr, "fopen `%s': %s", RC_DEPTREE, strerror (errno));
|
||||||
|
|
||||||
/* Save our external config files to disk */
|
/* Save our external config files to disk */
|
||||||
if (config) {
|
if (config) {
|
||||||
if (! (fp = fopen (RC_DEPCONFIG, "w")))
|
if ((fp = fopen (RC_DEPCONFIG, "w"))) {
|
||||||
eerror ("fopen `%s': %s", RC_DEPCONFIG, strerror (errno));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
STRLIST_FOREACH (config, service, i)
|
STRLIST_FOREACH (config, service, i)
|
||||||
fprintf (fp, "%s\n", service);
|
fprintf (fp, "%s\n", service);
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
}
|
} else
|
||||||
|
fprintf (stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror (errno));
|
||||||
rc_strlist_free (config);
|
rc_strlist_free (config);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_free_deptree (deptree);
|
rc_deptree_free (deptree);
|
||||||
|
|
||||||
eend (retval, "Failed to update the service dependency tree");
|
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_update_deptree)
|
librc_hidden_def(rc_deptree_update)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "librc.h"
|
#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 PROFILE_ENV "/etc/profile.env"
|
||||||
#define SYS_WHITELIST RC_LIBDIR "/conf.d/env_whitelist"
|
#define SYS_WHITELIST RC_LIBDIR "/conf.d/env_whitelist"
|
||||||
@ -26,7 +26,7 @@ void *rc_xmalloc (size_t size)
|
|||||||
if (value)
|
if (value)
|
||||||
return (value);
|
return (value);
|
||||||
|
|
||||||
ERRX
|
ERRX;
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_xmalloc)
|
librc_hidden_def(rc_xmalloc)
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ void *rc_xrealloc (void *ptr, size_t size)
|
|||||||
if (value)
|
if (value)
|
||||||
return (value);
|
return (value);
|
||||||
|
|
||||||
ERRX
|
ERRX;
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_xrealloc)
|
librc_hidden_def(rc_xrealloc)
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ char *rc_xstrdup (const char *str)
|
|||||||
if (value)
|
if (value)
|
||||||
return (value);
|
return (value);
|
||||||
|
|
||||||
ERRX
|
ERRX;
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_xstrdup)
|
librc_hidden_def(rc_xstrdup)
|
||||||
|
|
||||||
@ -217,14 +217,9 @@ char **rc_ls_dir (const char *dir, int options)
|
|||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
char **list = NULL;
|
char **list = NULL;
|
||||||
|
|
||||||
if (! dir)
|
if ((dp = opendir (dir)) == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
if ((dp = opendir (dir)) == NULL) {
|
|
||||||
eerror ("failed to opendir `%s': %s", dir, strerror (errno));
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while (((d = readdir (dp)) != NULL) && errno == 0) {
|
while (((d = readdir (dp)) != NULL) && errno == 0) {
|
||||||
if (d->d_name[0] != '.') {
|
if (d->d_name[0] != '.') {
|
||||||
@ -248,12 +243,6 @@ char **rc_ls_dir (const char *dir, int options)
|
|||||||
}
|
}
|
||||||
closedir (dp);
|
closedir (dp);
|
||||||
|
|
||||||
if (errno != 0) {
|
|
||||||
eerror ("failed to readdir `%s': %s", dir, strerror (errno));
|
|
||||||
rc_strlist_free (list);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (list);
|
return (list);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_ls_dir)
|
librc_hidden_def(rc_ls_dir)
|
||||||
@ -263,14 +252,9 @@ bool rc_rm_dir (const char *pathname, bool top)
|
|||||||
DIR *dp;
|
DIR *dp;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
|
|
||||||
if (! pathname)
|
if ((dp = opendir (pathname)) == NULL)
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
if ((dp = opendir (pathname)) == NULL) {
|
|
||||||
eerror ("failed to opendir `%s': %s", pathname, strerror (errno));
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while (((d = readdir (dp)) != NULL) && errno == 0) {
|
while (((d = readdir (dp)) != NULL) && errno == 0) {
|
||||||
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 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 {
|
} else {
|
||||||
if (unlink (tmp)) {
|
if (unlink (tmp)) {
|
||||||
eerror ("failed to unlink `%s': %s", tmp, strerror (errno));
|
|
||||||
free (tmp);
|
free (tmp);
|
||||||
closedir (dp);
|
closedir (dp);
|
||||||
return (false);
|
return (false);
|
||||||
@ -293,14 +276,10 @@ bool rc_rm_dir (const char *pathname, bool top)
|
|||||||
free (tmp);
|
free (tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errno != 0)
|
|
||||||
eerror ("failed to readdir `%s': %s", pathname, strerror (errno));
|
|
||||||
closedir (dp);
|
closedir (dp);
|
||||||
|
|
||||||
if (top && rmdir (pathname) != 0) {
|
if (top && rmdir (pathname) != 0)
|
||||||
eerror ("failed to rmdir `%s': %s", pathname, strerror (errno));
|
return (false);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@ -321,14 +300,9 @@ char **rc_get_config (const char *file)
|
|||||||
char *entry;
|
char *entry;
|
||||||
char *newline;
|
char *newline;
|
||||||
|
|
||||||
if (! file)
|
if (! (fp = fopen (file, "r")))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (! (fp = fopen (file, "r"))) {
|
|
||||||
ewarn ("rc_get_config `%s': %s", file, strerror (errno));
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fgets (buffer, RC_LINEBUFFER, fp)) {
|
while (fgets (buffer, RC_LINEBUFFER, fp)) {
|
||||||
p = buffer;
|
p = buffer;
|
||||||
|
|
||||||
@ -419,10 +393,8 @@ char **rc_get_list (const char *file)
|
|||||||
char *token;
|
char *token;
|
||||||
char **list = NULL;
|
char **list = NULL;
|
||||||
|
|
||||||
if (! (fp = fopen (file, "r"))) {
|
if (! (fp = fopen (file, "r")))
|
||||||
ewarn ("rc_get_list `%s': %s", file, strerror (errno));
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
|
||||||
|
|
||||||
while (fgets (buffer, RC_LINEBUFFER, fp)) {
|
while (fgets (buffer, RC_LINEBUFFER, fp)) {
|
||||||
p = buffer;
|
p = buffer;
|
||||||
@ -465,7 +437,7 @@ char **rc_filter_env (void)
|
|||||||
|
|
||||||
whitelist = rc_get_list (SYS_WHITELIST);
|
whitelist = rc_get_list (SYS_WHITELIST);
|
||||||
if (! 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);
|
env = rc_get_list (USR_WHITELIST);
|
||||||
rc_strlist_join (&whitelist, env);
|
rc_strlist_join (&whitelist, env);
|
||||||
@ -557,18 +529,13 @@ static bool file_regex (const char *file, const char *regex)
|
|||||||
bool retval = false;
|
bool retval = false;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (! rc_exists (file))
|
if (! (fp = fopen (file, "r")))
|
||||||
return (false);
|
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) {
|
if ((result = regcomp (&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
regerror (result, &re, buffer, sizeof (buffer));
|
regerror (result, &re, buffer, sizeof (buffer));
|
||||||
eerror ("file_regex: %s", buffer);
|
fprintf (stderr, "file_regex: %s", buffer);
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,23 +619,19 @@ char **rc_make_env (void)
|
|||||||
rc_strlist_add (&env, line);
|
rc_strlist_add (&env, line);
|
||||||
free (line);
|
free (line);
|
||||||
|
|
||||||
if (rc_exists (RC_KSOFTLEVEL)) {
|
if ((fp = fopen (RC_KSOFTLEVEL, "r"))) {
|
||||||
if (! (fp = fopen (RC_KSOFTLEVEL, "r")))
|
memset (buffer, 0, sizeof (buffer));
|
||||||
eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno));
|
if (fgets (buffer, sizeof (buffer), fp)) {
|
||||||
else {
|
i = strlen (buffer) - 1;
|
||||||
memset (buffer, 0, sizeof (buffer));
|
if (buffer[i] == '\n')
|
||||||
if (fgets (buffer, sizeof (buffer), fp)) {
|
buffer[i] = 0;
|
||||||
i = strlen (buffer) - 1;
|
i += strlen ("RC_DEFAULTLEVEL=") + 2;
|
||||||
if (buffer[i] == '\n')
|
line = rc_xmalloc (sizeof (char *) * i);
|
||||||
buffer[i] = 0;
|
snprintf (line, i, "RC_DEFAULTLEVEL=%s", buffer);
|
||||||
i += strlen ("RC_DEFAULTLEVEL=") + 2;
|
rc_strlist_add (&env, line);
|
||||||
line = rc_xmalloc (sizeof (char *) * i);
|
free (line);
|
||||||
snprintf (line, i, "RC_DEFAULTLEVEL=%s", buffer);
|
|
||||||
rc_strlist_add (&env, line);
|
|
||||||
free (line);
|
|
||||||
}
|
|
||||||
fclose (fp);
|
|
||||||
}
|
}
|
||||||
|
fclose (fp);
|
||||||
} else
|
} else
|
||||||
rc_strlist_add (&env, "RC_DEFAULTLEVEL=" RC_LEVEL_DEFAULT);
|
rc_strlist_add (&env, "RC_DEFAULTLEVEL=" RC_LEVEL_DEFAULT);
|
||||||
|
|
||||||
@ -679,8 +642,7 @@ char **rc_make_env (void)
|
|||||||
memset (sys, 0, sizeof (sys));
|
memset (sys, 0, sizeof (sys));
|
||||||
|
|
||||||
if (rc_is_dir ("/proc/xen")) {
|
if (rc_is_dir ("/proc/xen")) {
|
||||||
fp = fopen ("/proc/xen/capabilities", "r");
|
if ((fp = fopen ("/proc/xen/capabilities", "r"))) {
|
||||||
if (fp) {
|
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
if (file_regex ("/proc/xen/capabilities", "control_d"))
|
if (file_regex ("/proc/xen/capabilities", "control_d"))
|
||||||
snprintf (sys, sizeof (sys), "XENU");
|
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)
|
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");
|
FILE *fp = fopen (SOFTLEVEL, "w");
|
||||||
|
|
||||||
if (! fp)
|
if (! fp)
|
||||||
eerrorx ("failed to open `" SOFTLEVEL "': %s", strerror (errno));
|
return (false);
|
||||||
fprintf (fp, "%s", runlevel);
|
fprintf (fp, "%s", runlevel);
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
return (true);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_set_runlevel)
|
librc_hidden_def(rc_set_runlevel)
|
||||||
|
|
||||||
@ -200,17 +202,13 @@ char **rc_service_options (const char *service)
|
|||||||
char *p = buffer;
|
char *p = buffer;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if (! rc_service_exists (service))
|
if (! (svc = rc_resolve_service (service)))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
svc = rc_resolve_service (service);
|
|
||||||
|
|
||||||
snprintf (cmd, sizeof (cmd), ". '%s'; echo \"${opts}\"", svc);
|
snprintf (cmd, sizeof (cmd), ". '%s'; echo \"${opts}\"", svc);
|
||||||
if (! (fp = popen (cmd, "r"))) {
|
free (svc);
|
||||||
eerror ("popen `%s': %s", svc, strerror (errno));
|
if (! (fp = popen (cmd, "r")))
|
||||||
free (svc);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
|
||||||
|
|
||||||
if (fgets (buffer, RC_LINEBUFFER, fp)) {
|
if (fgets (buffer, RC_LINEBUFFER, fp)) {
|
||||||
if (buffer[strlen (buffer) - 1] == '\n')
|
if (buffer[strlen (buffer) - 1] == '\n')
|
||||||
@ -232,22 +230,17 @@ char *rc_service_description (const char *service, const char *option)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (! rc_service_exists (service))
|
if (! (svc = rc_resolve_service (service)))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
svc = rc_resolve_service (service);
|
|
||||||
|
|
||||||
if (! option)
|
if (! option)
|
||||||
option = "";
|
option = "";
|
||||||
|
|
||||||
snprintf (cmd, sizeof (cmd), ". '%s'; echo \"${description%s%s}\"",
|
snprintf (cmd, sizeof (cmd), ". '%s'; echo \"${description%s%s}\"",
|
||||||
svc, option ? "_" : "", option);
|
svc, option ? "_" : "", option);
|
||||||
if (! (fp = popen (cmd, "r"))) {
|
|
||||||
eerror ("popen `%s': %s", svc, strerror (errno));
|
|
||||||
free (svc);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
free (svc);
|
free (svc);
|
||||||
|
if (! (fp = popen (cmd, "r")))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
while (fgets (buffer, RC_LINEBUFFER, fp)) {
|
while (fgets (buffer, RC_LINEBUFFER, fp)) {
|
||||||
if (! desc) {
|
if (! desc) {
|
||||||
@ -315,7 +308,6 @@ bool rc_mark_service (const char *service, const rc_service_state_t state)
|
|||||||
unlink (file);
|
unlink (file);
|
||||||
i = symlink (init, file);
|
i = symlink (init, file);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
eerror ("symlink `%s' to `%s': %s", init, file, strerror (errno));
|
|
||||||
free (file);
|
free (file);
|
||||||
free (init);
|
free (init);
|
||||||
free (svc);
|
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),
|
rc_parse_service_state (RC_SERVICE_WASINACTIVE),
|
||||||
base, (char *) NULL);
|
base, (char *) NULL);
|
||||||
|
|
||||||
if (symlink (init, wasfile) != 0)
|
symlink (init, wasfile);
|
||||||
eerror ("symlink `%s' to `%s': %s", init, wasfile,
|
|
||||||
strerror (errno));
|
|
||||||
|
|
||||||
skip_wasinactive = true;
|
skip_wasinactive = true;
|
||||||
free (wasfile);
|
free (wasfile);
|
||||||
}
|
}
|
||||||
|
unlink (file);
|
||||||
errno = 0;
|
|
||||||
if (unlink (file) != 0 && errno != ENOENT)
|
|
||||||
eerror ("failed to delete `%s': %s", file,
|
|
||||||
strerror (errno));
|
|
||||||
}
|
}
|
||||||
free (file);
|
free (file);
|
||||||
}
|
}
|
||||||
@ -376,9 +361,7 @@ bool rc_mark_service (const char *service, const rc_service_state_t state)
|
|||||||
state == RC_SERVICE_INACTIVE)
|
state == RC_SERVICE_INACTIVE)
|
||||||
{
|
{
|
||||||
file = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL);
|
file = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL);
|
||||||
if (rc_exists (file))
|
unlink (file);
|
||||||
if (unlink (file) != 0)
|
|
||||||
eerror ("unlink `%s': %s", file, strerror (errno));
|
|
||||||
free (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) {
|
STRLIST_FOREACH (dirs, dir, i) {
|
||||||
char *bdir = rc_strcatpaths (sdir, dir, (char *) NULL);
|
char *bdir = rc_strcatpaths (sdir, dir, (char *) NULL);
|
||||||
file = rc_strcatpaths (bdir, base, (char *) NULL);
|
file = rc_strcatpaths (bdir, base, (char *) NULL);
|
||||||
if (rc_exists (file))
|
unlink (file);
|
||||||
if (unlink (file) != 0)
|
|
||||||
eerror ("unlink `%s': %s", file, strerror (errno));
|
|
||||||
free (file);
|
free (file);
|
||||||
|
|
||||||
/* Try and remove the dir - we don't care about errors */
|
/* 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 *) NULL);
|
||||||
char *value = NULL;
|
char *value = NULL;
|
||||||
|
|
||||||
if (rc_exists (file)) {
|
if ((fp = fopen (file, "r"))) {
|
||||||
if ((fp = fopen (file, "r")) == NULL)
|
memset (buffer, 0, sizeof (buffer));
|
||||||
eerror ("fopen `%s': %s", file, strerror (errno));
|
if (fgets (buffer, RC_LINEBUFFER, fp))
|
||||||
else {
|
value = rc_xstrdup (buffer);
|
||||||
memset (buffer, 0, sizeof (buffer));
|
fclose (fp);
|
||||||
if (fgets (buffer, RC_LINEBUFFER, fp))
|
|
||||||
value = rc_xstrdup (buffer);
|
|
||||||
fclose (fp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free (file);
|
free (file);
|
||||||
|
|
||||||
return (value);
|
return (value);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_get_service_option)
|
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 (! rc_is_dir (path)) {
|
||||||
if (mkdir (path, 0755) != 0) {
|
if (mkdir (path, 0755) != 0) {
|
||||||
eerror ("mkdir `%s': %s", path, strerror (errno));
|
|
||||||
free (path);
|
free (path);
|
||||||
free (file);
|
free (file);
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fp = fopen (file, "w")) == NULL)
|
if ((fp = fopen (file, "w"))) {
|
||||||
eerror ("fopen `%s': %s", file, strerror (errno));
|
|
||||||
else {
|
|
||||||
if (value)
|
if (value)
|
||||||
fprintf (fp, "%s", value);
|
fprintf (fp, "%s", value);
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
@ -537,7 +511,6 @@ static pid_t _exec_service (const char *service, const char *arg)
|
|||||||
free (svc);
|
free (svc);
|
||||||
|
|
||||||
if (mkfifo (fifo, 0600) != 0 && errno != EEXIST) {
|
if (mkfifo (fifo, 0600) != 0 && errno != EEXIST) {
|
||||||
eerror ("unable to create fifo `%s': %s", fifo, strerror (errno));
|
|
||||||
free (fifo);
|
free (fifo);
|
||||||
free (file);
|
free (file);
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -545,7 +518,7 @@ static pid_t _exec_service (const char *service, const char *arg)
|
|||||||
|
|
||||||
if ((pid = vfork ()) == 0) {
|
if ((pid = vfork ()) == 0) {
|
||||||
execl (file, file, arg, (char *) NULL);
|
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);
|
unlink (fifo);
|
||||||
_exit (EXIT_FAILURE);
|
_exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@ -554,7 +527,7 @@ static pid_t _exec_service (const char *service, const char *arg)
|
|||||||
free (file);
|
free (file);
|
||||||
|
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
eerror ("vfork: %s", strerror (errno));
|
fprintf (stderr, "vfork: %s\n", strerror (errno));
|
||||||
|
|
||||||
return (pid);
|
return (pid);
|
||||||
}
|
}
|
||||||
@ -593,17 +566,18 @@ pid_t rc_start_service (const char *service)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_start_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)
|
const char *service_to_start)
|
||||||
{
|
{
|
||||||
char *dir;
|
char *dir;
|
||||||
char *init;
|
char *init;
|
||||||
char *file;
|
char *file;
|
||||||
char *svc;
|
char *svc;
|
||||||
|
bool retval;
|
||||||
|
|
||||||
/* service may be a provided service, like net */
|
/* service may be a provided service, like net */
|
||||||
if (! service || ! rc_service_exists (service_to_start))
|
if (! service || ! rc_service_exists (service_to_start))
|
||||||
return;
|
return (false);
|
||||||
|
|
||||||
svc = rc_xstrdup (service);
|
svc = rc_xstrdup (service);
|
||||||
dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (svc),
|
dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (svc),
|
||||||
@ -611,21 +585,20 @@ void rc_schedule_start_service (const char *service,
|
|||||||
free (svc);
|
free (svc);
|
||||||
if (! rc_is_dir (dir))
|
if (! rc_is_dir (dir))
|
||||||
if (mkdir (dir, 0755) != 0) {
|
if (mkdir (dir, 0755) != 0) {
|
||||||
eerror ("mkdir `%s': %s", dir, strerror (errno));
|
|
||||||
free (dir);
|
free (dir);
|
||||||
return;
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
init = rc_resolve_service (service_to_start);
|
init = rc_resolve_service (service_to_start);
|
||||||
svc = rc_xstrdup (service_to_start);
|
svc = rc_xstrdup (service_to_start);
|
||||||
file = rc_strcatpaths (dir, basename (svc), (char *) NULL);
|
file = rc_strcatpaths (dir, basename (svc), (char *) NULL);
|
||||||
free (svc);
|
free (svc);
|
||||||
if (! rc_exists (file) && symlink (init, file) != 0)
|
retval = (rc_exists (file) || symlink (init, file) == 0);
|
||||||
eerror ("symlink `%s' to `%s': %s", init, file, strerror (errno));
|
|
||||||
|
|
||||||
free (init);
|
free (init);
|
||||||
free (file);
|
free (file);
|
||||||
free (dir);
|
free (dir);
|
||||||
|
|
||||||
|
return (retval);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_schedule_start_service)
|
librc_hidden_def(rc_schedule_start_service)
|
||||||
|
|
||||||
@ -674,10 +647,8 @@ bool rc_wait_service (const char *service)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nanosleep (&ts, NULL) == -1) {
|
if (nanosleep (&ts, NULL) == -1) {
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR)
|
||||||
eerror ("nanosleep: %s", strerror (errno));
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! forever)
|
if (! forever)
|
||||||
@ -703,11 +674,7 @@ char **rc_services_in_runlevel (const char *runlevel)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
dir = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
|
dir = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
|
||||||
if (! rc_is_dir (dir))
|
list = rc_ls_dir (dir, RC_LS_INITD);
|
||||||
eerror ("runlevel `%s' does not exist", runlevel);
|
|
||||||
else
|
|
||||||
list = rc_ls_dir (dir, RC_LS_INITD);
|
|
||||||
|
|
||||||
free (dir);
|
free (dir);
|
||||||
return (list);
|
return (list);
|
||||||
}
|
}
|
||||||
|
16
src/librc.h
16
src/librc.h
@ -42,7 +42,6 @@
|
|||||||
#include <kvm.h>
|
#include <kvm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "einfo.h"
|
|
||||||
#include "librc-depend.h"
|
#include "librc-depend.h"
|
||||||
#include "rc.h"
|
#include "rc.h"
|
||||||
#include "rc-misc.h"
|
#include "rc-misc.h"
|
||||||
@ -53,16 +52,20 @@
|
|||||||
#define librc_hidden_def(x) hidden_def(x)
|
#define librc_hidden_def(x) hidden_def(x)
|
||||||
|
|
||||||
librc_hidden_proto(rc_allow_plug)
|
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_env_bool)
|
||||||
librc_hidden_proto(rc_exists)
|
librc_hidden_proto(rc_exists)
|
||||||
librc_hidden_proto(rc_filter_env)
|
librc_hidden_proto(rc_filter_env)
|
||||||
librc_hidden_proto(rc_find_pids)
|
librc_hidden_proto(rc_find_pids)
|
||||||
librc_hidden_proto(rc_free_deptree)
|
|
||||||
librc_hidden_proto(rc_get_config)
|
librc_hidden_proto(rc_get_config)
|
||||||
librc_hidden_proto(rc_get_config_entry)
|
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_list)
|
||||||
librc_hidden_proto(rc_get_runlevel)
|
librc_hidden_proto(rc_get_runlevel)
|
||||||
librc_hidden_proto(rc_get_runlevels)
|
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_exec)
|
||||||
librc_hidden_proto(rc_is_file)
|
librc_hidden_proto(rc_is_file)
|
||||||
librc_hidden_proto(rc_is_link)
|
librc_hidden_proto(rc_is_link)
|
||||||
librc_hidden_proto(rc_load_deptree)
|
|
||||||
librc_hidden_proto(rc_ls_dir)
|
librc_hidden_proto(rc_ls_dir)
|
||||||
librc_hidden_proto(rc_make_env)
|
librc_hidden_proto(rc_make_env)
|
||||||
librc_hidden_proto(rc_mark_service)
|
librc_hidden_proto(rc_mark_service)
|
||||||
librc_hidden_proto(rc_order_services)
|
|
||||||
librc_hidden_proto(rc_resolve_service)
|
librc_hidden_proto(rc_resolve_service)
|
||||||
librc_hidden_proto(rc_rm_dir)
|
librc_hidden_proto(rc_rm_dir)
|
||||||
librc_hidden_proto(rc_runlevel_exists)
|
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_free)
|
||||||
librc_hidden_proto(rc_strlist_join)
|
librc_hidden_proto(rc_strlist_join)
|
||||||
librc_hidden_proto(rc_strlist_reverse)
|
librc_hidden_proto(rc_strlist_reverse)
|
||||||
librc_hidden_proto(rc_update_deptree)
|
|
||||||
librc_hidden_proto(rc_wait_service)
|
librc_hidden_proto(rc_wait_service)
|
||||||
librc_hidden_proto(rc_waitpid)
|
librc_hidden_proto(rc_waitpid)
|
||||||
librc_hidden_proto(rc_xmalloc)
|
librc_hidden_proto(rc_xmalloc)
|
||||||
|
@ -19,6 +19,18 @@
|
|||||||
#include "rc-misc.h"
|
#include "rc-misc.h"
|
||||||
#include "strlist.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)
|
int rc_depend (int argc, char **argv)
|
||||||
{
|
{
|
||||||
char **types = NULL;
|
char **types = NULL;
|
||||||
@ -39,8 +51,9 @@ int rc_depend (int argc, char **argv)
|
|||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
if (strcmp (argv[i], "--update") == 0) {
|
if (strcmp (argv[i], "--update") == 0) {
|
||||||
if (! update) {
|
if (! update) {
|
||||||
rc_update_deptree (true);
|
ebegin ("Caching service dependencies");
|
||||||
update = true;
|
update = (rc_deptree_update () == 0);
|
||||||
|
eend (update ? 0 : -1, "Failed to update the dependency tree");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -59,10 +72,10 @@ int rc_depend (int argc, char **argv)
|
|||||||
argv[i]++;
|
argv[i]++;
|
||||||
rc_strlist_add (&types, argv[i]);
|
rc_strlist_add (&types, argv[i]);
|
||||||
} else {
|
} else {
|
||||||
if ((deptree = rc_load_deptree ()) == NULL)
|
if ((deptree = _rc_deptree_load ()) == NULL)
|
||||||
eerrorx ("failed to load deptree");
|
eerrorx ("failed to load deptree");
|
||||||
|
|
||||||
di = rc_get_depinfo (deptree, argv[i]);
|
di = rc_deptree_depinfo (deptree, argv[i]);
|
||||||
if (! di)
|
if (! di)
|
||||||
eerror ("no dependency info for service `%s'", argv[i]);
|
eerror ("no dependency info for service `%s'", argv[i]);
|
||||||
else
|
else
|
||||||
@ -72,7 +85,7 @@ int rc_depend (int argc, char **argv)
|
|||||||
|
|
||||||
if (! services) {
|
if (! services) {
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
rc_free_deptree (deptree);
|
rc_deptree_free (deptree);
|
||||||
if (update)
|
if (update)
|
||||||
return (EXIT_SUCCESS);
|
return (EXIT_SUCCESS);
|
||||||
eerrorx ("no services specified");
|
eerrorx ("no services specified");
|
||||||
@ -84,7 +97,7 @@ int rc_depend (int argc, char **argv)
|
|||||||
rc_strlist_add (&types, "iuse");
|
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) {
|
if (depends) {
|
||||||
STRLIST_FOREACH (depends, service, i) {
|
STRLIST_FOREACH (depends, service, i) {
|
||||||
@ -103,7 +116,7 @@ int rc_depend (int argc, char **argv)
|
|||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
rc_strlist_free (services);
|
rc_strlist_free (services);
|
||||||
rc_strlist_free (depends);
|
rc_strlist_free (depends);
|
||||||
rc_free_deptree (deptree);
|
rc_deptree_free (deptree);
|
||||||
|
|
||||||
return (EXIT_SUCCESS);
|
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 (coldplugged_services);
|
||||||
rc_strlist_free (stop_services);
|
rc_strlist_free (stop_services);
|
||||||
rc_strlist_free (start_services);
|
rc_strlist_free (start_services);
|
||||||
rc_free_deptree (deptree);
|
rc_deptree_free (deptree);
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
|
|
||||||
/* Clean runlevel start, stop markers */
|
/* Clean runlevel start, stop markers */
|
||||||
@ -1021,7 +1021,7 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load our deptree now */
|
/* Load our deptree now */
|
||||||
if ((deptree = rc_load_deptree ()) == NULL)
|
if ((deptree = _rc_deptree_load ()) == NULL)
|
||||||
eerrorx ("failed to load deptree");
|
eerrorx ("failed to load deptree");
|
||||||
|
|
||||||
/* Clean the failed services state dir now */
|
/* 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, "iuse");
|
||||||
rc_strlist_add (&types, "iafter");
|
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);
|
runlevel, depoptions | RC_DEP_STOP);
|
||||||
|
|
||||||
rc_strlist_free (stop_services);
|
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
|
/* We got this far! Or last check is to see if any any service that
|
||||||
going to be started depends on us */
|
going to be started depends on us */
|
||||||
rc_strlist_add (&stopdeps, service);
|
rc_strlist_add (&stopdeps, service);
|
||||||
deporder = rc_get_depends (deptree, types, stopdeps,
|
deporder = rc_deptree_depends (deptree, types, stopdeps,
|
||||||
runlevel, RC_DEP_STRICT);
|
runlevel, RC_DEP_STRICT);
|
||||||
rc_strlist_free (stopdeps);
|
rc_strlist_free (stopdeps);
|
||||||
stopdeps = NULL;
|
stopdeps = NULL;
|
||||||
@ -1300,7 +1300,7 @@ int main (int argc, char **argv)
|
|||||||
rc_strlist_add (&types, "ineed");
|
rc_strlist_add (&types, "ineed");
|
||||||
rc_strlist_add (&types, "iuse");
|
rc_strlist_add (&types, "iuse");
|
||||||
rc_strlist_add (&types, "iafter");
|
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);
|
runlevel, depoptions | RC_DEP_START);
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
types = NULL;
|
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
|
/*! Schedule a service to be started when another service starts
|
||||||
* @param service that starts the scheduled service when started
|
* @param service that starts the scheduled service when started
|
||||||
* @param service_to_start service that will be 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);
|
const char *service_to_start);
|
||||||
/*! Return a NULL terminated list of services that are scheduled to start
|
/*! Return a NULL terminated list of services that are scheduled to start
|
||||||
* when the given service has started
|
* when the given service has started
|
||||||
@ -171,7 +171,7 @@ char *rc_get_runlevel (void);
|
|||||||
/*! Set the runlevel.
|
/*! Set the runlevel.
|
||||||
* This just changes the stored runlevel and does not start or stop any services.
|
* This just changes the stored runlevel and does not start or stop any services.
|
||||||
* @param runlevel to store */
|
* @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
|
/*! Checks if the runlevel exists or not
|
||||||
* @param runlevel to check
|
* @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,
|
/*! Update the cached dependency tree if it's older than any init script,
|
||||||
* its configuration file or an external configuration file the init script
|
* its configuration file or an external configuration file the init script
|
||||||
* has specified.
|
* has specified.
|
||||||
* @param force an update
|
|
||||||
* @return 0 if successful, otherwise -1 */
|
* @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.
|
/*! 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 */
|
* @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
|
/*! Get a services depedency information from a loaded tree
|
||||||
* @param deptree to search
|
* @param deptree to search
|
||||||
* @param service to find
|
* @param service to find
|
||||||
* @return service dependency information */
|
* @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
|
/*! Get a depenency type from the service dependency information
|
||||||
* @param depinfo service dependency to search
|
* @param depinfo service dependency to search
|
||||||
* @param type to find
|
* @param type to find
|
||||||
* @return service dependency type information */
|
* @return service dependency type information */
|
||||||
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);
|
||||||
char **rc_get_depends (rc_depinfo_t *deptree, char **types,
|
char **rc_deptree_depends (rc_depinfo_t *deptree, char **types,
|
||||||
char **services, const char *runlevel, int options);
|
char **services, const char *runlevel, int options);
|
||||||
/*! List all the services that should be stoppned and then started, in order,
|
/*! List all the services that should be stoppned and then started, in order,
|
||||||
* for the given runlevel, including sysinit and boot services where
|
* for the given runlevel, including sysinit and boot services where
|
||||||
* approriate.
|
* approriate.
|
||||||
@ -280,11 +284,11 @@ char **rc_get_depends (rc_depinfo_t *deptree, char **types,
|
|||||||
* @param runlevel to change into
|
* @param runlevel to change into
|
||||||
* @param options to pass
|
* @param options to pass
|
||||||
* @return NULL terminated list of services in order */
|
* @return NULL terminated list of services in order */
|
||||||
char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
|
char **rc_deptree_order_services (rc_depinfo_t *deptree, const char *runlevel,
|
||||||
int options);
|
int options);
|
||||||
/*! Free a deptree and its information
|
/*! Free a deptree and its information
|
||||||
* @param deptree to free */
|
* @param deptree to free */
|
||||||
void rc_free_deptree (rc_depinfo_t *deptree);
|
void rc_deptree_free (rc_depinfo_t *deptree);
|
||||||
|
|
||||||
/*! @name Plugins
|
/*! @name Plugins
|
||||||
* For each plugin loaded we will call rc_plugin_hook with the below
|
* 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_plugin_unload ();
|
||||||
rc_free_deptree (deptree);
|
rc_deptree_free (deptree);
|
||||||
rc_strlist_free (services);
|
rc_strlist_free (services);
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
rc_strlist_free (svclist);
|
rc_strlist_free (svclist);
|
||||||
@ -578,7 +578,7 @@ static void svc_start (bool deps)
|
|||||||
depoptions |= RC_DEP_START;
|
depoptions |= RC_DEP_START;
|
||||||
|
|
||||||
if (deps) {
|
if (deps) {
|
||||||
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
|
if (! deptree && ((deptree = _rc_deptree_load ()) == NULL))
|
||||||
eerrorx ("failed to load deptree");
|
eerrorx ("failed to load deptree");
|
||||||
|
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
@ -588,7 +588,7 @@ static void svc_start (bool deps)
|
|||||||
svclist = NULL;
|
svclist = NULL;
|
||||||
rc_strlist_add (&svclist, applet);
|
rc_strlist_add (&svclist, applet);
|
||||||
rc_strlist_free (services);
|
rc_strlist_free (services);
|
||||||
services = rc_get_depends (deptree, types, svclist, softlevel, 0);
|
services = rc_deptree_depends (deptree, types, svclist, softlevel, 0);
|
||||||
if (services) {
|
if (services) {
|
||||||
eerrorn ("ERROR: `%s' needs ", applet);
|
eerrorn ("ERROR: `%s' needs ", applet);
|
||||||
STRLIST_FOREACH (services, svc, i) {
|
STRLIST_FOREACH (services, svc, i) {
|
||||||
@ -605,12 +605,12 @@ static void svc_start (bool deps)
|
|||||||
types = NULL;
|
types = NULL;
|
||||||
rc_strlist_add (&types, "ineed");
|
rc_strlist_add (&types, "ineed");
|
||||||
rc_strlist_free (need_services);
|
rc_strlist_free (need_services);
|
||||||
need_services = rc_get_depends (deptree, types, svclist,
|
need_services = rc_deptree_depends (deptree, types, svclist,
|
||||||
softlevel, depoptions);
|
softlevel, depoptions);
|
||||||
|
|
||||||
rc_strlist_add (&types, "iuse");
|
rc_strlist_add (&types, "iuse");
|
||||||
rc_strlist_free (use_services);
|
rc_strlist_free (use_services);
|
||||||
use_services = rc_get_depends (deptree, types, svclist,
|
use_services = rc_deptree_depends (deptree, types, svclist,
|
||||||
softlevel, depoptions);
|
softlevel, depoptions);
|
||||||
|
|
||||||
if (! rc_runlevel_starting ()) {
|
if (! rc_runlevel_starting ()) {
|
||||||
@ -624,7 +624,7 @@ static void svc_start (bool deps)
|
|||||||
|
|
||||||
/* Now wait for them to start */
|
/* Now wait for them to start */
|
||||||
rc_strlist_add (&types, "iafter");
|
rc_strlist_add (&types, "iafter");
|
||||||
services = rc_get_depends (deptree, types, svclist,
|
services = rc_deptree_depends (deptree, types, svclist,
|
||||||
softlevel, depoptions);
|
softlevel, depoptions);
|
||||||
|
|
||||||
/* We use tmplist to hold our scheduled by list */
|
/* We use tmplist to hold our scheduled by list */
|
||||||
@ -686,7 +686,7 @@ static void svc_start (bool deps)
|
|||||||
svclist = NULL;
|
svclist = NULL;
|
||||||
rc_strlist_add (&svclist, svc);
|
rc_strlist_add (&svclist, svc);
|
||||||
rc_strlist_free (providelist);
|
rc_strlist_free (providelist);
|
||||||
providelist = rc_get_depends (deptree, types, svclist,
|
providelist = rc_deptree_depends (deptree, types, svclist,
|
||||||
softlevel, depoptions);
|
softlevel, depoptions);
|
||||||
STRLIST_FOREACH (providelist, svc2, j)
|
STRLIST_FOREACH (providelist, svc2, j)
|
||||||
rc_schedule_start_service (svc2, service);
|
rc_schedule_start_service (svc2, service);
|
||||||
@ -766,7 +766,7 @@ static void svc_start (bool deps)
|
|||||||
svclist = NULL;
|
svclist = NULL;
|
||||||
rc_strlist_add (&svclist, applet);
|
rc_strlist_add (&svclist, applet);
|
||||||
rc_strlist_free (tmplist);
|
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) {
|
STRLIST_FOREACH (tmplist, svc2, j) {
|
||||||
rc_strlist_free (services);
|
rc_strlist_free (services);
|
||||||
@ -822,7 +822,7 @@ static void svc_stop (bool deps)
|
|||||||
if (rc_runlevel_stopping ())
|
if (rc_runlevel_stopping ())
|
||||||
depoptions |= RC_DEP_STOP;
|
depoptions |= RC_DEP_STOP;
|
||||||
|
|
||||||
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
|
if (! deptree && ((deptree = _rc_deptree_load ()) == NULL))
|
||||||
eerrorx ("failed to load deptree");
|
eerrorx ("failed to load deptree");
|
||||||
|
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
@ -834,7 +834,7 @@ static void svc_stop (bool deps)
|
|||||||
rc_strlist_free (tmplist);
|
rc_strlist_free (tmplist);
|
||||||
tmplist = NULL;
|
tmplist = NULL;
|
||||||
rc_strlist_free (services);
|
rc_strlist_free (services);
|
||||||
services = rc_get_depends (deptree, types, svclist,
|
services = rc_deptree_depends (deptree, types, svclist,
|
||||||
softlevel, depoptions);
|
softlevel, depoptions);
|
||||||
rc_strlist_reverse (services);
|
rc_strlist_reverse (services);
|
||||||
STRLIST_FOREACH (services, svc, i) {
|
STRLIST_FOREACH (services, svc, i) {
|
||||||
@ -885,7 +885,7 @@ static void svc_stop (bool deps)
|
|||||||
This is important when a runlevel stops */
|
This is important when a runlevel stops */
|
||||||
rc_strlist_add (&types, "usesme");
|
rc_strlist_add (&types, "usesme");
|
||||||
rc_strlist_add (&types, "ibefore");
|
rc_strlist_add (&types, "ibefore");
|
||||||
services = rc_get_depends (deptree, types, svclist,
|
services = rc_deptree_depends (deptree, types, svclist,
|
||||||
softlevel, depoptions);
|
softlevel, depoptions);
|
||||||
STRLIST_FOREACH (services, svc, i) {
|
STRLIST_FOREACH (services, svc, i) {
|
||||||
if (rc_service_state (svc) & RC_SERVICE_STOPPED)
|
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"))
|
if (rc_env_bool ("RC_DEPEND_STRICT"))
|
||||||
depoptions |= RC_DEP_STRICT;
|
depoptions |= RC_DEP_STRICT;
|
||||||
|
|
||||||
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
|
if (! deptree && ((deptree = _rc_deptree_load ()) == NULL))
|
||||||
eerrorx ("failed to load deptree");
|
eerrorx ("failed to load deptree");
|
||||||
|
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
@ -1199,7 +1199,7 @@ int runscript (int argc, char **argv)
|
|||||||
svclist = NULL;
|
svclist = NULL;
|
||||||
rc_strlist_add (&svclist, applet);
|
rc_strlist_add (&svclist, applet);
|
||||||
rc_strlist_free (services);
|
rc_strlist_free (services);
|
||||||
services = rc_get_depends (deptree, types, svclist,
|
services = rc_deptree_depends (deptree, types, svclist,
|
||||||
softlevel, depoptions);
|
softlevel, depoptions);
|
||||||
STRLIST_FOREACH (services, svc, i)
|
STRLIST_FOREACH (services, svc, i)
|
||||||
printf ("%s%s", i == 1 ? "" : " ", svc);
|
printf ("%s%s", i == 1 ? "" : " ", svc);
|
||||||
|
Loading…
Reference in New Issue
Block a user