diff options
Diffstat (limited to 'src/rc/rc-misc.c')
| -rw-r--r-- | src/rc/rc-misc.c | 107 | 
1 files changed, 107 insertions, 0 deletions
diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c index f2f4d9f0..6dfa4235 100644 --- a/src/rc/rc-misc.c +++ b/src/rc/rc-misc.c @@ -23,6 +23,7 @@  #  include <sys/sysinfo.h>  #endif +#include <sys/time.h>  #include <ctype.h>  #include <fcntl.h>  #include <limits.h> @@ -31,7 +32,9 @@  #include <stdio.h>  #include <stdlib.h>  #include <string.h> +#include <time.h>  #include <unistd.h> +#include <utime.h>  #include "einfo.h"  #include "queue.h" @@ -488,3 +491,107 @@ const char *detect_vm(void)  	return NULL;  } + +RC_DEPTREE * _rc_deptree_load(int force, int *regen) +{ +	int fd; +	int retval; +	int serrno = errno; +	int merrno; +	time_t t; +	char file[PATH_MAX]; +	struct stat st; +	struct utimbuf ut; +	FILE *fp; + +	t = 0; +	if (rc_deptree_update_needed(&t, file) || force != 0) { +		/* Test if we have permission to update the deptree */ +		fd = open(RC_DEPTREE_CACHE, O_WRONLY); +		merrno = errno; +		errno = serrno; +		if (fd == -1 && merrno == EACCES) +			return rc_deptree_load(); +		close(fd); + +		if (regen) +			*regen = 1; +		ebegin("Caching service dependencies"); +		retval = rc_deptree_update() ? 0 : -1; +		eend (retval, "Failed to update the dependency tree"); + +		if (retval == 0) { +			stat(RC_DEPTREE_CACHE, &st); +			if (st.st_mtime < t) { +				eerror("Clock skew detected with `%s'", file); +				eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE +				    "' to %s", ctime(&t)); +				fp = fopen(RC_DEPTREE_SKEWED, "w"); +				if (fp != NULL) { +					fprintf(fp, "%s\n", file); +					fclose(fp); +				} +				ut.actime = t; +				ut.modtime = t; +				utime(RC_DEPTREE_CACHE, &ut); +			} else { +				if (exists(RC_DEPTREE_SKEWED)) +					unlink(RC_DEPTREE_SKEWED); +			} +		} +		if (force == -1 && regen != NULL) +			*regen = retval; +	} +	return rc_deptree_load(); +} + +bool _rc_can_find_pids(void) +{ +	RC_PIDLIST *pids; +	RC_PID *pid; +	RC_PID *pid2; +	bool retval = false; + +	if (geteuid() == 0) +		return true; + +	/* If we cannot see process 1, then we don't test to see if +	 * services crashed or not */ +	pids = rc_find_pids(NULL, NULL, 0, 1); +	if (pids) { +		pid = LIST_FIRST(pids); +		if (pid) { +			retval = true; +			while (pid) { +				pid2 = LIST_NEXT(pid, entries); +				free(pid); +				pid = pid2; +			} +		} +		free(pids); +	} +	return retval; +} + +static const struct { +	const char * const name; +	RC_SERVICE bit; +} service_bits[] = { +	{ "service_started",     RC_SERVICE_STARTED,     }, +	{ "service_stopped",     RC_SERVICE_STOPPED,     }, +	{ "service_inactive",    RC_SERVICE_INACTIVE,    }, +	{ "service_starting",    RC_SERVICE_STARTING,    }, +	{ "service_stopping",    RC_SERVICE_STOPPING,    }, +	{ "service_hotplugged",  RC_SERVICE_HOTPLUGGED,  }, +	{ "service_wasinactive", RC_SERVICE_WASINACTIVE, }, +	{ "service_failed",      RC_SERVICE_FAILED,      }, +}; + +RC_SERVICE lookup_service_state(const char *service) +{ +	size_t i; +	for (i = 0; i < ARRAY_SIZE(service_bits); ++i) +		if (!strcmp(service, service_bits[i].name)) +			return service_bits[i].bit; +	return 0; +}  | 
