diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | daemon.c | 45 | ||||
-rw-r--r-- | daemon.h | 6 | ||||
-rw-r--r-- | service.c | 31 |
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; |