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