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

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

View File

@ -54,12 +54,12 @@ LDLIBS_LIBEINFO = $(LDLIBS)
LIBRCSOVER = 0 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

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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");

View File

@ -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);
} }

View File

@ -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)

View File

@ -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);
} }

View File

@ -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;

View File

@ -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

View File

@ -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);