By default, rc-status now shows the statuses of the services in the current runlevel and any unassigned non stopped services, #52.
This commit is contained in:
		@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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");
 | 
			
		||||
			}
 | 
			
		||||
			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);
 | 
			
		||||
		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;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		print_services(NULL, services);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
exit:
 | 
			
		||||
	rc_stringlist_free(services);
 | 
			
		||||
	rc_stringlist_free(types);
 | 
			
		||||
	rc_stringlist_free(levels);
 | 
			
		||||
	rc_deptree_free(deptree);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user