diff options
author | turret <turret@duck.com> | 2024-01-18 19:01:13 -0600 |
---|---|---|
committer | turret <turret@duck.com> | 2024-01-18 19:01:13 -0600 |
commit | bc6e03d73b4ff54f5562400c57ffa1e685ac971a (patch) | |
tree | bb23ae9bc40c312ac44be8c3594087c7fa1af0ac | |
parent | e6c7c2f3d683a5c15e2be15563e2f52d8aed91ed (diff) | |
download | discord-bot-skeleton-bc6e03d73b4ff54f5562400c57ffa1e685ac971a.tar.gz discord-bot-skeleton-bc6e03d73b4ff54f5562400c57ffa1e685ac971a.tar.bz2 discord-bot-skeleton-bc6e03d73b4ff54f5562400c57ffa1e685ac971a.zip |
init: apply .env files
we apply .env files from both the current working directory and the
directory of the executable we're running from
very simple .env format, KEY=VALUE, comments prepended with # on first
character of line only.
-rw-r--r-- | init/init.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/init/init.c b/init/init.c index 7fb229e..3457769 100644 --- a/init/init.c +++ b/init/init.c @@ -1,8 +1,11 @@ +#include <fcntl.h> #include <signal.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> #include <sys/param.h> #include <sys/resource.h> +#include <sys/stat.h> #include <sys/wait.h> #include <curl/curl.h> @@ -62,7 +65,52 @@ static void do_initcalls(void) } } +static void doenv(char *path) +{ + int fd = open(path, O_RDONLY); + if(fd < 0) + return; + + struct stat statbuf; + if(fstat(fd, &statbuf) < 0) + return; + + char *file_mmap = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if(file_mmap == NULL) + return; + + char *file = malloc(statbuf.st_size + 1); + file[statbuf.st_size + 1] = 0; + memcpy(file, file_mmap, statbuf.st_size); + munmap(file_mmap, statbuf.st_size); + + int offset = 0; + while(1) { + char *line = &(file[offset]); + if(*line == '\0') + break; + + char *eol = strchrnul(line, '\n'); + *eol = '\0'; + if(*line == '#') + goto nextline; + + char *divider = strchr(line, '='); + if(divider == NULL) + goto nextline; + *divider = '\0'; + setenv(line, divider + 1, 0); + print(LOG_DEBUG "env: setting \"%s\" to \"%s\"", + line, divider + 1); + +nextline: + offset += (eol - line) + 1; + continue; + } + + free(file); +} int main(void) { @@ -89,6 +137,29 @@ int main(void) sigaddset(&set, SIGTERM); sigprocmask(SIG_BLOCK, &set, NULL); + /* use .env files if present */ + doenv(".env"); + + /* find directory of self and use env from there if it exists */ + char *buf = calloc(PATH_MAX, sizeof(char)); + ssize_t self_size = readlink("/proc/self/exe", buf, PATH_MAX); + if(self_size + strlen(".env") + 1 > PATH_MAX) + goto skip_self; + + char *lastslash = strrchr(buf, '/'); + *lastslash = '\0'; + + char *cwd = get_current_dir_name(); + int cwd_is_exec_dir = strcmp(buf, cwd) == 0; + free(cwd); + if(cwd_is_exec_dir) + goto skip_self; + + strcat(buf, "/.env"); + doenv(buf); +skip_self: + free(buf); + /* fetch token */ char *token_base = getenv("TOKEN"); if(!token_base) |