summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--daemon.c45
-rw-r--r--daemon.h6
-rw-r--r--service.c31
4 files changed, 63 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index a8ca227..5698196 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,7 @@ MAN8 = ${BINS:=.8}
 MAN5 = spawntab.5
 
 OBJS += daemon.o
+OBJS += service.o
 
 all: ${BINS}
 
diff --git a/daemon.c b/daemon.c
index 36d5986..0b07bb9 100644
--- a/daemon.c
+++ b/daemon.c
@@ -17,6 +17,8 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -35,9 +37,6 @@
 #define ETCDIR "/usr/local/etc"
 #endif
 
-int restartInterval = 1000;
-struct Set256 stopExits;
-
 static void parseExits(char *list) {
 	setClear(&stopExits);
 	while (*list) {
@@ -52,15 +51,6 @@ static void parseExits(char *list) {
 
 int main(int argc, char *argv[]) {
 	bool daemonize = true;
-
-	const char *pidPath = NULL;
-	const char *configPath = ETCDIR "/spawntab";
-	const char *fifoPath = RUNDIR "/spawnd.pipe";
-
-	const char *chdirPath = "/";
-	const char *user = NULL;
-	const char *group = NULL;
-
 	setAdd(&stopExits, 127);
 	setAdd(&stopExits, EX_USAGE);
 	setAdd(&stopExits, EX_DATAERR);
@@ -69,9 +59,16 @@ int main(int argc, char *argv[]) {
 	setAdd(&stopExits, EX_CANTCREAT);
 	setAdd(&stopExits, EX_CONFIG);
 
+	const char *pidPath = NULL;
+	const char *configPath = ETCDIR "/spawntab";
+	const char *fifoPath = RUNDIR "/spawnd.pipe";
+
+	const char *user = NULL;
+	const char *group = NULL;
+
 	for (int opt; 0 < (opt = getopt(argc, argv, "C:c:df:g:p:s:t:u:"));) {
 		switch (opt) {
-			break; case 'C': chdirPath = optarg;
+			break; case 'C': serviceDir = optarg;
 			break; case 'c': fifoPath = optarg;
 			break; case 'd': daemonize = false;
 			break; case 'f': configPath = optarg;
@@ -84,6 +81,21 @@ int main(int argc, char *argv[]) {
 		}
 	}
 
+	// TODO: Read config file.
+	
+	int error = access(serviceDir, X_OK);
+	if (error) err(EX_NOINPUT, "%s", serviceDir);
+
+	errno = 0;
+	serviceUser = (user ? getpwnam(user) : getpwuid(getuid()));
+	if (errno) err(EX_OSFILE, "getpwnam");
+	if (!serviceUser) errx(EX_USAGE, "no such user %s", user);
+
+	errno = 0;
+	serviceGroup = (group ? getgrnam(group) : getgrgid(serviceUser->pw_gid));
+	if (errno) err(EX_OSFILE, "getgrnam");
+	if (!serviceGroup) errx(EX_USAGE, "no such group %s", group);
+
 	int pidFile = -1;
 	if (pidPath) {
 		pidFile = open(
@@ -92,13 +104,6 @@ int main(int argc, char *argv[]) {
 		if (pidFile < 0) err(EX_CANTCREAT, "%s", pidPath);
 	}
 
-	// TODO: Read config file.
-	
-	int error = access(chdirPath, X_OK);
-	if (error) err(EX_NOINPUT, "%s", chdirPath);
-
-	// TODO: Do user, group lookup.
-
 	// We can't lock a named pipe, so just warn if it already exists.
 	error = mkfifo(fifoPath, 0600);
 	if (error) {
diff --git a/daemon.h b/daemon.h
index 0d9e4de..3a141ba 100644
--- a/daemon.h
+++ b/daemon.h
@@ -14,6 +14,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <grp.h>
+#include <pwd.h>
 #include <stdint.h>
 
 typedef unsigned char byte;
@@ -33,3 +35,7 @@ static inline uint32_t setTest(const struct Set256 *set, byte x) {
 
 extern int restartInterval;
 extern struct Set256 stopExits;
+
+extern const char *serviceDir;
+extern struct passwd *serviceUser;
+extern struct group *serviceGroup;
diff --git a/service.c b/service.c
new file mode 100644
index 0000000..a81a588
--- /dev/null
+++ b/service.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2020  C. McEnroe <june@causal.agency>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <err.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysexits.h>
+
+#include "daemon.h"
+
+struct Set256 stopExits;
+int restartInterval = 1000;
+
+const char *serviceDir = "/";
+struct passwd *serviceUser;
+struct group *serviceGroup;