aboutsummaryrefslogtreecommitdiff
path: root/src/rc/rc-misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rc/rc-misc.c')
-rw-r--r--src/rc/rc-misc.c107
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;
+}