about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-08-15 15:16:50 -0400
committerJune McEnroe <june@causal.agency>2020-08-15 15:16:50 -0400
commitb7e36c72a604796209f7f7b11d88aa3b75c1b44f (patch)
tree5e0198c4a6ef0688d6db2e086e8a8f3ed4c2dcb3
parentRead service pipes (diff)
downloadcatsit-b7e36c72a604796209f7f7b11d88aa3b75c1b44f.tar.gz
catsit-b7e36c72a604796209f7f7b11d88aa3b75c1b44f.zip
Parse control commands
-rw-r--r--daemon.c53
-rw-r--r--daemon.h3
2 files changed, 53 insertions, 3 deletions
diff --git a/daemon.c b/daemon.c
index c759f20..13098af 100644
--- a/daemon.c
+++ b/daemon.c
@@ -17,6 +17,7 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <fnmatch.h>
 #include <grp.h>
 #include <poll.h>
 #include <pwd.h>
@@ -27,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/wait.h>
@@ -115,6 +117,50 @@ err:
 	fclose(file);
 }
 
+typedef void Action(struct Service *service);
+static void parseControl(char *command) {
+	char *action = strsep(&command, WS);
+	if (!command) {
+		syslog(LOG_NOTICE, "no service names for %s", action);
+		return;
+	}
+
+	Action *fn = NULL;
+	int signal = 0;
+	if (!strcmp(action, "start")) {
+		fn = serviceStart;
+	} else if (!strcmp(action, "stop")) {
+		fn = serviceStop;
+	} else if (!strcmp(action, "restart")) {
+		fn = serviceRestart;
+	} else if (!strcmp(action, "status")) {
+		// TODO
+	} else {
+		for (int i = 1; i < NSIG; ++i) {
+			if (strcasecmp(action, sys_signame[i])) continue;
+			signal = i;
+			break;
+		}
+	}
+	if (!fn && !signal) {
+		syslog(LOG_NOTICE, "unknown action or signal %s", action);
+		return;
+	}
+
+	while (command) {
+		char *pattern = strsep(&command, WS);
+		for (size_t i = 0; i < services.len; ++i) {
+			struct Service *service = &services.ptr[i];
+			if (fnmatch(pattern, service->name, 0)) continue;
+			if (signal) {
+				serviceSignal(service, signal);
+			} else {
+				fn(service);
+			}
+		}
+	}
+}
+
 static void parseExits(char *list) {
 	setClear(&stopExits);
 	while (*list) {
@@ -288,7 +334,9 @@ int main(int argc, char *argv[]) {
 		if (nfds > 0 && fds[0].revents) {
 			const char *line;
 			while (NULL != (line = lineRead(&fifoLine, fifo))) {
-				syslog(LOG_INFO, "control: %s", line);
+				char buf[LineCap];
+				snprintf(buf, sizeof(buf), "%s", line);
+				parseControl(buf);
 			}
 			if (errno != EAGAIN) syslog(LOG_ERR, "read: %m");
 		}
@@ -331,7 +379,8 @@ int main(int argc, char *argv[]) {
 			signals[SIGHUP] = 0;
 		}
 		if (signals[SIGINFO]) {
-			// TODO: status *
+			char command[] = "status *";
+			parseControl(command);
 			signals[SIGINFO] = 0;
 		}
 	}
diff --git a/daemon.h b/daemon.h
index 17b1c7f..b8b288b 100644
--- a/daemon.h
+++ b/daemon.h
@@ -51,9 +51,10 @@ static inline int prependAdd(const char *command) {
 	return 0;
 }
 
+enum { LineCap = 512 };
 struct Line {
 	size_t len;
-	char buf[512];
+	char buf[LineCap];
 };
 
 static inline const char *lineFlush(struct Line *line) {