summary refs log tree commit diff
diff options
context:
space:
mode:
authorC. McEnroe <june@causal.agency>2020-08-14 16:17:29 -0400
committerC. McEnroe <june@causal.agency>2020-08-14 16:17:29 -0400
commit96e962a08c12ef14f1eef3b5db41204a36f91722 (patch)
tree89fc2b3c0e54774759ad12355954d94b0c0d2bc0
parentImplement spawntab parsing (diff)
downloadcatsit-96e962a08c12ef14f1eef3b5db41204a36f91722.tar.gz
catsit-96e962a08c12ef14f1eef3b5db41204a36f91722.zip
Build environment for services
-rw-r--r--daemon.c31
-rw-r--r--daemon.h16
-rw-r--r--service.c12
3 files changed, 44 insertions, 15 deletions
diff --git a/daemon.c b/daemon.c
index 6cbf8eb..a2ce4dc 100644
--- a/daemon.c
+++ b/daemon.c
@@ -134,8 +134,8 @@ int main(int argc, char *argv[]) {
 	const char *configPath = ETCDIR "/spawntab";
 	const char *fifoPath = RUNDIR "/spawnd.pipe";
 
-	const char *user = NULL;
-	const char *group = NULL;
+	const char *userName = NULL;
+	const char *groupName = NULL;
 
 	for (int opt; 0 < (opt = getopt(argc, argv, "C:c:df:g:p:s:t:u:"));) {
 		switch (opt) {
@@ -143,29 +143,42 @@ int main(int argc, char *argv[]) {
 			break; case 'c': fifoPath = optarg;
 			break; case 'd': daemonize = false;
 			break; case 'f': configPath = optarg;
-			break; case 'g': group = optarg;
+			break; case 'g': groupName = optarg;
 			break; case 'p': pidPath = optarg;
 			break; case 's': parseExits(optarg);
 			break; case 't': restartInterval = strtoul(optarg, NULL, 10);
-			break; case 'u': user = optarg;
+			break; case 'u': userName = optarg;
 			break; default:  return EX_USAGE;
 		}
 	}
-
 	parseConfig(true, configPath);
 	
 	int error = access(serviceDir, X_OK);
 	if (error) err(EX_NOINPUT, "%s", serviceDir);
 
 	errno = 0;
-	serviceUser = (user ? getpwnam(user) : getpwuid(getuid()));
+	struct passwd *user = (userName ? getpwnam(userName) : getpwuid(getuid()));
 	if (errno) err(EX_OSFILE, "getpwnam");
-	if (!serviceUser) errx(EX_USAGE, "no such user %s", user);
+	if (!user) errx(EX_USAGE, "no such user %s", userName);
 
 	errno = 0;
-	serviceGroup = (group ? getgrnam(group) : getgrgid(serviceUser->pw_gid));
+	struct group *group = (
+		groupName ? getgrnam(groupName) : getgrgid(user->pw_gid)
+	);
 	if (errno) err(EX_OSFILE, "getgrnam");
-	if (!serviceGroup) errx(EX_USAGE, "no such group %s", group);
+	if (!group) errx(EX_USAGE, "no such group %s", groupName);
+
+	serviceUID = user->pw_uid;
+	serviceGID = group->gr_gid;
+
+	int len = asprintf(&serviceEnviron[LOGNAME], "LOGNAME=%s", user->pw_name);
+	if (len < 0) err(EX_OSERR, "asprintf");
+
+	len = asprintf(&serviceEnviron[USER], "USER=%s", user->pw_name);
+	if (len < 0) err(EX_OSERR, "asprintf");
+
+	len = asprintf(&serviceEnviron[HOME], "HOME=%s", user->pw_dir);
+	if (len < 0) err(EX_OSERR, "asprintf");
 
 	int pidFile = -1;
 	if (pidPath) {
diff --git a/daemon.h b/daemon.h
index d7efb28..2c77537 100644
--- a/daemon.h
+++ b/daemon.h
@@ -19,6 +19,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 typedef unsigned char byte;
 
@@ -47,9 +48,20 @@ static inline int prependAdd(const char *command) {
 	return 0;
 }
 
+enum {
+	SHELL,
+	PATH,
+	LOGNAME,
+	USER,
+	HOME,
+	EnvironNull,
+	EnvironLen,
+};
+
 extern const char *serviceDir;
-extern struct passwd *serviceUser;
-extern struct group *serviceGroup;
+extern uid_t serviceUID;
+extern gid_t serviceGID;
+extern char *serviceEnviron[EnvironLen];
 
 struct Service {
 	char *name;
diff --git a/service.c b/service.c
index b6e6ce1..7087e38 100644
--- a/service.c
+++ b/service.c
@@ -14,17 +14,21 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <grp.h>
-#include <pwd.h>
+#include <paths.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "daemon.h"
 
 const char *serviceDir = "/";
-struct passwd *serviceUser;
-struct group *serviceGroup;
+uid_t serviceUID;
+gid_t serviceGID;
+char *serviceEnviron[EnvironLen] = {
+	[SHELL] = "SHELL=" _PATH_BSHELL,
+	[PATH]  = "PATH=" _PATH_DEFPATH,
+};
 
 struct Prepend prepend;
 struct Services services;