diff options
Diffstat (limited to 'src/librc')
-rw-r--r-- | src/librc/librc.c | 70 | ||||
-rw-r--r-- | src/librc/librc.h | 4 | ||||
-rw-r--r-- | src/librc/rc.h.in | 21 | ||||
-rw-r--r-- | src/librc/rc.map | 4 |
4 files changed, 97 insertions, 2 deletions
diff --git a/src/librc/librc.c b/src/librc/librc.c index 05c1c3d0..f73936d9 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -66,7 +66,7 @@ static const rc_service_state_name_t rc_service_state_names[] = { }; #define LS_INITD 0x01 -#define LS_DIR 0x02 +#define LS_DIR 0x02 static RC_STRINGLIST * ls_dir(const char *dir, int options) { @@ -102,7 +102,7 @@ ls_dir(const char *dir, int options) } if (options & LS_DIR) { if (stat(d->d_name, &buf) == 0 && - ! S_ISDIR(buf.st_mode)) + !S_ISDIR(buf.st_mode)) continue; } rc_stringlist_add(list, d->d_name); @@ -330,6 +330,51 @@ rc_runlevel_exists(const char *runlevel) } librc_hidden_def(rc_runlevel_exists) +bool +rc_runlevel_stack(const char *dst, const char *src) +{ + char d[PATH_MAX], s[PATH_MAX]; + + if (!rc_runlevel_exists(dst) || !rc_runlevel_exists(src)) + return false; + snprintf(s, sizeof(s), "../%s", src); + snprintf(d, sizeof(s), "%s/%s/%s", RC_RUNLEVELDIR, dst, src); + return (symlink(s, d) == 0 ? true : false); +} +librc_hidden_def(rc_runlevel_stack) + +bool +rc_runlevel_unstack(const char *dst, const char *src) +{ + char path[PATH_MAX]; + + snprintf(path, sizeof(path), "%s/%s/%s", RC_RUNLEVELDIR, dst, src); + return (unlink(path) == 0 ? true : false); +} +librc_hidden_def(rc_runlevel_unstack) + +RC_STRINGLIST * +rc_runlevel_stacks(const char *runlevel) +{ + char path[PATH_MAX]; + RC_STRINGLIST *dirs; + RC_STRING *d, *dn; + + if (!runlevel) + return false; + snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel); + dirs = ls_dir(path, LS_DIR); + TAILQ_FOREACH_SAFE(d, dirs, entries, dn) { + if (!rc_runlevel_exists(d->value)) { + TAILQ_REMOVE(dirs, d, entries); + free(d->value); + free(d); + } + } + return dirs; +} +librc_hidden_def(rc_runlevel_stacks) + /* Resolve a service name to it's full path */ char * rc_service_resolve(const char *service) @@ -781,6 +826,27 @@ rc_services_in_runlevel(const char *runlevel) librc_hidden_def(rc_services_in_runlevel) RC_STRINGLIST * +rc_services_in_runlevel_stacked(const char *runlevel) +{ + RC_STRINGLIST *list, *stacks, *sl; + RC_STRING *stack; + + list = rc_services_in_runlevel(runlevel); + stacks = rc_runlevel_stacks(runlevel); + TAILQ_FOREACH (stack, stacks, entries) { + sl = rc_services_in_runlevel(stack->value); + if (list != NULL) { + TAILQ_CONCAT(list, sl, entries); + free(sl); + } else + list = sl; + } + return list; +} +librc_hidden_def(rc_services_in_runlevel_stacked) + + +RC_STRINGLIST * rc_services_in_state(RC_SERVICE state) { RC_STRINGLIST *services; diff --git a/src/librc/librc.h b/src/librc/librc.h index ba7da315..d2501c06 100644 --- a/src/librc/librc.h +++ b/src/librc/librc.h @@ -91,8 +91,11 @@ librc_hidden_proto(rc_runlevel_exists) librc_hidden_proto(rc_runlevel_get) librc_hidden_proto(rc_runlevel_list) librc_hidden_proto(rc_runlevel_set) +librc_hidden_proto(rc_runlevel_stack) +librc_hidden_proto(rc_runlevel_stacks) librc_hidden_proto(rc_runlevel_starting) librc_hidden_proto(rc_runlevel_stopping) +librc_hidden_proto(rc_runlevel_unstack) librc_hidden_proto(rc_service_add) librc_hidden_proto(rc_service_daemons_crashed) librc_hidden_proto(rc_service_daemon_set) @@ -106,6 +109,7 @@ librc_hidden_proto(rc_service_resolve) librc_hidden_proto(rc_service_schedule_clear) librc_hidden_proto(rc_service_schedule_start) librc_hidden_proto(rc_services_in_runlevel) +librc_hidden_proto(rc_services_in_runlevel_stacked) librc_hidden_proto(rc_services_in_state) librc_hidden_proto(rc_services_scheduled) librc_hidden_proto(rc_services_scheduled_by) diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in index 82874156..cb5258c5 100644 --- a/src/librc/rc.h.in +++ b/src/librc/rc.h.in @@ -80,6 +80,22 @@ char *rc_runlevel_get(void); * @return true if the runlevel exists, otherwise false */ bool rc_runlevel_exists(const char *); +/*! Stack a runlevel onto another + * @param runlevel to stack onto + * @param runlevel being stacked + * @return true if successful, otherwise false */ +bool rc_runlevel_stack(const char *, const char *); + +/*! Unstack a runlevel from another + * @param runlevel to unstack from + * @param runlevel being unstacked + * @return true if successful, otherwise false */ +bool rc_runlevel_unstack(const char *, const char *); + +/*! Return a NULL terminated list of runlevel stacks in the runlevels + * @return a NULL terminated list of runlevels */ +RC_STRINGLIST *rc_runlevel_stacks(const char *); + /*! Return a NULL terminated list of runlevels * @return a NULL terminated list of runlevels */ RC_STRINGLIST *rc_runlevel_list(void); @@ -225,6 +241,11 @@ bool rc_service_value_set(const char *, const char *, const char *); * @return NULL terminated list of services */ RC_STRINGLIST *rc_services_in_runlevel(const char *); +/*! List the stacked services in a runlevel + * @param runlevel to list + * @return NULL terminated list of services */ +RC_STRINGLIST *rc_services_in_runlevel_stacked(const char *); + /*! List the services in a state * @param state to list * @return NULL terminated list of services */ diff --git a/src/librc/rc.map b/src/librc/rc.map index e9fed69b..7cfbfabc 100644 --- a/src/librc/rc.map +++ b/src/librc/rc.map @@ -18,8 +18,11 @@ global: rc_runlevel_get; rc_runlevel_list; rc_runlevel_set; + rc_runlevel_stack; + rc_runlevel_stacks; rc_runlevel_starting; rc_runlevel_stopping; + rc_runlevel_unstack; rc_service_add; rc_service_daemons_crashed; rc_service_daemon_set; @@ -34,6 +37,7 @@ global: rc_service_schedule_clear; rc_service_schedule_start; rc_services_in_runlevel; + rc_services_in_runlevel_stacked; rc_services_in_state; rc_services_scheduled; rc_services_scheduled_by; |