summaryrefslogtreecommitdiff
path: root/src/rc/runscript.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-03-16 17:00:56 +0000
committerRoy Marples <roy@marples.name>2008-03-16 17:00:56 +0000
commitcb9da6a262b60255cd037f20b4cde3ab2c8a1e6a (patch)
treec5c57d5adedf009fdb02b53677e2cdf940bdb47c /src/rc/runscript.c
parent40e12f6ba026af9c24d5c3d8e36512719ed5faee (diff)
downloadopenrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.gz
openrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.bz2
openrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.xz
Remove null terminated char ** lists in favour of RC_STRINGLIST, using TAILQ from queue(3). Refactor code style around the BSD KNF.
Diffstat (limited to 'src/rc/runscript.c')
-rw-r--r--src/rc/runscript.c1263
1 files changed, 624 insertions, 639 deletions
diff --git a/src/rc/runscript.c b/src/rc/runscript.c
index ef9a3e2..cfc2611 100644
--- a/src/rc/runscript.c
+++ b/src/rc/runscript.c
@@ -34,6 +34,7 @@
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/stat.h>
+
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
@@ -60,11 +61,10 @@
#include "rc.h"
#include "rc-misc.h"
#include "rc-plugin.h"
-#include "strlist.h"
#define SELINUX_LIB RC_LIBDIR "/runscript_selinux.so"
-#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
+#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
/* usecs to wait while we poll the fifo */
#define WAIT_INTERVAL 20000000
@@ -75,192 +75,187 @@
#define ONE_SECOND 1000000000
static const char *applet = NULL;
-static char **applet_list = NULL;
+static RC_STRINGLIST *applet_list = NULL;
+static RC_STRINGLIST *restart_services = NULL;
+static RC_STRINGLIST *need_services = NULL;
+static RC_STRINGLIST *use_services = NULL;
+static RC_STRINGLIST *services = NULL;
+static RC_STRINGLIST *tmplist = NULL;
static char *service = NULL;
static char *exclusive = NULL;
static char *mtime_test = NULL;
-static rc_depinfo_t *deptree = NULL;
-static char **services = NULL;
-static char **tmplist = NULL;
-static char **providelist = NULL;
-static char **restart_services = NULL;
-static char **need_services = NULL;
-static char **use_services = NULL;
-static char **env = NULL;
-static char *tmp = NULL;
-static char *softlevel = NULL;
+static RC_DEPTREE *deptree = NULL;
+static char *runlevel = NULL;
static bool sighup = false;
static char *ibsave = NULL;
static bool in_background = false;
-static rc_hook_t hook_out = 0;
+static RC_HOOK hook_out = 0;
static pid_t service_pid = 0;
static char *prefix = NULL;
static bool prefix_locked = false;
static int signal_pipe[2] = { -1, -1 };
static int master_tty = -1;
-extern char **environ;
-
-static const char *const types_b[] = { "broken", NULL };
-static const char *const types_n[] = { "ineed", NULL };
-static const char *const types_nu[] = { "ineed", "iuse", NULL };
-static const char *const types_nua[] = { "ineed", "iuse", "iafter", NULL };
-
-static const char *const types_m[] = { "needsme", NULL };
-static const char *const types_mua[] = { "needsme", "usesme", "beforeme", NULL };
+static RC_STRINGLIST *types_b = NULL;
+static RC_STRINGLIST *types_n = NULL;
+static RC_STRINGLIST *types_nu = NULL;
+static RC_STRINGLIST *types_nua = NULL;
+static RC_STRINGLIST *types_m = NULL;
+static RC_STRINGLIST *types_mua = NULL;
#ifdef __linux__
-static void (*selinux_run_init_old) (void);
-static void (*selinux_run_init_new) (int argc, char **argv);
+static void (*selinux_run_init_old)(void);
+static void (*selinux_run_init_new)(int argc, char **argv);
-static void setup_selinux (int argc, char **argv);
+static void setup_selinux(int argc, char **argv);
-static void setup_selinux (int argc, char **argv)
+static void setup_selinux(int argc, char **argv)
{
void *lib_handle = NULL;
- if (! exists (SELINUX_LIB))
+ if (! exists(SELINUX_LIB))
return;
- lib_handle = dlopen (SELINUX_LIB, RTLD_NOW | RTLD_GLOBAL);
+ lib_handle = dlopen(SELINUX_LIB, RTLD_NOW | RTLD_GLOBAL);
if (! lib_handle) {
- eerror ("dlopen: %s", dlerror ());
+ eerror("dlopen: %s", dlerror());
return;
}
selinux_run_init_old = (void (*)(void))
- dlfunc (lib_handle, "selinux_runscript");
+ dlfunc(lib_handle, "selinux_runscript");
selinux_run_init_new = (void (*)(int, char **))
- dlfunc (lib_handle, "selinux_runscript2");
+ dlfunc(lib_handle, "selinux_runscript2");
/* Use new run_init if it exists, else fall back to old */
if (selinux_run_init_new)
- selinux_run_init_new (argc, argv);
+ selinux_run_init_new(argc, argv);
else if (selinux_run_init_old)
- selinux_run_init_old ();
+ selinux_run_init_old();
else
/* This shouldnt happen... probably corrupt lib */
- eerrorx ("run_init is missing from runscript_selinux.so!");
+ eerrorx("run_init is missing from runscript_selinux.so!");
- dlclose (lib_handle);
+ dlclose(lib_handle);
}
#endif
-static void handle_signal (int sig)
+static void handle_signal(int sig)
{
int serrno = errno;
char signame[10] = { '\0' };
struct winsize ws;
switch (sig) {
- case SIGHUP:
- sighup = true;
- break;
-
- case SIGCHLD:
- if (signal_pipe[1] > -1) {
- if (write (signal_pipe[1], &sig, sizeof (sig)) == -1)
- eerror ("%s: send: %s", service, strerror (errno));
- } else
- rc_waitpid (-1);
- break;
-
- case SIGWINCH:
- if (master_tty >= 0) {
- ioctl (fileno (stdout), TIOCGWINSZ, &ws);
- ioctl (master_tty, TIOCSWINSZ, &ws);
- }
- break;
+ case SIGHUP:
+ sighup = true;
+ break;
+
+ case SIGCHLD:
+ if (signal_pipe[1] > -1) {
+ if (write(signal_pipe[1], &sig, sizeof(sig)) == -1)
+ eerror("%s: send: %s", service, strerror(errno));
+ } else
+ rc_waitpid (-1);
+ break;
- case SIGINT:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGINT");
- /* FALLTHROUGH */
- case SIGTERM:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGTERM");
- /* FALLTHROUGH */
- case SIGQUIT:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGQUIT");
- /* Send the signal to our children too */
- if (service_pid > 0)
- kill (service_pid, sig);
- eerrorx ("%s: caught %s, aborting", applet, signame);
- /* NOTREACHED */
-
- default:
- eerror ("%s: caught unknown signal %d", applet, sig);
+ case SIGWINCH:
+ if (master_tty >= 0) {
+ ioctl(fileno(stdout), TIOCGWINSZ, &ws);
+ ioctl(master_tty, TIOCSWINSZ, &ws);
+ }
+ break;
+
+ case SIGINT:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGINT");
+ /* FALLTHROUGH */
+ case SIGTERM:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGTERM");
+ /* FALLTHROUGH */
+ case SIGQUIT:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGQUIT");
+ /* Send the signal to our children too */
+ if (service_pid > 0)
+ kill(service_pid, sig);
+ eerrorx("%s: caught %s, aborting", applet, signame);
+ /* NOTREACHED */
+
+ default:
+ eerror("%s: caught unknown signal %d", applet, sig);
}
/* Restore errno */
errno = serrno;
}
-static time_t get_mtime (const char *pathname, bool follow_link)
+static time_t get_mtime(const char *pathname, bool follow_link)
{
struct stat buf;
int retval;
if (! pathname)
- return (0);
+ return 0;
- retval = follow_link ? stat (pathname, &buf) : lstat (pathname, &buf);
+ retval = follow_link ? stat(pathname, &buf) : lstat(pathname, &buf);
if (! retval)
- return (buf.st_mtime);
+ return buf.st_mtime;
errno = 0;
- return (0);
+ return 0;
}
-static bool in_control ()
+static const char *const tests[] = {
+ "starting", "started", "stopping", "inactive", "wasinactive", NULL
+};
+static bool in_control()
{
char *path;
+ time_t m;
time_t mtime;
- const char *tests[] = { "starting", "started", "stopping",
- "inactive", "wasinactive", NULL };
int i = 0;
if (sighup)
- return (false);
+ return false;
- if (! mtime_test || ! exists (mtime_test))
- return (false);
+ if (! mtime_test || ! exists(mtime_test))
+ return false;
- if (rc_service_state (applet) & RC_SERVICE_STOPPED)
- return (false);
+ if (rc_service_state(applet) & RC_SERVICE_STOPPED)
+ return false;
- if (! (mtime = get_mtime (mtime_test, false)))
- return (false);
+ if (! (mtime = get_mtime(mtime_test, false)))
+ return false;
while (tests[i]) {
- path = rc_strcatpaths (RC_SVCDIR, tests[i], applet, (char *) NULL);
- if (exists (path)) {
- time_t m = get_mtime (path, false);
+ path = rc_strcatpaths(RC_SVCDIR, tests[i], applet, (char *) NULL);
+ if (exists(path)) {
+ m = get_mtime(path, false);
if (mtime < m && m != 0) {
- free (path);
- return (false);
+ free(path);
+ return false;
}
}
- free (path);
+ free(path);
i++;
}
- return (true);
+ return true;
}
-static void uncoldplug ()
+static void uncoldplug()
{
- char *cold = rc_strcatpaths (RC_SVCDIR, "coldplugged", applet, (char *) NULL);
- if (exists (cold) && unlink (cold) != 0)
- eerror ("%s: unlink `%s': %s", applet, cold, strerror (errno));
- free (cold);
+ char *cold = rc_strcatpaths(RC_SVCDIR, "coldplugged", applet, (char *) NULL);
+ if (exists(cold) && unlink(cold) != 0)
+ eerror("%s: unlink `%s': %s", applet, cold, strerror(errno));
+ free(cold);
}
-static void start_services (char **list) {
- char *svc;
- int i;
- rc_service_state_t state = rc_service_state (service);
+static void start_services(RC_STRINGLIST *list) {
+ RC_STRING *svc;
+ RC_SERVICE state = rc_service_state (service);
if (! list)
return;
@@ -270,102 +265,107 @@ static void start_services (char **list) {
state & RC_SERVICE_STARTING ||
state & RC_SERVICE_STARTED)
{
- STRLIST_FOREACH (list, svc, i) {
- if (rc_service_state (svc) & RC_SERVICE_STOPPED) {
+ TAILQ_FOREACH(svc, list, entries) {
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED) {
if (state & RC_SERVICE_INACTIVE ||
state & RC_SERVICE_WASINACTIVE)
{
- rc_service_schedule_start (service, svc);
- ewarn ("WARNING: %s is scheduled to started when %s has started",
- svc, applet);
+ rc_service_schedule_start(service, svc->value);
+ ewarn("WARNING: %s is scheduled to started"
+ " when %s has started",
+ svc->value, applet);
} else
- rc_service_start (svc);
+ rc_service_start(svc->value);
}
}
}
}
-static void restore_state (void)
+static void restore_state(void)
{
- rc_service_state_t state;
+ RC_SERVICE state;
- if (rc_in_plugin || ! in_control ())
+ if (rc_in_plugin || ! in_control())
return;
- state = rc_service_state (applet);
+ state = rc_service_state(applet);
if (state & RC_SERVICE_STOPPING) {
-
if (state & RC_SERVICE_WASINACTIVE)
- rc_service_mark (applet, RC_SERVICE_INACTIVE);
+ rc_service_mark(applet, RC_SERVICE_INACTIVE);
else
- rc_service_mark (applet, RC_SERVICE_STARTED);
- if (rc_runlevel_stopping ())
- rc_service_mark (applet, RC_SERVICE_FAILED);
+ rc_service_mark(applet, RC_SERVICE_STARTED);
+ if (rc_runlevel_stopping())
+ rc_service_mark(applet, RC_SERVICE_FAILED);
} else if (state & RC_SERVICE_STARTING) {
if (state & RC_SERVICE_WASINACTIVE)
- rc_service_mark (applet, RC_SERVICE_INACTIVE);
+ rc_service_mark(applet, RC_SERVICE_INACTIVE);
else
- rc_service_mark (applet, RC_SERVICE_STOPPED);
- if (rc_runlevel_starting ())
- rc_service_mark (applet, RC_SERVICE_FAILED);
+ rc_service_mark(applet, RC_SERVICE_STOPPED);
+ if (rc_runlevel_starting())
+ rc_service_mark(applet, RC_SERVICE_FAILED);
}
if (exclusive)
- unlink (exclusive);
- free (exclusive);
+ unlink(exclusive);
+ free(exclusive);
exclusive = NULL;
}
-static void cleanup (void)
+static void cleanup(void)
{
- restore_state ();
+ restore_state();
if (! rc_in_plugin) {
if (prefix_locked)
- unlink (PREFIX_LOCK);
+ unlink(PREFIX_LOCK);
if (hook_out) {
- rc_plugin_run (hook_out, applet);
+ rc_plugin_run(hook_out, applet);
if (hook_out == RC_HOOK_SERVICE_START_DONE)
- rc_plugin_run (RC_HOOK_SERVICE_START_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
else if (hook_out == RC_HOOK_SERVICE_STOP_DONE)
- rc_plugin_run (RC_HOOK_SERVICE_STOP_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
}
if (restart_services)
- start_services (restart_services);
+ start_services(restart_services);
}
- rc_plugin_unload ();
- rc_deptree_free (deptree);
- rc_strlist_free (services);
- rc_strlist_free (providelist);
- rc_strlist_free (need_services);
- rc_strlist_free (use_services);
- rc_strlist_free (restart_services);
- rc_strlist_free (applet_list);
- rc_strlist_free (tmplist);
+ rc_stringlist_free(types_b);
+ rc_stringlist_free(types_n);
+ rc_stringlist_free(types_nu);
+ rc_stringlist_free(types_nua);
+ rc_stringlist_free(types_m);
+ rc_stringlist_free(types_mua);
+
+ rc_plugin_unload();
+ rc_deptree_free(deptree);
+
+ rc_stringlist_free(restart_services);
+ rc_stringlist_free(need_services);
+ rc_stringlist_free(use_services);
+ rc_stringlist_free(services);
+ rc_stringlist_free(applet_list);
+ rc_stringlist_free(tmplist);
free (ibsave);
- rc_strlist_free (env);
-
if (mtime_test)
{
if (! rc_in_plugin)
- unlink (mtime_test);
- free (mtime_test);
+ unlink(mtime_test);
+ free(mtime_test);
}
- free (exclusive);
- free (service);
- free (prefix);
- free (softlevel);
+ free(exclusive);
+ free(service);
+ free(prefix);
+ free(runlevel);
}
-static int write_prefix (const char *buffer, size_t bytes, bool *prefixed) {
+static int write_prefix(const char *buffer, size_t bytes, bool *prefixed) {
unsigned int i;
- const char *ec = ecolor (ECOLOR_HILITE);
- const char *ec_normal = ecolor (ECOLOR_NORMAL);
+ const char *ec = ecolor(ECOLOR_HILITE);
+ const char *ec_normal = ecolor(ECOLOR_NORMAL);
ssize_t ret = 0;
- int fd = fileno (stdout);
+ int fd = fileno(stdout);
for (i = 0; i < bytes; i++) {
/* We don't prefix escape codes, like eend */
@@ -373,25 +373,25 @@ static int write_prefix (const char *buffer, size_t bytes, bool *prefixed) {
*prefixed = true;
if (! *prefixed) {
- ret += write (fd, ec, strlen (ec));
- ret += write (fd, prefix, strlen (prefix));
- ret += write (fd, ec_normal, strlen (ec_normal));
- ret += write (fd, "|", 1);
+ ret += write(fd, ec, strlen(ec));
+ ret += write(fd, prefix, strlen(prefix));
+ ret += write(fd, ec_normal, strlen(ec_normal));
+ ret += write(fd, "|", 1);
*prefixed = true;
}
if (buffer[i] == '\n')
*prefixed = false;
- ret += write (fd, buffer + i, 1);
+ ret += write(fd, buffer + i, 1);
}
- return (ret);
+ return ret;
}
-static bool svc_exec (const char *arg1, const char *arg2)
+static bool svc_exec(const char *arg1, const char *arg2)
{
bool execok;
- int fdout = fileno (stdout);
+ int fdout = fileno(stdout);
struct termios tt;
struct winsize ws;
int i;
@@ -405,12 +405,12 @@ static bool svc_exec (const char *arg1, const char *arg2)
int slave_tty;
/* Setup our signal pipe */
- if (pipe (signal_pipe) == -1)
- eerrorx ("%s: pipe: %s", service, applet);
+ if (pipe(signal_pipe) == -1)
+ eerrorx("%s: pipe: %s", service, applet);
for (i = 0; i < 2; i++)
- if ((flags = fcntl (signal_pipe[i], F_GETFD, 0) == -1 ||
- fcntl (signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) == -1))
- eerrorx ("%s: fcntl: %s", service, strerror (errno));
+ if ((flags = fcntl(signal_pipe[i], F_GETFD, 0) == -1 ||
+ fcntl(signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) == -1))
+ eerrorx("%s: fcntl: %s", service, strerror(errno));
/* Open a pty for our prefixed output
* We do this instead of mapping pipes to stdout, stderr so that
@@ -418,127 +418,125 @@ static bool svc_exec (const char *arg1, const char *arg2)
* The only loss is that we can no longer tell the difference
* between the childs stdout or stderr */
master_tty = slave_tty = -1;
- if (prefix && isatty (fdout)) {
- tcgetattr (fdout, &tt);
- ioctl (fdout, TIOCGWINSZ, &ws);
+ if (prefix && isatty(fdout)) {
+ tcgetattr(fdout, &tt);
+ ioctl(fdout, TIOCGWINSZ, &ws);
/* If the below call fails due to not enough ptys then we don't
* prefix the output, but we still work */
- openpty (&master_tty, &slave_tty, NULL, &tt, &ws);
+ openpty(&master_tty, &slave_tty, NULL, &tt, &ws);
if (master_tty >= 0 &&
- (flags = fcntl (master_tty, F_GETFD, 0)) == 0)
- fcntl (master_tty, F_SETFD, flags | FD_CLOEXEC);
+ (flags = fcntl(master_tty, F_GETFD, 0)) == 0)
+ fcntl(master_tty, F_SETFD, flags | FD_CLOEXEC);
if (slave_tty >=0 &&
- (flags = fcntl (slave_tty, F_GETFD, 0)) == 0)
- fcntl (slave_tty, F_SETFD, flags | FD_CLOEXEC);
+ (flags = fcntl(slave_tty, F_GETFD, 0)) == 0)
+ fcntl(slave_tty, F_SETFD, flags | FD_CLOEXEC);
}
service_pid = fork();
if (service_pid == -1)
- eerrorx ("%s: fork: %s", service, strerror (errno));
+ eerrorx("%s: fork: %s", service, strerror(errno));
if (service_pid == 0) {
if (slave_tty >= 0) {
- dup2 (slave_tty, 1);
- dup2 (slave_tty, 2);
+ dup2(slave_tty, 1);
+ dup2(slave_tty, 2);
}
- if (exists (RC_SVCDIR "/runscript.sh")) {
- execl (RC_SVCDIR "/runscript.sh", RC_SVCDIR "/runscript.sh",
- service, arg1, arg2, (char *) NULL);
- eerror ("%s: exec `" RC_SVCDIR "/runscript.sh': %s",
- service, strerror (errno));
- _exit (EXIT_FAILURE);
+ if (exists(RC_SVCDIR "/runscript.sh")) {
+ execl(RC_SVCDIR "/runscript.sh", RC_SVCDIR "/runscript.sh",
+ service, arg1, arg2, (char *) NULL);
+ eerror("%s: exec `" RC_SVCDIR "/runscript.sh': %s",
+ service, strerror(errno));
+ _exit(EXIT_FAILURE);
} else {
- execl (RC_LIBDIR "/sh/runscript.sh", RC_LIBDIR "/sh/runscript.sh",
- service, arg1, arg2, (char *) NULL);
- eerror ("%s: exec `" RC_LIBDIR "/sh/runscript.sh': %s",
- service, strerror (errno));
- _exit (EXIT_FAILURE);
+ execl(RC_LIBDIR "/sh/runscript.sh", RC_LIBDIR "/sh/runscript.sh",
+ service, arg1, arg2, (char *) NULL);
+ eerror("%s: exec `" RC_LIBDIR "/sh/runscript.sh': %s",
+ service, strerror(errno));
+ _exit(EXIT_FAILURE);
}
}
- selfd = MAX (master_tty, signal_pipe[0]) + 1;
- buffer = xmalloc (sizeof (char) * BUFSIZ);
+ selfd = MAX(master_tty, signal_pipe[0]) + 1;
+ buffer = xmalloc(sizeof(char) * BUFSIZ);
for (;;) {
- FD_ZERO (&rset);
- FD_SET (signal_pipe[0], &rset);
+ FD_ZERO(&rset);
+ FD_SET(signal_pipe[0], &rset);
if (master_tty >= 0)
- FD_SET (master_tty, &rset);
+ FD_SET(master_tty, &rset);
- if ((s = select (selfd, &rset, NULL, NULL, NULL)) == -1) {
+ if ((s = select(selfd, &rset, NULL, NULL, NULL)) == -1) {
if (errno != EINTR) {
- eerror ("%s: select: %s", service, strerror (errno));
+ eerror("%s: select: %s", service, strerror(errno));
break;
}
}
if (s > 0) {
- if (master_tty >= 0 && FD_ISSET (master_tty, &rset)) {
- bytes = read (master_tty, buffer, BUFSIZ);
- write_prefix (buffer, bytes, &prefixed);
+ if (master_tty >= 0 && FD_ISSET(master_tty, &rset)) {
+ bytes = read(master_tty, buffer, BUFSIZ);
+ write_prefix(buffer, bytes, &prefixed);
}
/* Only SIGCHLD signals come down this pipe */
- if (FD_ISSET (signal_pipe[0], &rset))
+ if (FD_ISSET(signal_pipe[0], &rset))
break;
}
}
- free (buffer);
- close (signal_pipe[0]);
- close (signal_pipe[1]);
+ free(buffer);
+ close(signal_pipe[0]);
+ close(signal_pipe[1]);
signal_pipe[0] = signal_pipe[1] = -1;
if (master_tty >= 0) {
/* Why did we do this? */
/* signal (SIGWINCH, SIG_IGN); */
- close (master_tty);
+ close(master_tty);
master_tty = -1;
}
- execok = rc_waitpid (service_pid) == 0 ? true : false;
+ execok = rc_waitpid(service_pid) == 0 ? true : false;
service_pid = 0;
- return (execok);
+ return execok;
}
-static bool svc_wait (rc_depinfo_t *depinfo, const char *svc)
+static bool svc_wait(const char *svc)
{
- char *s;
- char *fifo;
+ char fifo[PATH_MAX];
struct timespec ts;
int nloops = WAIT_MAX * (ONE_SECOND / WAIT_INTERVAL);
bool retval = false;
bool forever = false;
- char **keywords = NULL;
- int i;
-
- if (! service)
- return (false);
+ RC_STRINGLIST *keywords;
+ RC_STRING *s;
/* Some services don't have a timeout, like fsck */
- keywords = rc_deptree_depend (depinfo, svc, "keyword");
- STRLIST_FOREACH (keywords, s, i) {
- if (strcmp (s, "notimeout") == 0) {
- forever = true;
- break;
+ keywords = rc_deptree_depend(deptree, svc, "keyword");
+ if (keywords) {
+ TAILQ_FOREACH(s, keywords, entries) {
+ if (strcmp (s->value, "notimeout") == 0) {
+ forever = true;
+ break;
+ }
}
+ rc_stringlist_free (keywords);
}
- rc_strlist_free (keywords);
- fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename_c (svc), (char *) NULL);
+ snprintf(fifo, sizeof(fifo), RC_SVCDIR "/exclusive/%s", basename_c(svc));
ts.tv_sec = 0;
ts.tv_nsec = WAIT_INTERVAL;
while (nloops) {
- if (! exists (fifo)) {
+ if (! exists(fifo)) {
retval = true;
break;
}
- if (nanosleep (&ts, NULL) == -1) {
+ if (nanosleep(&ts, NULL) == -1) {
if (errno != EINTR)
break;
}
@@ -547,190 +545,211 @@ static bool svc_wait (rc_depinfo_t *depinfo, const char *svc)
nloops --;
}
- if (! exists (fifo))
+ if (! exists(fifo))
retval = true;
- free (fifo);
- return (retval);
+ return retval;
}
-static rc_service_state_t svc_status ()
+static RC_SERVICE svc_status(void)
{
char status[10];
int (*e) (const char *fmt, ...) = &einfo;
-
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_STOPPING) {
- snprintf (status, sizeof (status), "stopping");
+ snprintf(status, sizeof(status), "stopping");
e = &ewarn;
} else if (state & RC_SERVICE_STARTING) {
- snprintf (status, sizeof (status), "starting");
+ snprintf(status, sizeof(status), "starting");
e = &ewarn;
} else if (state & RC_SERVICE_INACTIVE) {
- snprintf (status, sizeof (status), "inactive");
+ snprintf(status, sizeof(status), "inactive");
e = &ewarn;
} else if (state & RC_SERVICE_STARTED) {
- if (geteuid () == 0 && rc_service_daemons_crashed (service)) {
- snprintf (status, sizeof (status), "crashed");
+ if (rc_service_daemons_crashed(service)) {
+ snprintf(status, sizeof (status), "crashed");
e = &eerror;
} else
- snprintf (status, sizeof (status), "started");
+ snprintf(status, sizeof(status), "started");
} else
- snprintf (status, sizeof (status), "stopped");
+ snprintf(status, sizeof(status), "stopped");
- e ("status: %s", status);
- return (state);
+ e("status: %s", status);
+ return state;
}
-static void make_exclusive ()
+static void make_exclusive(void)
{
char *path;
size_t l;
/* We create a fifo so that other services can wait until we complete */
if (! exclusive)
- exclusive = rc_strcatpaths (RC_SVCDIR, "exclusive", applet, (char *) NULL);
+ exclusive = rc_strcatpaths(RC_SVCDIR, "exclusive", applet, (char *) NULL);
- if (mkfifo (exclusive, 0600) != 0 && errno != EEXIST &&
+ if (mkfifo(exclusive, 0600) != 0 && errno != EEXIST &&
(errno != EACCES || geteuid () == 0))
eerrorx ("%s: unable to create fifo `%s': %s",
- applet, exclusive, strerror (errno));
+ applet, exclusive, strerror(errno));
- path = rc_strcatpaths (RC_SVCDIR, "exclusive", applet, (char *) NULL);
+ path = rc_strcatpaths(RC_SVCDIR, "exclusive", applet, (char *) NULL);
l = strlen (path) + 16;
- mtime_test = xmalloc (sizeof (char) * l);
- snprintf (mtime_test, l, "%s.%d", path, getpid ());
- free (path);
-
- if (exists (mtime_test) && unlink (mtime_test) != 0) {
- eerror ("%s: unlink `%s': %s",
- applet, mtime_test, strerror (errno));
- free (mtime_test);
+ mtime_test = xmalloc(sizeof (char) * l);
+ snprintf(mtime_test, l, "%s.%d", path, getpid());
+ free(path);
+
+ if (exists(mtime_test) && unlink(mtime_test) != 0) {
+ eerror("%s: unlink `%s': %s",
+ applet, mtime_test, strerror(errno));
+ free(mtime_test);
mtime_test = NULL;
return;
}
- if (symlink (service, mtime_test) != 0) {
- eerror ("%s: symlink `%s' to `%s': %s",
- applet, service, mtime_test, strerror (errno));
- free (mtime_test);
+ if (symlink(service, mtime_test) != 0) {
+ eerror("%s: symlink `%s' to `%s': %s",
+ applet, service, mtime_test, strerror(errno));
+ free(mtime_test);
mtime_test = NULL;
}
}
-static void unlink_mtime_test ()
+static void unlink_mtime_test(void)
{
- if (unlink (mtime_test) != 0)
- eerror ("%s: unlink `%s': %s", applet, mtime_test, strerror (errno));
- free (mtime_test);
+ if (unlink(mtime_test) != 0)
+ eerror("%s: unlink `%s': %s", applet, mtime_test, strerror(errno));
+ free(mtime_test);
mtime_test = NULL;
}
-static void get_started_services ()
+static void get_started_services(void)
+{
+ RC_STRINGLIST *tmp = rc_services_in_state(RC_SERVICE_INACTIVE);
+ rc_stringlist_free(restart_services);
+ restart_services = rc_services_in_state(RC_SERVICE_STARTED);
+ TAILQ_CONCAT(restart_services, tmp);
+ free(tmp);
+}
+
+static void setup_types(void)
{
- rc_strlist_free (tmplist);
- tmplist = rc_services_in_state (RC_SERVICE_INACTIVE);
- rc_strlist_free (restart_services);
- restart_services = rc_services_in_state (RC_SERVICE_STARTED);
- rc_strlist_join (&restart_services, tmplist);
- rc_strlist_free (tmplist);
- tmplist = NULL;
+ types_b = rc_stringlist_new();
+ rc_stringlist_add(types_b, "broken");
+
+ types_n = rc_stringlist_new();
+ rc_stringlist_add(types_n, "ineed");
+
+ types_nu = rc_stringlist_new();
+ rc_stringlist_add(types_nu, "ineed");
+ rc_stringlist_add(types_nu, "iuse");
+
+ types_nua = rc_stringlist_new();
+ rc_stringlist_add(types_nua, "ineed");
+ rc_stringlist_add(types_nua, "iuse");
+ rc_stringlist_add(types_nua, "iafter");
+
+ types_m = rc_stringlist_new();
+ rc_stringlist_add(types_m, "needsme");
+
+ types_mua = rc_stringlist_new();
+ rc_stringlist_add(types_mua, "needsme");
+ rc_stringlist_add(types_mua, "usesme");
+ rc_stringlist_add(types_mua, "beforeme");
}
-static void svc_start (bool deps)
+static void svc_start(bool deps)
{
bool started;
bool background = false;
- char *svc;
- char *svc2;
- int i;
- int j;
+ RC_STRING *svc;
+ RC_STRING *svc2;
int depoptions = RC_DEP_TRACE;
- rc_service_state_t state;
+ RC_SERVICE state;
+ bool first;
+ int n;
+ size_t len;
+ char *p;
+ char *tmp;
- state = rc_service_state (service);
+ state = rc_service_state(service);
- if (rc_yesno (getenv ("IN_HOTPLUG")) || in_background) {
+ if (rc_yesno(getenv("IN_HOTPLUG")) || in_background) {
if (! state & RC_SERVICE_INACTIVE &&
! state & RC_SERVICE_STOPPED)
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
background = true;
}
if (state & RC_SERVICE_STARTED) {
- ewarn ("WARNING: %s has already been started", applet);
+ ewarn("WARNING: %s has already been started", applet);
return;
} else if (state & RC_SERVICE_STARTING)
- ewarnx ("WARNING: %s is already starting", applet);
+ ewarnx("WARNING: %s is already starting", applet);
else if (state & RC_SERVICE_STOPPING)
- ewarnx ("WARNING: %s is stopping", applet);
+ ewarnx("WARNING: %s is stopping", applet);
else if (state & RC_SERVICE_INACTIVE && ! background)
- ewarnx ("WARNING: %s has already started, but is inactive", applet);
+ ewarnx("WARNING: %s has already started, but is inactive", applet);
- if (! rc_service_mark (service, RC_SERVICE_STARTING)) {
+ if (! rc_service_mark(service, RC_SERVICE_STARTING)) {
if (errno == EACCES)
- eerrorx ("%s: superuser access required", applet);
- eerrorx ("ERROR: %s has been started by something else", applet);
+ eerrorx("%s: superuser access required", applet);
+ eerrorx("ERROR: %s has been started by something else", applet);
}
- make_exclusive (service);
+ make_exclusive();
hook_out = RC_HOOK_SERVICE_START_OUT;
- rc_plugin_run (RC_HOOK_SERVICE_START_IN, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_IN, applet);
- if (rc_conf_yesno ("rc_depend_strict"))
+ if (rc_conf_yesno("rc_depend_strict"))
depoptions |= RC_DEP_STRICT;
if (deps) {
if (! deptree && ((deptree = _rc_deptree_load (NULL)) == NULL))
- eerrorx ("failed to load deptree");
+ eerrorx("failed to load deptree");
- rc_strlist_free (services);
- services = rc_deptree_depends (deptree, types_b,
- (const char * const *) applet_list,
- softlevel, 0);
- if (services) {
+ if (! types_b)
+ setup_types();
+
+ services = rc_deptree_depends(deptree, types_b, applet_list,
+ runlevel, 0);
+ if (TAILQ_FIRST(services)) {
eerrorn ("ERROR: `%s' needs ", applet);
- STRLIST_FOREACH (services, svc, i) {
- if (i > 0)
- fprintf (stderr, ", ");
- fprintf (stderr, "%s", svc);
+ first = true;
+ TAILQ_FOREACH(svc, services, entries) {
+ if (first)
+ first = false;
+ else
+ fprintf(stderr, ", ");
+ fprintf(stderr, "%s", svc->value);
}
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
- rc_strlist_free (services);
+ rc_stringlist_free(services);
services = NULL;
- rc_strlist_free (need_services);
- need_services = rc_deptree_depends (deptree, types_n,
- (const char * const *) applet_list,
- softlevel, depoptions);
-
- rc_strlist_free (use_services);
- use_services = rc_deptree_depends (deptree, types_nu,
- (const char * const *) applet_list,
- softlevel, depoptions);
-
- if (! rc_runlevel_starting ()) {
- STRLIST_FOREACH (use_services, svc, i)
- if (rc_service_state (svc) & RC_SERVICE_STOPPED) {
- pid_t pid = rc_service_start (svc);
- if (! rc_conf_yesno ("rc_parallel"))
- rc_waitpid (pid);
+ need_services = rc_deptree_depends(deptree, types_n, applet_list,
+ runlevel, depoptions);
+ use_services = rc_deptree_depends(deptree, types_nu, applet_list,
+ runlevel, depoptions);
+
+ if (! rc_runlevel_starting())
+ TAILQ_FOREACH(svc, use_services, entries)
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED) {
+ pid_t pid = rc_service_start(svc->value);
+ if (! rc_conf_yesno("rc_parallel"))
+ rc_waitpid(pid);
}
- }
/* Now wait for them to start */
- services = rc_deptree_depends (deptree, types_nua,
- (const char * const *) applet_list,
- softlevel, depoptions);
+ services = rc_deptree_depends(deptree, types_nua, applet_list,
+ runlevel, depoptions);
/* We use tmplist to hold our scheduled by list */
- rc_strlist_free (tmplist);
- tmplist = NULL;
+ tmplist = rc_stringlist_new();
- STRLIST_FOREACH (services, svc, i) {
- rc_service_state_t svcs = rc_service_state (svc);
+ TAILQ_FOREACH(svc, services, entries) {
+ RC_SERVICE svcs = rc_service_state(svc->value);
if (svcs & RC_SERVICE_STARTED)
continue;
@@ -738,270 +757,272 @@ static void svc_start (bool deps)
* starting state which we are after */
if (svcs & RC_SERVICE_STARTING &&
svcs & RC_SERVICE_WASINACTIVE) {
- bool use = false;
- STRLIST_FOREACH (use_services, svc2, j)
- if (strcmp (svc, svc2) == 0) {
- use = true;
+ TAILQ_FOREACH(svc2, use_services, entries) {
+ if (strcmp (svc->value, svc2->value) == 0)
break;
}
- if (! use)
+ if (! svc2)
continue;
}
- if (! svc_wait (deptree, svc))
- eerror ("%s: timed out waiting for %s", applet, svc);
- if ((svcs = rc_service_state (svc)) & RC_SERVICE_STARTED)
+ if (! svc_wait(svc->value))
+ eerror ("%s: timed out waiting for %s",
+ applet, svc->value);
+ if ((svcs = rc_service_state(svc->value)) & RC_SERVICE_STARTED)
continue;
-
- STRLIST_FOREACH (need_services, svc2, j)
- if (strcmp (svc, svc2) == 0) {
+ TAILQ_FOREACH(svc2, need_services, entries) {
+ if (strcmp (svc->value, svc2->value) == 0) {
if (svcs & RC_SERVICE_INACTIVE ||
svcs & RC_SERVICE_WASINACTIVE)
- rc_strlist_add (&tmplist, svc);
+ rc_stringlist_add(tmplist, svc->value);
else
- eerrorx ("ERROR: cannot start %s as %s would not start",
- applet, svc);
+ eerrorx("ERROR: cannot start %s as"
+ " %s would not start",
+ applet, svc->value);
}
+ }
}
- if (tmplist) {
- int n = 0;
- size_t len = 0;
- char *p;
-
+ if (TAILQ_FIRST(tmplist)) {
/* Set the state now, then unlink our exclusive so that
our scheduled list is preserved */
- rc_service_mark (service, RC_SERVICE_STOPPED);
- unlink_mtime_test ();
-
- STRLIST_FOREACH (tmplist, svc, i) {
- rc_service_schedule_start (svc, service);
- rc_strlist_free (providelist);
- providelist = rc_deptree_depend (deptree, "iprovide", svc);
- STRLIST_FOREACH (providelist, svc2, j)
- rc_service_schedule_start (svc2, service);
-
- len += strlen (svc) + 2;
+ rc_service_mark(service, RC_SERVICE_STOPPED);
+ unlink_mtime_test();
+
+ rc_stringlist_free(use_services);
+ use_services = NULL;
+ len = 0;
+ n = 0;
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ rc_service_schedule_start(svc->value, service);
+ use_services = rc_deptree_depend(deptree, "iprovide",
+ svc->value);
+ TAILQ_FOREACH (svc2, use_services, entries)
+ rc_service_schedule_start(svc2->value, service);
+ rc_stringlist_free(use_services);
+ use_services = NULL;
+ len += strlen(svc->value) + 2;
n++;
}
len += 5;
- tmp = xmalloc (sizeof (char) * len);
- p = tmp;
- STRLIST_FOREACH (tmplist, svc, i) {
- if (i > 1) {
- if (i == n)
- p += snprintf (p, len, " or ");
- else
- p += snprintf (p, len, ", ");
- }
- p += snprintf (p, len, "%s", svc);
+ tmp = p = xmalloc(sizeof(char) * len);
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ if (p != tmp)
+ p += snprintf(p, len, ", ");
+ p += snprintf(p, len, "%s", svc->value);
}
- ewarnx ("WARNING: %s is scheduled to start when %s has started",
- applet, tmp);
+ free(tmp);
+ ewarnx("WARNING: %s is scheduled to start when %s has started",
+ applet, tmp);
}
- rc_strlist_free (services);
+ rc_stringlist_free(services);
services = NULL;
+ rc_stringlist_free(tmplist);
+ tmplist = NULL;
}
if (ibsave)
- setenv ("IN_BACKGROUND", ibsave, 1);
+ setenv("IN_BACKGROUND", ibsave, 1);
hook_out = RC_HOOK_SERVICE_START_DONE;
- rc_plugin_run (RC_HOOK_SERVICE_START_NOW, applet);
- started = svc_exec ("start", NULL);
+ rc_plugin_run(RC_HOOK_SERVICE_START_NOW, applet);
+ started = svc_exec("start", NULL);
if (ibsave)
- unsetenv ("IN_BACKGROUND");
+ unsetenv("IN_BACKGROUND");
- if (in_control ()) {
+ if (in_control()) {
if (! started)
- eerrorx ("ERROR: %s failed to start", applet);
+ eerrorx("ERROR: %s failed to start", applet);
} else {
- if (rc_service_state (service) & RC_SERVICE_INACTIVE)
- ewarnx ("WARNING: %s has started, but is inactive", applet);
+ if (rc_service_state(service) & RC_SERVICE_INACTIVE)
+ ewarnx("WARNING: %s has started, but is inactive", applet);
else
- ewarnx ("WARNING: %s not under our control, aborting", applet);
+ ewarnx("WARNING: %s not under our control, aborting", applet);
}
- rc_service_mark (service, RC_SERVICE_STARTED);
- unlink_mtime_test ();
+ rc_service_mark(service, RC_SERVICE_STARTED);
+ unlink_mtime_test();
hook_out = RC_HOOK_SERVICE_START_OUT;
- rc_plugin_run (RC_HOOK_SERVICE_START_DONE, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_DONE, applet);
if (exclusive)
- unlink (exclusive);
+ unlink(exclusive);
/* Now start any scheduled services */
- rc_strlist_free (services);
- services = rc_services_scheduled (service);
- STRLIST_FOREACH (services, svc, i)
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
- rc_service_start (svc);
- rc_strlist_free (services);
- services = NULL;
+ services = rc_services_scheduled(service);
+ if (services) {
+ TAILQ_FOREACH(svc, services, entries)
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ rc_service_start(svc->value);
+ rc_stringlist_free(services);
+ services = NULL;
+ }
/* Do the same for any services we provide */
- rc_strlist_free (tmplist);
- tmplist = rc_deptree_depend (deptree, "iprovide", applet);
-
- STRLIST_FOREACH (tmplist, svc2, j) {
- rc_strlist_free (services);
- services = rc_services_scheduled (svc2);
- STRLIST_FOREACH (services, svc, i)
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
- rc_service_start (svc);
+ tmplist = rc_deptree_depend(deptree, "iprovide", applet);
+ if (tmplist) {
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ services = rc_services_scheduled(svc->value);
+ if (services) {
+ TAILQ_FOREACH(svc2, services, entries)
+ if (rc_service_state(svc2->value) & RC_SERVICE_STOPPED)
+ rc_service_start(svc2->value);
+ rc_stringlist_free(services);
+ services = NULL;
+ }
+ }
+ rc_stringlist_free(tmplist);
+ tmplist = NULL;
}
hook_out = 0;
- rc_plugin_run (RC_HOOK_SERVICE_START_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
}
-static void svc_stop (bool deps)
+static void svc_stop(bool deps)
{
bool stopped;
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
+ int depoptions = RC_DEP_TRACE;
+ RC_STRING *svc;
- if (rc_runlevel_stopping () &&
+ if (rc_runlevel_stopping() &&
state & RC_SERVICE_FAILED)
exit (EXIT_FAILURE);
- if (rc_yesno (getenv ("IN_HOTPLUG")) || in_background)
+ if (rc_yesno(getenv("IN_HOTPLUG")) || in_background)
if (! (state & RC_SERVICE_STARTED) &&
! (state & RC_SERVICE_INACTIVE))
exit (EXIT_FAILURE);
if (state & RC_SERVICE_STOPPED) {
- ewarn ("WARNING: %s is already stopped", applet);
+ ewarn("WARNING: %s is already stopped", applet);
return;
} else if (state & RC_SERVICE_STOPPING)
- ewarnx ("WARNING: %s is already stopping", applet);
+ ewarnx("WARNING: %s is already stopping", applet);
- if (! rc_service_mark (service, RC_SERVICE_STOPPING)) {
+ if (! rc_service_mark(service, RC_SERVICE_STOPPING)) {
if (errno == EACCES)
- eerrorx ("%s: superuser access required", applet);
- eerrorx ("ERROR: %s has been stopped by something else", applet);
+ eerrorx("%s: superuser access required", applet);
+ eerrorx("ERROR: %s has been stopped by something else", applet);
}
- make_exclusive (service);
+ make_exclusive();
hook_out = RC_HOOK_SERVICE_STOP_OUT;
- rc_plugin_run (RC_HOOK_SERVICE_STOP_IN, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_IN, applet);
- if (! rc_runlevel_stopping () &&
- rc_service_in_runlevel (service, RC_LEVEL_BOOT))
+ if (! rc_runlevel_stopping() &&
+ rc_service_in_runlevel(service, RC_LEVEL_BOOT))
ewarn ("WARNING: you are stopping a boot service");
if (deps && ! (state & RC_SERVICE_WASINACTIVE)) {
- int depoptions = RC_DEP_TRACE;
- char *svc;
- int i;
- if (rc_conf_yesno ("rc_depend_strict"))
+ if (rc_conf_yesno("rc_depend_strict"))
depoptions |= RC_DEP_STRICT;
- if (! deptree && ((deptree = _rc_deptree_load (NULL)) == NULL))
+ if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
eerrorx ("failed to load deptree");
- rc_strlist_free (tmplist);
- tmplist = NULL;
- rc_strlist_free (services);
- services = rc_deptree_depends (deptree, types_m,
- (const char * const *) applet_list,
- softlevel, depoptions);
- rc_strlist_reverse (services);
- STRLIST_FOREACH (services, svc, i) {
- rc_service_state_t svcs = rc_service_state (svc);
+ if (! types_m)
+ setup_types();
+
+ tmplist = rc_stringlist_new();
+ services = rc_deptree_depends(deptree, types_m, applet_list,
+ runlevel, depoptions);
+ TAILQ_FOREACH_REVERSE(svc, services, rc_stringlist, entries) {
+ RC_SERVICE svcs = rc_service_state(svc->value);
if (svcs & RC_SERVICE_STARTED ||
svcs & RC_SERVICE_INACTIVE)
{
- svc_wait (deptree, svc);
- svcs = rc_service_state (svc);
+ svc_wait(svc->value);
+ svcs = rc_service_state(svc->value);
if (svcs & RC_SERVICE_STARTED ||
svcs & RC_SERVICE_INACTIVE)
{
- pid_t pid = rc_service_stop (svc);
- if (! rc_conf_yesno ("rc_parallel"))
- rc_waitpid (pid);
- rc_strlist_add (&tmplist, svc);
+ pid_t pid = rc_service_stop(svc->value);
+ if (! rc_conf_yesno("rc_parallel"))
+ rc_waitpid(pid);
+ rc_stringlist_add(tmplist, svc->value);
}
}
}
- rc_strlist_free (services);
+ rc_stringlist_free(services);
services = NULL;
- STRLIST_FOREACH (tmplist, svc, i) {
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
continue;
/* We used to loop 3 times here - maybe re-do this if needed */
- svc_wait (deptree, svc);
- if (! (rc_service_state (svc) & RC_SERVICE_STOPPED)) {
- if (rc_runlevel_stopping ()) {
- /* If shutting down, we should stop even if a dependant failed */
- if (softlevel &&
- (strcmp (softlevel, RC_LEVEL_SHUTDOWN) == 0 ||
- strcmp (softlevel, RC_LEVEL_REBOOT) == 0 ||
- strcmp (softlevel, RC_LEVEL_SINGLE) == 0))
+ svc_wait(svc->value);
+ if (! (rc_service_state(svc->value) & RC_SERVICE_STOPPED)) {
+ if (rc_runlevel_stopping()) {
+ /* If shutting down, we should stop even
+ * if a dependant failed */
+ if (runlevel &&
+ (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
+ strcmp(runlevel, RC_LEVEL_REBOOT) == 0 ||
+ strcmp(runlevel, RC_LEVEL_SINGLE) == 0))
continue;
- rc_service_mark (service, RC_SERVICE_FAILED);
+ rc_service_mark(service, RC_SERVICE_FAILED);
}
- eerrorx ("ERROR: cannot stop %s as %s is still up",
- applet, svc);
+ eerrorx("ERROR: cannot stop %s as %s is still up",
+ applet, svc->value);
}
}
- rc_strlist_free (tmplist);
+ rc_stringlist_free(tmplist);
tmplist = NULL;
/* We now wait for other services that may use us and are stopping
This is important when a runlevel stops */
- services = rc_deptree_depends (deptree, types_mua,
- (const char * const *) applet_list,
- softlevel, depoptions);
- STRLIST_FOREACH (services, svc, i) {
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
+ services = rc_deptree_depends(deptree, types_mua, applet_list,
+ runlevel, depoptions);
+ TAILQ_FOREACH(svc, services, entries) {
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
continue;
- svc_wait (deptree, svc);
+ svc_wait(svc->value);
}
-
- rc_strlist_free (services);
+ rc_stringlist_free (services);
services = NULL;
}
/* If we're stopping localmount, set LC_ALL=C so that
* bash doesn't load anything blocking the unmounting of /usr */
- if (strcmp (applet, "localmount") == 0)
- setenv ("LC_ALL", "C", 1);
+ if (strcmp(applet, "localmount") == 0)
+ setenv("LC_ALL", "C", 1);
if (ibsave)
- setenv ("IN_BACKGROUND", ibsave, 1);
+ setenv("IN_BACKGROUND", ibsave, 1);
hook_out = RC_HOOK_SERVICE_STOP_DONE;
- rc_plugin_run (RC_HOOK_SERVICE_STOP_NOW, applet);
- stopped = svc_exec ("stop", NULL);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_NOW, applet);
+ stopped = svc_exec("stop", NULL);
if (ibsave)
- unsetenv ("IN_BACKGROUND");
+ unsetenv("IN_BACKGROUND");
- if (! in_control ())
- ewarnx ("WARNING: %s not under our control, aborting", applet);
+ if (! in_control())
+ ewarnx("WARNING: %s not under our control, aborting", applet);
if (! stopped)
- eerrorx ("ERROR: %s failed to stop", applet);
+ eerrorx("ERROR: %s failed to stop", applet);
if (in_background)
- rc_service_mark (service, RC_SERVICE_INACTIVE);
+ rc_service_mark(service, RC_SERVICE_INACTIVE);
else
- rc_service_mark (service, RC_SERVICE_STOPPED);
+ rc_service_mark(service, RC_SERVICE_STOPPED);
- unlink_mtime_test ();
+ unlink_mtime_test();
hook_out = RC_HOOK_SERVICE_STOP_OUT;
- rc_plugin_run (RC_HOOK_SERVICE_STOP_DONE, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_DONE, applet);
if (exclusive)
- unlink (exclusive);
+ unlink(exclusive);
hook_out = 0;
- rc_plugin_run (RC_HOOK_SERVICE_STOP_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
}
-static void svc_restart (bool deps)
+static void svc_restart(bool deps)
{
/* This is hairly and a better way needs to be found I think!
The issue is this - openvpn need net and dns. net can restart
@@ -1012,22 +1033,22 @@ static void svc_restart (bool deps)
our status is invalid.
One workaround would be to introduce a new status, or status locking. */
if (! deps) {
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_STARTED || state & RC_SERVICE_INACTIVE)
- svc_exec ("stop", "start");
+ svc_exec("stop", "start");
else
- svc_exec ("start", NULL);
+ svc_exec("start", NULL);
return;
}
- if (! (rc_service_state (service) & RC_SERVICE_STOPPED)) {
- get_started_services ();
- svc_stop (deps);
+ if (! (rc_service_state(service) & RC_SERVICE_STOPPED)) {
+ get_started_services();
+ svc_stop(deps);
}
- svc_start (deps);
- start_services (restart_services);
- rc_strlist_free (restart_services);
+ svc_start(deps);
+ start_services(restart_services);
+ rc_stringlist_free(restart_services);
restart_services = NULL;
}
@@ -1048,128 +1069,94 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int runscript (int argc, char **argv)
+int runscript(int argc, char **argv)
{
- size_t i;
bool deps = true;
bool doneone = false;
char pid[16];
int retval;
int opt;
- char *svc;
+ RC_STRING *svc;
+ char dir[PATH_MAX];
+ size_t l = 0;
+ size_t ll;
+ char *save;
+ int depoptions = RC_DEP_TRACE;
/* Show help if insufficient args */
- if (argc < 2 || ! exists (argv[1])) {
- fprintf (stderr, "runscript is not meant to be to run directly\n");
- exit (EXIT_FAILURE);
+ if (argc < 2 || ! exists(argv[1])) {
+ fprintf(stderr, "runscript is not meant to be to run directly\n");
+ exit(EXIT_FAILURE);
}
- applet = basename_c (argv[1]);
+ applet = basename_c(argv[1]);
if (argc < 3)
- usage (EXIT_FAILURE);
+ usage(EXIT_FAILURE);
if (*argv[1] == '/')
- service = xstrdup (argv[1]);
+ service = xstrdup(argv[1]);
else {
- char d[PATH_MAX];
- getcwd (d, sizeof (d));
- i = strlen (d) + strlen (argv[1]) + 2;
- service = xmalloc (sizeof (char) * i);
- snprintf (service, i, "%s/%s", d, argv[1]);
+ getcwd(dir, sizeof(dir));
+ l = strlen(dir) + strlen(argv[1]) + 2;
+ service = xmalloc(sizeof (char) * l);
+ snprintf(service, l, "%s/%s", dir, argv[1]);
}
- atexit (cleanup);
+ atexit(cleanup);
/* Change dir to / to ensure all init scripts don't use stuff in pwd */
- chdir ("/");
+ chdir("/");
#ifdef __linux__
/* coldplug events can trigger init scripts, but we don't want to run them
until after rc sysinit has completed so we punt them to the boot runlevel */
- if (exists ("/dev/.rcsysinit")) {
- eerror ("%s: cannot run until sysvinit completes", applet);
- if (mkdir ("/dev/.rcboot", 0755) != 0 && errno != EEXIST)
- eerrorx ("%s: mkdir `/dev/.rcboot': %s", applet, strerror (errno));
- tmp = rc_strcatpaths ("/dev/.rcboot", applet, (char *) NULL);
- symlink (service, tmp);
+ if (exists("/dev/.rcsysinit")) {
+ eerror("%s: cannot run until sysvinit completes", applet);
+ if (mkdir("/dev/.rcboot", 0755) != 0 && errno != EEXIST)
+ eerrorx("%s: mkdir `/dev/.rcboot': %s", applet, strerror(errno));
+ prefix = rc_strcatpaths("/dev/.rcboot", applet, (char *) NULL);
+ symlink(service, prefix);
exit (EXIT_FAILURE);
}
#endif
- if ((softlevel = xstrdup (getenv ("RC_SOFTLEVEL"))) == NULL) {
- /* Ensure our environment is pure
- Also, add our configuration to it */
- char *p;
- env = env_filter ();
-
- if (env) {
-
-#ifdef __linux__
- /* clearenv isn't portable, but there's no harm in using it
- if we have it */
- clearenv ();
-#else
- char *var;
- /* No clearenv present here then.
- We could manipulate environ directly ourselves, but it seems that
- some kernels bitch about this according to the environ man pages
- so we walk though environ and call unsetenv for each value. */
- while (environ[0]) {
- tmp = xstrdup (environ[0]);
- p = tmp;
- var = strsep (&p, "=");
- unsetenv (var);
- free (tmp);
- }
- tmp = NULL;
-#endif
- }
-
- tmplist = env_config ();
- rc_strlist_join (&env, tmplist);
- rc_strlist_free (tmplist);
- tmplist = NULL;
- STRLIST_FOREACH (env, p, i)
- putenv (p);
- /* We don't free our list as that would be null in environ */
-
- softlevel = rc_runlevel_get ();
+ if ((runlevel = xstrdup (getenv ("RC_RUNLEVEL"))) == NULL) {
+ env_filter();
+ env_config();
+ runlevel = rc_runlevel_get();
}
- setenv ("EINFO_LOG", service, 1);
- setenv ("SVCNAME", applet, 1);
+ setenv("EINFO_LOG", service, 1);
+ setenv("SVCNAME", applet, 1);
/* Set an env var so that we always know our pid regardless of any
subshells the init script may create so that our mark_service_*
functions can always instruct us of this change */
- snprintf (pid, sizeof (pid), "%d", (int) getpid ());
- setenv ("RC_RUNSCRIPT_PID", pid, 1);
+ snprintf(pid, sizeof(pid), "%d", (int) getpid());
+ setenv("RC_RUNSCRIPT_PID", pid, 1);
/* eprefix is kinda klunky, but it works for our purposes */
- if (rc_conf_yesno ("rc_parallel")) {
- size_t l = 0;
- size_t ll;
-
+ if (rc_conf_yesno("rc_parallel")) {
/* Get the longest service name */
- services = rc_services_in_runlevel (NULL);
- STRLIST_FOREACH (services, svc, i) {
- ll = strlen (svc);
+ services = rc_services_in_runlevel(NULL);
+ TAILQ_FOREACH(svc, services, entries) {
+ ll = strlen(svc->value);
if (ll > l)
l = ll;
}
/* Make our prefix string */
- prefix = xmalloc (sizeof (char) * l + 1);
- ll = strlen (applet);
- memcpy (prefix, applet, ll);
- memset (prefix + ll, ' ', l - ll);
- memset (prefix + l, 0, 1);
- eprefix (prefix);
+ prefix = xmalloc(sizeof(char) * l + 1);
+ ll = strlen(applet);
+ memcpy(prefix, applet, ll);
+ memset(prefix + ll, ' ', l - ll);
+ memset(prefix + l, 0, 1);
+ eprefix(prefix);
}
#ifdef __linux__
/* Ok, we are ready to go, so setup selinux if applicable */
- setup_selinux (argc, argv);
+ setup_selinux(argc, argv);
#endif
/* Punt the first arg as it's our service name */
@@ -1177,44 +1164,46 @@ int runscript (int argc, char **argv)
argv++;
/* Right then, parse any options there may be */
- while ((opt = getopt_long (argc, argv, getoptstring,
- longopts, (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, getoptstring, longopts, (int *) 0)) != -1)
switch (opt) {
- case 'd':
- setenv ("RC_DEBUG", "yes", 1);
- break;
- case 's':
- if (! (rc_service_state (service) & RC_SERVICE_STARTED))
- exit (EXIT_FAILURE);
- break;
- case 'D':
- deps = false;
- break;
- case_RC_COMMON_GETOPT
- }
+ case 'd':
+ setenv("RC_DEBUG", "yes", 1);
+ break;
+ case 's':
+ if (! (rc_service_state(service) & RC_SERVICE_STARTED))
+ exit(EXIT_FAILURE);
+ break;
+ case 'D':
+ deps = false;
+ break;
+ case_RC_COMMON_GETOPT
+ }
/* Save the IN_BACKGROUND env flag so it's ONLY passed to the service
that is being called and not any dependents */
- if (getenv ("IN_BACKGROUND")) {
- ibsave = xstrdup (getenv ("IN_BACKGROUND"));
- in_background = rc_yesno (ibsave);
- unsetenv ("IN_BACKGROUND");
+ if (getenv("IN_BACKGROUND")) {
+ ibsave = xstrdup(getenv("IN_BACKGROUND"));
+ in_background = rc_yesno(ibsave);
+ unsetenv("IN_BACKGROUND");
}
- if (rc_yesno (getenv ("IN_HOTPLUG"))) {
- if (! rc_conf_yesno ("rc_hotplug") || ! service_plugable (applet))
- eerrorx ("%s: not allowed to be hotplugged", applet);
+ if (rc_yesno(getenv("IN_HOTPLUG"))) {
+ if (! rc_conf_yesno("rc_hotplug") || ! service_plugable(applet))
+ eerrorx("%s: not allowed to be hotplugged", applet);
}
/* Setup a signal handler */
- signal_setup (SIGHUP, handle_signal);
- signal_setup (SIGINT, handle_signal);
- signal_setup (SIGQUIT, handle_signal);
- signal_setup (SIGTERM, handle_signal);
- signal_setup (SIGCHLD, handle_signal);
+ signal_setup(SIGHUP, handle_signal);
+ signal_setup(SIGINT, handle_signal);
+ signal_setup(SIGQUIT, handle_signal);
+ signal_setup(SIGTERM, handle_signal);
+ signal_setup(SIGCHLD, handle_signal);
/* Load our plugins */
- rc_plugin_load ();
+ rc_plugin_load();
+
+ applet_list = rc_stringlist_new();
+ rc_stringlist_add(applet_list, applet);
/* Now run each option */
retval = EXIT_SUCCESS;
@@ -1229,99 +1218,95 @@ int runscript (int argc, char **argv)
This is important as we stamp on the restart function now but
some start/stop routines still need to behave differently if
restarting. */
- unsetenv ("RC_CMD");
- setenv ("RC_CMD", optarg, 1);
+ unsetenv("RC_CMD");
+ setenv("RC_CMD", optarg, 1);
doneone = true;
- rc_strlist_add (&applet_list, applet);
if (strcmp (optarg, "describe") == 0 ||
strcmp (optarg, "help") == 0)
{
- char *save = prefix;
-
- eprefix (NULL);
+ save = prefix;
+ eprefix(NULL);
prefix = NULL;
- svc_exec (optarg, NULL);
- eprefix (save);
- } else if (strcmp (optarg, "ineed") == 0 ||
- strcmp (optarg, "iuse") == 0 ||
- strcmp (optarg, "needsme") == 0 ||
- strcmp (optarg, "usesme") == 0 ||
- strcmp (optarg, "iafter") == 0 ||
- strcmp (optarg, "ibefore") == 0 ||
- strcmp (optarg, "iprovide") == 0)
+ svc_exec(optarg, NULL);
+ eprefix(save);
+ } else if (strcmp(optarg, "ineed") == 0 ||
+ strcmp(optarg, "iuse") == 0 ||
+ strcmp(optarg, "needsme") == 0 ||
+ strcmp(optarg, "usesme") == 0 ||
+ strcmp(optarg, "iafter") == 0 ||
+ strcmp(optarg, "ibefore") == 0 ||
+ strcmp(optarg, "iprovide") == 0)
{
- int depoptions = RC_DEP_TRACE;
-
- if (rc_conf_yesno ("rc_depend_strict"))
+ if (rc_conf_yesno("rc_depend_strict"))
depoptions |= RC_DEP_STRICT;
- if (! deptree && ((deptree = _rc_deptree_load (NULL)) == NULL))
- eerrorx ("failed to load deptree");
-
- rc_strlist_free (services);
- rc_strlist_free (tmplist);
- rc_strlist_add (&tmplist, optarg);
- services = rc_deptree_depends (deptree,
- (const char * const *) tmplist,
- (const char * const *) applet_list,
- softlevel, depoptions);
- STRLIST_FOREACH (services, svc, i)
- printf ("%s%s", i == 1 ? "" : " ", svc);
- if (services)
+ if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
+ eerrorx("failed to load deptree");
+
+ tmplist = rc_stringlist_new();
+ rc_stringlist_add(tmplist, optarg);
+ services = rc_deptree_depends(deptree, tmplist, applet_list,
+ runlevel, depoptions);
+ rc_stringlist_free(tmplist);
+ tmplist = NULL;
+ TAILQ_FOREACH(svc, services, entries)
+ printf("%s ", svc->value);
+ if (TAILQ_FIRST(services))
printf ("\n");
+ rc_stringlist_free(services);
+ services = NULL;
} else if (strcmp (optarg, "status") == 0) {
- rc_service_state_t r = svc_status (service);
+ RC_SERVICE r = svc_status();
retval = (int) r;
if (retval & RC_SERVICE_STARTED)
retval = 0;
} else {
- if (strcmp (optarg, "conditionalrestart") == 0 ||
- strcmp (optarg, "condrestart") == 0)
+ if (strcmp(optarg, "conditionalrestart") == 0 ||
+ strcmp(optarg, "condrestart") == 0)
{
- if (rc_service_state (service) & RC_SERVICE_STARTED)
- svc_restart (deps);
- } else if (strcmp (optarg, "restart") == 0) {
+ if (rc_service_state(service) & RC_SERVICE_STARTED)
+ svc_restart(deps);
+ } else if (strcmp(optarg, "restart") == 0) {
svc_restart (deps);
- } else if (strcmp (optarg, "start") == 0) {
- svc_start (deps);
- } else if (strcmp (optarg, "stop") == 0) {
+ } else if (strcmp(optarg, "start") == 0) {
+ svc_start(deps);
+ } else if (strcmp(optarg, "stop") == 0) {
if (deps && in_background)
- get_started_services ();
+ get_started_services();
- svc_stop (deps);
+ svc_stop(deps);
if (deps) {
if (! in_background &&
- ! rc_runlevel_stopping () &&
- rc_service_state (service) & RC_SERVICE_STOPPED)
- uncoldplug ();
+ ! rc_runlevel_stopping() &&
+ rc_service_state(service) & RC_SERVICE_STOPPED)
+ uncoldplug();
if (in_background &&
- rc_service_state (service) & RC_SERVICE_INACTIVE)
+ rc_service_state(service) & RC_SERVICE_INACTIVE)
{
- int j;
- STRLIST_FOREACH (restart_services, svc, j)
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
- rc_service_schedule_start (service, svc);
+ TAILQ_FOREACH(svc, restart_services, entries)
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ rc_service_schedule_start(service, svc->value);
}
}
- } else if (strcmp (optarg, "zap") == 0) {
- einfo ("Manually resetting %s to stopped state", applet);
- rc_service_mark (applet, RC_SERVICE_STOPPED);
- uncoldplug ();
+ } else if (strcmp(optarg, "zap") == 0) {
+ einfo("Manually resetting %s to stopped state", applet);
+ rc_service_mark(applet, RC_SERVICE_STOPPED);
+ uncoldplug();
} else
- svc_exec (optarg, NULL);
+ svc_exec(optarg, NULL);
/* We should ensure this list is empty after an action is done */
- rc_strlist_free (restart_services);
+ rc_stringlist_free(restart_services);
restart_services = NULL;
}
if (! doneone)
- usage (EXIT_FAILURE);
+ usage(EXIT_FAILURE);
}
- return (retval);
+ return retval;
}