summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-04-09 22:56:32 +0000
committerRoy Marples <roy@marples.name>2008-04-09 22:56:32 +0000
commit0e38dcc4d2e9c6f56bf02ff660f63526a942027d (patch)
tree0700ac5511494b0e8a862f60660ccb99de23f688
parent9176b77c2383f3a70f842b82dbdd4ab59f7c9bd3 (diff)
downloadopenrc-0e38dcc4d2e9c6f56bf02ff660f63526a942027d.tar.gz
openrc-0e38dcc4d2e9c6f56bf02ff660f63526a942027d.tar.bz2
openrc-0e38dcc4d2e9c6f56bf02ff660f63526a942027d.tar.xz
By default, rc-status now shows the statuses of the services in the current runlevel and any unassigned non stopped services, #52.
-rw-r--r--man/rc-status.85
-rw-r--r--src/rc/rc-status.c121
2 files changed, 84 insertions, 42 deletions
diff --git a/man/rc-status.8 b/man/rc-status.8
index 0d4d9cc..c84b3dc 100644
--- a/man/rc-status.8
+++ b/man/rc-status.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Feb 22, 2008
+.Dd Arp 9, 2008
.Dt RC-STATUS 8 SMM
.Os OpenRC
.Sh NAME
@@ -36,7 +36,8 @@
.Nm
gathers and displays information about the status of services
in different runlevels. The default behavior is to show information
-about the current runlevel, but any runlevel can be quickly examined.
+about the current runlevel and any unassgined services that are not stopped,
+but any runlevel can be quickly examined.
.Pp
The options are as follows:
.Bl -tag -width ".Fl test , test string"
diff --git a/src/rc/rc-status.c b/src/rc/rc-status.c
index 7f040d3..f79d339 100644
--- a/src/rc/rc-status.c
+++ b/src/rc/rc-status.c
@@ -42,7 +42,8 @@
extern const char *applet;
static bool test_crashed = false;
-static const char *const types_nua[] = { "ineed", "iuse", "iafter", NULL };
+static RC_DEPTREE *deptree = NULL;
+static RC_STRINGLIST *types = NULL;
bool _rc_can_find_pids(void)
{
@@ -73,7 +74,7 @@ bool _rc_can_find_pids(void)
return retval;
}
-static void print_level(char *level)
+static void print_level(const char *level)
{
printf ("Runlevel: ");
if (isatty(fileno(stdout)))
@@ -120,6 +121,46 @@ static void print_service(const char *service)
ebracket(cols, color, status);
}
+static void print_services(const char *runlevel, RC_STRINGLIST *services)
+{
+ RC_STRINGLIST *l = NULL;
+ RC_STRING *s, *t;
+ char *r = NULL;
+
+ if (! services)
+ return;
+ if (! deptree)
+ deptree = _rc_deptree_load(NULL);
+ if (! deptree) {
+ TAILQ_FOREACH(s, services, entries)
+ if (!runlevel ||
+ rc_service_in_runlevel(s->value, runlevel))
+ print_service(s->value);
+ return;
+ }
+ if (! types) {
+ types = rc_stringlist_new();
+ rc_stringlist_add(types, "ineed");
+ rc_stringlist_add(types, "iuse");
+ rc_stringlist_add(types, "iafter");
+ }
+ if (!runlevel)
+ r = rc_runlevel_get();
+ l = rc_deptree_depends(deptree, types, services, r ? r : runlevel,
+ RC_DEP_STRICT | RC_DEP_TRACE | RC_DEP_START);
+ free(r);
+ TAILQ_FOREACH(s, l, entries) {
+ TAILQ_FOREACH(t, services, entries)
+ if (strcmp(t->value, s->value) == 0)
+ break;
+ if (!t)
+ continue;
+ if (!runlevel || rc_service_in_runlevel(s->value, runlevel))
+ print_service(s->value);
+ }
+ rc_stringlist_free(l);
+}
+
#include "_usage.h"
#define extraopts "[runlevel1] [runlevel2] ..."
#define getoptstring "alrsu" getoptstring_COMMON
@@ -143,16 +184,11 @@ static const char * const longopts_help[] = {
int rc_status(int argc, char **argv)
{
- RC_DEPTREE *deptree = NULL;
RC_STRINGLIST *levels = NULL;
RC_STRINGLIST *services;
- RC_STRINGLIST *types = NULL;
- RC_STRINGLIST *ordered;
- RC_STRING *s;
- RC_STRING *l;
+ RC_STRING *s, *l, *t;
char *p;
int opt;
- int depopts = RC_DEP_STRICT | RC_DEP_START | RC_DEP_TRACE;
test_crashed = _rc_can_find_pids();
@@ -166,35 +202,33 @@ int rc_status(int argc, char **argv)
levels = rc_runlevel_list();
TAILQ_FOREACH (l, levels, entries)
printf("%s\n", l->value);
- rc_stringlist_free(levels);
- exit(EXIT_SUCCESS);
+ goto exit;
/* NOTREACHED */
case 'r':
- p = rc_runlevel_get ();
+ p = rc_runlevel_get();
printf("%s\n", p);
free(p);
- exit(EXIT_SUCCESS);
+ goto exit;
/* NOTREACHED */
case 's':
services = rc_services_in_runlevel(NULL);
- TAILQ_FOREACH(s, services, entries)
- print_service(s->value);
- rc_stringlist_free(services);
- exit (EXIT_SUCCESS);
+ print_services(NULL, services);
+ goto exit;
/* NOTREACHED */
case 'u':
services = rc_services_in_runlevel(NULL);
levels = rc_runlevel_list();
- TAILQ_FOREACH(s, services, entries) {
+ TAILQ_FOREACH_SAFE(s, services, entries, t) {
TAILQ_FOREACH(l, levels, entries)
- if (rc_service_in_runlevel(s->value, l->value))
+ if (rc_service_in_runlevel(s->value, l->value)) {
+ TAILQ_REMOVE(services, s, entries);
+ free(s->value);
+ free(s);
break;
- if (! l)
- print_service(s->value);
+ }
}
- rc_stringlist_free(levels);
- rc_stringlist_free(services);
- exit (EXIT_SUCCESS);
+ print_services(NULL, services);
+ goto exit;
/* NOTREACHED */
case_RC_COMMON_GETOPT
@@ -216,27 +250,34 @@ int rc_status(int argc, char **argv)
TAILQ_FOREACH(l, levels, entries) {
print_level(l->value);
services = rc_services_in_runlevel(l->value);
- if (! services)
- continue;
- if (deptree) {
- if (! types) {
- types = rc_stringlist_new();
- rc_stringlist_add(types, "ineed");
- rc_stringlist_add(types, "iuse");
- rc_stringlist_add(types, "iafter");
+ print_services(l->value, services);
+ rc_stringlist_free(services);
+ services = NULL;
+ }
+
+ /* Show unassigned running too */
+ if (argc < 2) {
+ print_level("UNASSIGNED");
+ services = rc_services_in_runlevel(NULL);
+ rc_stringlist_free(levels);
+ levels = rc_runlevel_list();
+ TAILQ_FOREACH_SAFE(s, services, entries, t) {
+ TAILQ_FOREACH(l, levels, entries) {
+ if (rc_service_in_runlevel(s->value, l->value) ||
+ rc_service_state(s->value) & RC_SERVICE_STOPPED)
+ {
+ TAILQ_REMOVE(services, s, entries);
+ free(s->value);
+ free(s);
+ break;
+ }
}
- ordered = rc_deptree_depends(deptree, types, services,
- l->value, depopts);
- rc_stringlist_free(services);
- services = ordered;
- ordered = NULL;
}
- TAILQ_FOREACH(s, services, entries)
- if (rc_service_in_runlevel(s->value, l->value))
- print_service(s->value);
- rc_stringlist_free(services);
+ print_services(NULL, services);
}
+exit:
+ rc_stringlist_free(services);
rc_stringlist_free(types);
rc_stringlist_free(levels);
rc_deptree_free(deptree);