diff options
-rw-r--r-- | daemon.c | 31 | ||||
-rw-r--r-- | daemon.h | 16 | ||||
-rw-r--r-- | service.c | 12 |
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; |