From 7274301be24a70c094e8c91a36f3e8b6156f53ba Mon Sep 17 00:00:00 2001
From: Roy Marples <roy@marples.name>
Date: Fri, 28 Sep 2007 14:53:38 +0000
Subject: rc_service_state now returns the state as a mask, which means that we
 can do things with just the one call making is more efficient.

---
 src/librc-depend.c |  17 ++++---
 src/librc.c        |  64 ++++++++++++-------------
 src/rc-status.c    |  13 ++---
 src/rc.c           |  20 ++++----
 src/rc.h           |  25 +++++-----
 src/runscript.c    | 137 +++++++++++++++++++++++++----------------------------
 6 files changed, 135 insertions(+), 141 deletions(-)

(limited to 'src')

diff --git a/src/librc-depend.c b/src/librc-depend.c
index 4bab21cd..4a3c10e2 100644
--- a/src/librc-depend.c
+++ b/src/librc-depend.c
@@ -184,11 +184,13 @@ librc_hidden_def(rc_get_deptype)
 
 static bool valid_service (const char *runlevel, const char *service)
 {
+	rc_service_state_t state = rc_service_state (service);
+
 	return ((strcmp (runlevel, bootlevel) != 0 &&
 			 rc_service_in_runlevel (service, bootlevel)) ||
 			rc_service_in_runlevel (service, runlevel) ||
-			rc_service_state (service, RC_SERVICE_COLDPLUGGED) ||
-			rc_service_state (service, RC_SERVICE_STARTED));
+			state & RC_SERVICE_COLDPLUGGED ||
+			state & RC_SERVICE_STARTED);
 }
 
 static bool get_provided1 (const char *runlevel, struct lhead *providers,
@@ -203,10 +205,11 @@ static bool get_provided1 (const char *runlevel, struct lhead *providers,
 	STRLIST_FOREACH (deptype->services, service, i)
 	{
 		bool ok = true;
+		rc_service_state_t s = rc_service_state (service);
 		if (level)
 			ok = rc_service_in_runlevel (service, level);
 		else if (coldplugged)
-			ok = (rc_service_state (service, RC_SERVICE_COLDPLUGGED) &&
+			ok = (s & RC_SERVICE_COLDPLUGGED &&
 				  ! rc_service_in_runlevel (service, runlevel) &&
 				  ! rc_service_in_runlevel (service, bootlevel));
 
@@ -215,14 +218,14 @@ static bool get_provided1 (const char *runlevel, struct lhead *providers,
 
 		switch (state) {
 			case RC_SERVICE_STARTED:
-				ok = rc_service_state (service, state);
+				ok = (s & RC_SERVICE_STARTED);
 				break;
 			case RC_SERVICE_INACTIVE:
 			case RC_SERVICE_STARTING:
 			case RC_SERVICE_STOPPING:
-				ok = (rc_service_state (service, RC_SERVICE_STARTING) ||
-					  rc_service_state (service, RC_SERVICE_STOPPING) ||
-					  rc_service_state (service, RC_SERVICE_INACTIVE));
+				ok = (s & RC_SERVICE_STARTING ||
+					  s & RC_SERVICE_STOPPING ||
+					  s & RC_SERVICE_INACTIVE);
 				break;
 			default:
 				break;
diff --git a/src/librc.c b/src/librc.c
index 366c7c49..f3495cbe 100644
--- a/src/librc.c
+++ b/src/librc.c
@@ -23,6 +23,8 @@ typedef struct rc_service_state_name {
 	const char *name;
 } rc_service_state_name_t;
 
+/* We MUST list the states below 0x10 first
+ * The rest can be in any order */
 static const rc_service_state_name_t rc_service_state_names[] = {
 	{ RC_SERVICE_STARTED,     "started" },
 	{ RC_SERVICE_STOPPED,     "stopped" },
@@ -428,43 +430,39 @@ bool rc_mark_service (const char *service, const rc_service_state_t state)
 }
 librc_hidden_def(rc_mark_service)
 
-bool rc_service_state (const char *service, const rc_service_state_t state)
+rc_service_state_t rc_service_state (const char *service)
 {
-	char *file;
-	bool retval;
-	char *svc;
+	int i;
+	int state = RC_SERVICE_STOPPED;
+	char *svc = rc_xstrdup (service);
 
-	/* If the init script does not exist then we are stopped */
-	if (! rc_service_exists (service))
-		return (state == RC_SERVICE_STOPPED ? true : false);
-
-	/* We check stopped state by not being in any of the others */
-	if (state == RC_SERVICE_STOPPED)
-		return ( ! (rc_service_state (service, RC_SERVICE_STARTED) ||
-					rc_service_state (service, RC_SERVICE_STARTING) ||
-					rc_service_state (service, RC_SERVICE_STOPPING) ||
-					rc_service_state (service, RC_SERVICE_INACTIVE)));
-
-	/* The crashed state and scheduled states are virtual */
-	if (state == RC_SERVICE_CRASHED)
-		return (rc_service_daemons_crashed (service));
-	else if (state == RC_SERVICE_SCHEDULED) {
+	for (i = 0; rc_service_state_names[i].name; i++) {
+		char *file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[i].name,
+									 basename (svc), (char*) NULL);
+		if (rc_exists (file)) {
+			if (rc_service_state_names[i].state <= 0x10)
+				state = rc_service_state_names[i].state;
+			else
+				state |= rc_service_state_names[i].state;
+		}
+		free (file);
+	}
+	free (svc);
+
+	if (state & RC_SERVICE_STOPPED) {
 		char **services = rc_services_scheduled_by (service);
-		retval = (services);
-		if (services)
+		if (services) {
+			state |= RC_SERVICE_SCHEDULED;
 			free (services);
-		return (retval);
+		}
 	}
 
-	/* Now we just check if a file by the service name rc_exists
-	   in the state dir */
-	svc = rc_xstrdup (service);
-	file = rc_strcatpaths (RC_SVCDIR, rc_parse_service_state (state),
-						   basename (svc), (char*) NULL);
-	free (svc);
-	retval = rc_exists (file);
-	free (file);
-	return (retval);
+	if (state & RC_SERVICE_STARTED && geteuid () == 0) {
+		if (rc_service_daemons_crashed (service))
+			state |= RC_SERVICE_CRASHED;
+	}
+
+	return (state);
 }
 librc_hidden_def(rc_service_state)
 
@@ -585,7 +583,7 @@ librc_hidden_def(rc_waitpid)
 
 pid_t rc_stop_service (const char *service)
 {
-	if (rc_service_state (service, RC_SERVICE_STOPPED))
+	if (rc_service_state (service) & RC_SERVICE_STOPPED)
 		return (0);
 
 	return (_exec_service (service, "stop"));
@@ -594,7 +592,7 @@ librc_hidden_def(rc_stop_service)
 
 pid_t rc_start_service (const char *service)
 {
-	if (! rc_service_state (service, RC_SERVICE_STOPPED))
+	if (! rc_service_state (service) & RC_SERVICE_STOPPED)
 		return (0);
 
 	return (_exec_service (service, "start"));
diff --git a/src/rc-status.c b/src/rc-status.c
index be0f23ab..dacbe851 100644
--- a/src/rc-status.c
+++ b/src/rc-status.c
@@ -31,22 +31,23 @@ static void print_service (char *service)
 {
 	char status[10];
 	int cols =  printf (" %s\n", service);
+	rc_service_state_t state = rc_service_state (service);
 	einfo_color_t color = ECOLOR_BAD;
 
-	if (rc_service_state (service, RC_SERVICE_STOPPING))
+	if (state & RC_SERVICE_STOPPING)
 		snprintf (status, sizeof (status),   "stopping ");
-	else if (rc_service_state (service, RC_SERVICE_STARTING)) {
+	else if (state & RC_SERVICE_STARTING) {
 		snprintf (status, sizeof (status), "starting ");
 		color = ECOLOR_WARN;
-	} else if (rc_service_state (service, RC_SERVICE_INACTIVE)) {
+	} else if (state & RC_SERVICE_INACTIVE) {
 		snprintf (status, sizeof (status), "inactive ");
 		color = ECOLOR_WARN;
-	} else if (geteuid () == 0 && rc_service_state (service, RC_SERVICE_CRASHED))
+	} else if (state & RC_SERVICE_CRASHED)
 		snprintf (status, sizeof (status),   " crashed ");
-	else if (rc_service_state (service, RC_SERVICE_STARTED)) {
+	else if (state & RC_SERVICE_STARTED) {
 		snprintf (status, sizeof (status), " started ");
 		color = ECOLOR_GOOD;
-	} else if (rc_service_state (service, RC_SERVICE_SCHEDULED)) {
+	} else if (state & RC_SERVICE_SCHEDULED) {
 		snprintf (status, sizeof (status), "scheduled");
 		color = ECOLOR_WARN;
 	} else
diff --git a/src/rc.c b/src/rc.c
index 9d3206dd..3fb708f0 100644
--- a/src/rc.c
+++ b/src/rc.c
@@ -269,19 +269,19 @@ static int do_service (int argc, char **argv)
 		eerrorx ("%s: no service specified", applet);
 
 	if (strcmp (applet, "service_started") == 0)
-		ok = rc_service_state (argv[0], RC_SERVICE_STARTED);
+		ok = (rc_service_state (argv[0]) & RC_SERVICE_STARTED);
 	else if (strcmp (applet, "service_stopped") == 0)
-		ok = rc_service_state (argv[0], RC_SERVICE_STOPPED);
+		ok = (rc_service_state (argv[0]) & RC_SERVICE_STOPPED);
 	else if (strcmp (applet, "service_inactive") == 0)
-		ok = rc_service_state (argv[0], RC_SERVICE_INACTIVE);
+		ok = (rc_service_state (argv[0]) & RC_SERVICE_INACTIVE);
 	else if (strcmp (applet, "service_starting") == 0)
-		ok = rc_service_state (argv[0], RC_SERVICE_STOPPING);
+		ok = (rc_service_state (argv[0]) & RC_SERVICE_STOPPING);
 	else if (strcmp (applet, "service_stopping") == 0)
-		ok = rc_service_state (argv[0], RC_SERVICE_STOPPING);
+		ok = (rc_service_state (argv[0]) & RC_SERVICE_STOPPING);
 	else if (strcmp (applet, "service_coldplugged") == 0)
-		ok = rc_service_state (argv[0], RC_SERVICE_COLDPLUGGED);
+		ok = (rc_service_state (argv[0]) & RC_SERVICE_COLDPLUGGED);
 	else if (strcmp (applet, "service_wasinactive") == 0)
-		ok = rc_service_state (argv[0], RC_SERVICE_WASINACTIVE);
+		ok = (rc_service_state (argv[0]) & RC_SERVICE_WASINACTIVE);
 	else if (strcmp (applet, "service_started_daemon") == 0) {
 		int idx = 0;
 		if (argc > 2)
@@ -1180,7 +1180,7 @@ int main (int argc, char **argv)
 		char *svc2 = NULL;
 		int k;
 
-		if (rc_service_state (service, RC_SERVICE_STOPPED))
+		if (rc_service_state (service) & RC_SERVICE_STOPPED)
 			continue;
 
 		/* We always stop the service when in these runlevels */
@@ -1224,7 +1224,7 @@ int main (int argc, char **argv)
 			}
 		} else {
 			/* Allow coldplugged services not to be in the runlevels list */
-			if (rc_service_state (service, RC_SERVICE_COLDPLUGGED))
+			if (rc_service_state (service) & RC_SERVICE_COLDPLUGGED)
 				continue;
 		}
 
@@ -1324,7 +1324,7 @@ int main (int argc, char **argv)
 
 
 	STRLIST_FOREACH (start_services, service, i) {
-		if (rc_service_state (service, RC_SERVICE_STOPPED))	{
+		if (rc_service_state (service) & RC_SERVICE_STOPPED)	{
 			pid_t pid;
 
 			if (! interactive)
diff --git a/src/rc.h b/src/rc.h
index b9c79c21..78b3df62 100644
--- a/src/rc.h
+++ b/src/rc.h
@@ -44,22 +44,22 @@ typedef enum
 {
 	/* These are actual states
 	 * The service has to be in one only at all times */
-	RC_SERVICE_STARTED     = 0x0001,
-	RC_SERVICE_STOPPED     = 0x0002,
-	RC_SERVICE_STARTING    = 0x0003,
+	RC_SERVICE_STOPPED     = 0x0001,
+	RC_SERVICE_STARTED     = 0x0002,
 	RC_SERVICE_STOPPING    = 0x0004,
-	RC_SERVICE_INACTIVE    = 0x0005,
+	RC_SERVICE_STARTING    = 0x0008,
+	RC_SERVICE_INACTIVE    = 0x0010,
 
 	/* Service may or may not have been coldplugged */
-	RC_SERVICE_COLDPLUGGED = 0x0010,
+	RC_SERVICE_COLDPLUGGED = 0x0100,
 
 	/* Optional states service could also be in */
-	RC_SERVICE_FAILED      = 0x0100,
-	RC_SERVICE_SCHEDULED   = 0x0101,
-	RC_SERVICE_WASINACTIVE = 0x0102,
+	RC_SERVICE_FAILED      = 0x0200,
+	RC_SERVICE_SCHEDULED   = 0x0400,
+	RC_SERVICE_WASINACTIVE = 0x0800,
 
-	/* Regardless of state, service may have crashed daemons */
-	RC_SERVICE_CRASHED     = 0x1000
+ 	/* Regardless of state, service may have crashed daemons */
+ 	RC_SERVICE_CRASHED     = 0x1000
 } rc_service_state_t;
 
 /*! Resolves a service name to its full path.
@@ -90,9 +90,8 @@ bool rc_service_in_runlevel (const char *service, const char *runlevel);
 
 /*! Checks if a service in in a state
  * @param service to check
- * @param state service should be in
- * @return true if service is in the requested state, otherwise false */
-bool rc_service_state (const char *service, rc_service_state_t state);
+ * @return state of the service */
+rc_service_state_t rc_service_state (const char *service);
 
 /*! Marks the service state
  * @param service to mark
diff --git a/src/runscript.c b/src/runscript.c
index e8e6d484..dfe41850 100644
--- a/src/runscript.c
+++ b/src/runscript.c
@@ -189,7 +189,7 @@ static bool in_control ()
 	if (! mtime_test || ! rc_exists (mtime_test))
 		return (false);
 
-	if (rc_service_state (applet, RC_SERVICE_STOPPED))
+	if (rc_service_state (applet) & RC_SERVICE_STOPPED)
 		return (false);
 
 	if (! (mtime = get_mtime (mtime_test, false)))
@@ -220,24 +220,23 @@ static void uncoldplug ()
 }
 
 static void start_services (char **list) {
-	bool inactive;
 	char *svc;
 	int i;
+	rc_service_state_t state = rc_service_state (service);
 
 	if (! list)
 		return;
 
-	inactive = rc_service_state (service, RC_SERVICE_INACTIVE);
-	if (! inactive)
-		inactive = rc_service_state (service, RC_SERVICE_WASINACTIVE);
-
-	if (inactive ||
-		rc_service_state (service, RC_SERVICE_STARTING) ||
-		rc_service_state (service, RC_SERVICE_STARTED))
+	if ((state & RC_SERVICE_INACTIVE ||
+		 state & RC_SERVICE_WASINACTIVE) &&
+		((state & RC_SERVICE_STARTING) ||
+		 (state & RC_SERVICE_STARTED)))
 	{
 		STRLIST_FOREACH (list, svc, i) {
-			if (rc_service_state (svc, RC_SERVICE_STOPPED)) {
-				if (inactive) {
+			if (rc_service_state (svc) & RC_SERVICE_STOPPED) {
+				if (state & RC_SERVICE_INACTIVE ||
+					state & RC_SERVICE_WASINACTIVE)
+				{
 					rc_schedule_start_service (service, svc);
 					ewarn ("WARNING: %s is scheduled to started when %s has started",
 						   svc, applet);
@@ -272,25 +271,19 @@ static void cleanup (void)
 	free (ibsave);
 
 	if (! rc_in_plugin && in_control ()) {
-		if (rc_service_state (applet, RC_SERVICE_STOPPING)) {
+		rc_service_state_t state = rc_service_state (applet);
+		if (state & RC_SERVICE_STOPPING) {
 			/* If the we're shutting down, do it cleanly */
 			if ((softlevel &&
 				 rc_runlevel_stopping () &&
 				 (strcmp (softlevel, RC_LEVEL_SHUTDOWN) == 0 ||
 				  strcmp (softlevel, RC_LEVEL_REBOOT) == 0)))
 				rc_mark_service (applet, RC_SERVICE_STOPPED);
-			else if (rc_service_state (applet, RC_SERVICE_WASINACTIVE))
+			else if (state & RC_SERVICE_WASINACTIVE)
 				rc_mark_service (applet, RC_SERVICE_INACTIVE);
 			else
 				rc_mark_service (applet, RC_SERVICE_STARTED);
 		}
-		else if (rc_service_state (applet, RC_SERVICE_STOPPING))
-		{
-			if (rc_service_state (applet, RC_SERVICE_WASINACTIVE))
-				rc_mark_service (applet, RC_SERVICE_INACTIVE);
-			else 
-				rc_mark_service (applet, RC_SERVICE_STOPPED);
-		}
 		if (exclusive && rc_exists (exclusive))
 			unlink (exclusive);
 	}
@@ -455,32 +448,27 @@ static rc_service_state_t svc_status ()
 	char status[10];
 	int (*e) (const char *fmt, ...) = &einfo;
 
-	rc_service_state_t retval = RC_SERVICE_STOPPED;
+	rc_service_state_t state = rc_service_state (service);
 
-	if (rc_service_state (service, RC_SERVICE_STOPPING)) {
+	if (state & RC_SERVICE_STOPPING) {
 		snprintf (status, sizeof (status), "stopping");
 		e = &ewarn;
-		retval = RC_SERVICE_STOPPING;
-	} else if (rc_service_state (service, RC_SERVICE_STOPPING)) {
+	} else if (state & RC_SERVICE_STOPPING) {
 		snprintf (status, sizeof (status), "starting");
 		e = &ewarn;
-		retval = RC_SERVICE_STOPPING;
-	} else if (rc_service_state (service, RC_SERVICE_INACTIVE)) {
+	} else if (state & RC_SERVICE_INACTIVE) {
 		snprintf (status, sizeof (status), "inactive");
 		e = &ewarn;
-		retval = RC_SERVICE_INACTIVE;
-	} else if (rc_service_state (service, RC_SERVICE_CRASHED)) {
+	} else if (state & RC_SERVICE_CRASHED) {
 		snprintf (status, sizeof (status), "crashed");
 		e = &eerror;
-		retval = RC_SERVICE_CRASHED;
-	} else if (rc_service_state (service, RC_SERVICE_STARTED)) {
+	} else if (state & RC_SERVICE_STARTED) {
 		snprintf (status, sizeof (status), "started");
-		retval = RC_SERVICE_STARTED;
 	} else
 		snprintf (status, sizeof (status), "stopped");
 
 	e ("status: %s", status);
-	return (retval);
+	return (state);
 }
 
 static void make_exclusive ()
@@ -554,25 +542,27 @@ static void svc_start (bool deps)
 	int i;
 	int j;
 	int depoptions = RC_DEP_TRACE;
+	rc_service_state_t state;
 
 	rc_plugin_run (RC_HOOK_SERVICE_START_IN, applet);
 	hook_out = RC_HOOK_SERVICE_START_OUT;
+	state = rc_service_state (service);
 
 	if (rc_env_bool ("IN_HOTPLUG") || in_background) {
-		if (! rc_service_state (service, RC_SERVICE_INACTIVE) &&
-			! rc_service_state (service, RC_SERVICE_STOPPED))
+		if (! state & RC_SERVICE_INACTIVE &&
+			! state & RC_SERVICE_STOPPED)
 			exit (EXIT_FAILURE);
 		background = true;
 	}
 
-	if (rc_service_state (service, RC_SERVICE_STARTED)) {
+	if (state & RC_SERVICE_STARTED) {
 		ewarn ("WARNING: %s has already been started", applet);
 		return;
-	} else if (rc_service_state (service, RC_SERVICE_STOPPING))
+	} else if (state & RC_SERVICE_STOPPING)
 		ewarnx ("WARNING: %s is already starting", applet);
-	else if (rc_service_state (service, RC_SERVICE_STOPPING))
+	else if (state & RC_SERVICE_STOPPING)
 		ewarnx ("WARNING: %s is stopping", applet);
-	else if (rc_service_state (service, RC_SERVICE_INACTIVE) && ! background)
+	else if (state & RC_SERVICE_INACTIVE && ! background)
 		ewarnx ("WARNING: %s has already started, but is inactive", applet);
 
 	if (! rc_mark_service (service, RC_SERVICE_STOPPING))
@@ -624,7 +614,7 @@ static void svc_start (bool deps)
 
 		if (! rc_runlevel_starting ()) {
 			STRLIST_FOREACH (use_services, svc, i)
-				if (rc_service_state (svc, RC_SERVICE_STOPPED)) {
+				if (rc_service_state (svc) & RC_SERVICE_STOPPED) {
 					pid_t pid = rc_start_service (svc);
 					if (! rc_env_bool ("RC_PARALLEL"))
 						rc_waitpid (pid);
@@ -641,13 +631,14 @@ static void svc_start (bool deps)
 		tmplist = NULL;
 
 		STRLIST_FOREACH (services, svc, i) {
-			if (rc_service_state (svc, RC_SERVICE_STARTED))
+			rc_service_state_t svcs = rc_service_state (svc);
+			if (svcs & RC_SERVICE_STARTED)
 				continue;
 
 			/* Don't wait for services which went inactive but are now in
 			 * starting state which we are after */
-			if (rc_service_state (svc, RC_SERVICE_STOPPING) &&
-				rc_service_state(svc, RC_SERVICE_WASINACTIVE)) {
+			if (svcs & RC_SERVICE_STOPPING &&
+				svcs & RC_SERVICE_WASINACTIVE) {
 				bool use = false;
 				STRLIST_FOREACH (use_services, svc2, j)
 					if (strcmp (svc, svc2) == 0) {
@@ -660,13 +651,13 @@ static void svc_start (bool deps)
 			
 			if (! rc_wait_service (svc))
 				eerror ("%s: timed out waiting for %s", applet, svc);
-			if (rc_service_state (svc, RC_SERVICE_STARTED))
+			if ((svcs = rc_service_state (svc)) & RC_SERVICE_STARTED)
 				continue;
 
 			STRLIST_FOREACH (need_services, svc2, j)
 				if (strcmp (svc, svc2) == 0) {
-					if (rc_service_state (svc, RC_SERVICE_INACTIVE) ||
-						rc_service_state (svc, RC_SERVICE_WASINACTIVE))
+					if (svcs & RC_SERVICE_INACTIVE ||
+						svcs & RC_SERVICE_WASINACTIVE)
 						rc_strlist_add (&tmplist, svc);
 					else
 						eerrorx ("ERROR: cannot start %s as %s would not start",
@@ -736,7 +727,7 @@ static void svc_start (bool deps)
 
 	if (in_control ()) {
 		if (! started) {
-			if (rc_service_state (service, RC_SERVICE_WASINACTIVE))
+			if (rc_service_state (service) & RC_SERVICE_WASINACTIVE)
 				rc_mark_service (service, RC_SERVICE_INACTIVE);
 			else {
 				rc_mark_service (service, RC_SERVICE_STOPPED);
@@ -751,7 +742,7 @@ static void svc_start (bool deps)
 		rc_plugin_run (RC_HOOK_SERVICE_START_DONE, applet);
 	} else {
 		rc_plugin_run (RC_HOOK_SERVICE_START_DONE, applet);
-		if (rc_service_state (service, RC_SERVICE_INACTIVE))
+		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);
@@ -761,7 +752,7 @@ static void svc_start (bool deps)
 	rc_strlist_free (services);
 	services = rc_services_scheduled (service);
 	STRLIST_FOREACH (services, svc, i)
-		if (rc_service_state (svc, RC_SERVICE_STOPPED))
+		if (rc_service_state (svc) & RC_SERVICE_STOPPED)
 			rc_start_service (svc);
 	rc_strlist_free (services);
 	services = NULL;
@@ -780,7 +771,7 @@ static void svc_start (bool deps)
 		rc_strlist_free (services);
 		services = rc_services_scheduled (svc2);
 		STRLIST_FOREACH (services, svc, i)
-			if (rc_service_state (svc, RC_SERVICE_STOPPED))
+			if (rc_service_state (svc) & RC_SERVICE_STOPPED)
 				rc_start_service (svc);
 	}
 
@@ -791,22 +782,23 @@ static void svc_start (bool deps)
 static void svc_stop (bool deps)
 {
 	bool stopped;
+	rc_service_state_t state = rc_service_state (service);
 
 	hook_out = RC_HOOK_SERVICE_STOP_OUT;
 
 	if (rc_runlevel_stopping () &&
-		rc_service_state (service, RC_SERVICE_FAILED))
+		state & RC_SERVICE_FAILED)
 		exit (EXIT_FAILURE);
 
 	if (rc_env_bool ("IN_HOTPLUG") || in_background)
-		if (! rc_service_state (service, RC_SERVICE_STARTED) && 
-			! rc_service_state (service, RC_SERVICE_INACTIVE))
+		if (! (state & RC_SERVICE_STARTED) && 
+			! (state & RC_SERVICE_INACTIVE))
 			exit (EXIT_FAILURE);
 
-	if (rc_service_state (service, RC_SERVICE_STOPPED)) {
+	if (state & RC_SERVICE_STOPPED) {
 		ewarn ("WARNING: %s is already stopped", applet);
 		return;
-	} else if (rc_service_state (service, RC_SERVICE_STOPPING))
+	} else if (state & RC_SERVICE_STOPPING)
 		ewarnx ("WARNING: %s is already stopping", applet);
 
 	if (! rc_mark_service (service, RC_SERVICE_STOPPING))
@@ -818,7 +810,7 @@ static void svc_stop (bool deps)
 		rc_service_in_runlevel (service, RC_LEVEL_BOOT))
 		ewarn ("WARNING: you are stopping a boot service");
 
-	if (deps && ! rc_service_state (service, RC_SERVICE_WASINACTIVE)) {
+	if (deps && ! (state & RC_SERVICE_WASINACTIVE)) {
 		int depoptions = RC_DEP_TRACE;
 		char *svc;
 		int i;
@@ -845,12 +837,14 @@ static void svc_stop (bool deps)
 								   softlevel, depoptions);
 		rc_strlist_reverse (services);
 		STRLIST_FOREACH (services, svc, i) {
-			if (rc_service_state (svc, RC_SERVICE_STARTED) || 
-				rc_service_state (svc, RC_SERVICE_INACTIVE))
+			rc_service_state_t svcs = rc_service_state (svc);
+			if (svcs & RC_SERVICE_STARTED || 
+				svcs & RC_SERVICE_INACTIVE)
 			{
 				rc_wait_service (svc);
-				if (rc_service_state (svc, RC_SERVICE_STARTED) || 
-					rc_service_state (svc, RC_SERVICE_INACTIVE))
+				svcs = rc_service_state (svc);
+				if (svcs & RC_SERVICE_STARTED || 
+					svcs & RC_SERVICE_INACTIVE)
 				{
 					pid_t pid = rc_stop_service (svc);
 					if (! rc_env_bool ("RC_PARALLEL"))
@@ -863,13 +857,12 @@ static void svc_stop (bool deps)
 		services = NULL;
 
 		STRLIST_FOREACH (tmplist, svc, i) {
-			if (rc_service_state (svc, RC_SERVICE_STOPPED))
+			if (rc_service_state (svc) & RC_SERVICE_STOPPED)
 				continue;
 
 			/* We used to loop 3 times here - maybe re-do this if needed */
 			rc_wait_service (svc);
-			if (! rc_service_state (svc, RC_SERVICE_STOPPED)) {
-
+			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 &&
@@ -894,7 +887,7 @@ static void svc_stop (bool deps)
 		services = rc_get_depends (deptree, types, svclist,
 								   softlevel, depoptions);
 		STRLIST_FOREACH (services, svc, i) {
-			if (rc_service_state (svc, RC_SERVICE_STOPPED))
+			if (rc_service_state (svc) & RC_SERVICE_STOPPED)
 				continue;
 			rc_wait_service (svc);
 		}
@@ -918,7 +911,7 @@ static void svc_stop (bool deps)
 	}
 
 	if (! stopped) {
-		if (rc_service_state (service, RC_SERVICE_WASINACTIVE))
+		if (rc_service_state (service) &  RC_SERVICE_WASINACTIVE)
 			rc_mark_service (service, RC_SERVICE_INACTIVE);
 		else
 			rc_mark_service (service, RC_SERVICE_STARTED);
@@ -948,15 +941,15 @@ static void svc_restart (bool deps)
 	   our status is invalid.
 	   One workaround would be to introduce a new status, or status locking. */
 	if (! deps) {
-		if (rc_service_state (service, RC_SERVICE_STARTED) ||
-			rc_service_state (service, RC_SERVICE_INACTIVE))
+		rc_service_state_t state = rc_service_state (service);
+		if (state & RC_SERVICE_STARTED || state & RC_SERVICE_INACTIVE)
 			svc_exec ("stop", "start");
 		else
 			svc_exec ("start", NULL);
 		return;
 	}
 
-	if (! rc_service_state (service, RC_SERVICE_STOPPED)) {
+	if (! (rc_service_state (service) & RC_SERVICE_STOPPED)) {
 		get_started_services ();
 		svc_stop (deps);
 	}
@@ -1122,7 +1115,7 @@ int runscript (int argc, char **argv)
 				setenv ("RC_DEBUG", "yes", 1);
 				break;
 			case 's':
-				if (! rc_service_state (service, RC_SERVICE_STARTED))
+				if (! (rc_service_state (service) & RC_SERVICE_STARTED))
 					exit (EXIT_FAILURE);
 				break;
 			case 'D':
@@ -1226,7 +1219,7 @@ int runscript (int argc, char **argv)
 			if (strcmp (optarg, "conditionalrestart") == 0 ||
 				strcmp (optarg, "condrestart") == 0)
 			{
-				if (rc_service_state (service, RC_SERVICE_STARTED))
+				if (rc_service_state (service) & RC_SERVICE_STARTED)
 					svc_restart (deps);
 			} else if (strcmp (optarg, "restart") == 0) {
 				svc_restart (deps);
@@ -1241,15 +1234,15 @@ int runscript (int argc, char **argv)
 				if (deps) {
 					if (! in_background &&
 						! rc_runlevel_stopping () &&
-						rc_service_state (service, RC_SERVICE_STOPPED))
+						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))
+							if (rc_service_state (svc) & RC_SERVICE_STOPPED)
 								rc_schedule_start_service (service, svc);
 					}
 				}
-- 
cgit v1.2.3