From 40ad83dc6a95791bd20e214d2eb1b135900d47cc Mon Sep 17 00:00:00 2001
From: David Oberhollenzer <goliath@infraroot.at>
Date: Mon, 18 Mar 2019 14:08:17 +0100
Subject: initd: implement handling of socket requests

Actually process requests and send an answer to status inquiries.

Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
---
 initd/init.h       |  3 +++
 initd/main.c       | 21 +++++++++++++++++++++
 initd/supervisor.c | 26 ++++++++++++++++++++++++++
 3 files changed, 50 insertions(+)

(limited to 'initd')

diff --git a/initd/init.h b/initd/init.h
index ce0bb1f..39e63a4 100644
--- a/initd/init.h
+++ b/initd/init.h
@@ -67,6 +67,9 @@ void supervisor_init(void);
 
 bool supervisor_process_queues(void);
 
+void supervisor_answer_status_request(int fd, const void *dest_addr,
+				      size_t addrlen);
+
 /********** signal_<platform>.c **********/
 
 /*
diff --git a/initd/main.c b/initd/main.c
index db44dc5..9432042 100644
--- a/initd/main.c
+++ b/initd/main.c
@@ -43,6 +43,27 @@ static void handle_signal(void)
 
 static void handle_request(void)
 {
+	struct sockaddr_un addr;
+	init_request_t rq;
+	socklen_t addrlen;
+	ssize_t ret;
+retry:
+	memset(&rq, 0, sizeof(rq));
+	addrlen = sizeof(addr);
+	ret = recvfrom(sockfd, &rq, sizeof(rq), MSG_DONTWAIT | MSG_TRUNC,
+		       &addr, &addrlen);
+
+	if (ret < 0 && errno == EINTR)
+		goto retry;
+
+	if ((size_t)ret < sizeof(rq))
+		return;
+
+	switch (rq.rq) {
+	case EIR_STATUS:
+		supervisor_answer_status_request(sockfd, &addr, addrlen);
+		break;
+	}
 }
 
 void target_completed(int target)
diff --git a/initd/supervisor.c b/initd/supervisor.c
index 3ed0ec7..3743ad6 100644
--- a/initd/supervisor.c
+++ b/initd/supervisor.c
@@ -167,3 +167,29 @@ bool supervisor_process_queues(void)
 		target_completed(target);
 	return true;
 }
+
+static int send_svc_list(int fd, const void *dst, size_t addrlen,
+			 E_SERVICE_STATE state, service_t *list)
+{
+	while (list != NULL) {
+		if (init_socket_send_status(fd, dst, addrlen, state, list))
+			return -1;
+
+		list = list->next;
+	}
+
+	return 0;
+}
+
+void supervisor_answer_status_request(int fd, const void *dst, size_t addrlen)
+{
+	if (send_svc_list(fd, dst, addrlen, ESS_RUNNING, running))
+		return;
+	if (send_svc_list(fd, dst, addrlen, ESS_EXITED, completed))
+		return;
+	if (send_svc_list(fd, dst, addrlen, ESS_ENQUEUED, queue))
+		return;
+	if (send_svc_list(fd, dst, addrlen, ESS_ENQUEUED, terminated))
+		return;
+	init_socket_send_status(fd, dst, addrlen, ESS_NONE, NULL);
+}
-- 
cgit v1.2.3