commit 814604b6f98160ff44e2c61469659d65b285ca8a
Author: aabacchus <ben@bvnf.space>
Date: Fri, 21 Apr 2023 15:28:44 +0100
init: parses config vars
Diffstat:
5 files changed, 380 insertions(+), 0 deletions(-)
diff --git a/src/.gitignore b/src/.gitignore
@@ -0,0 +1,3 @@
+*.a
+*.o
+test
diff --git a/src/Makefile b/src/Makefile
@@ -0,0 +1,20 @@
+.POSIX:
+
+XCFLAGS = $(CFLAGS) -Wall -Wextra -pedantic -D_XOPEN_SOURCE=700 -Og -g
+
+libkiss.a: libkiss.o
+ $(AR) -rcs $@ libkiss.o
+
+.c.o:
+ $(CC) $(XCFLAGS) -c $< -o $@
+
+test: test.o libkiss.a
+ $(CC) $(LDFLAGS) test.o libkiss.a -o $@
+
+clean:
+ rm -f libkiss.a libkiss.o test.o test
+
+.PHONY: clean
+
+libkiss.o: kiss.h
+test.o: kiss.h
diff --git a/src/kiss.h b/src/kiss.h
@@ -0,0 +1,40 @@
+#include <limits.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+struct cmd {
+ char **args;
+};
+
+struct env {
+ bool color;
+ bool debug;
+ bool force;
+ bool keeplog;
+ bool prompt;
+ char **hooks;
+ char **kiss_path;
+ char **path;
+ char *b3[5];
+ char *compress;
+ char *elf;
+ char *get[7];
+ char *pid;
+ char *pwd;
+ char *root;
+ char *su;
+ char *tmpdir;
+ char date[17]; /* YYYY-MM-DD-HH:MM + '\0' */
+};
+
+void mylog(const char *s);
+void warn(const char *s);
+void die(const char *s);
+void die_perror(const char *s);
+
+char **split(char *s, char *sep);
+char *find_in_path(char *name, char **path);
+int available_cmd(char **path, char *cmd, ...);
+
+struct env *setup_env(void);
+void destroy_env(struct env *e);
diff --git a/src/libkiss.c b/src/libkiss.c
@@ -0,0 +1,266 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "kiss.h"
+
+void
+mylog(const char *s) {
+ fprintf(stderr, "-> %s\n", s);
+}
+
+void
+warn(const char *s) {
+ fprintf(stderr, "WARNING %s\n", s);
+}
+
+void
+die(const char *s) {
+ mylog(s);
+ exit(1);
+}
+
+void
+die_perror(const char *s) {
+ perror(s);
+ exit(1);
+}
+
+char **
+split(char *s, char *sep) {
+ if (s == NULL)
+ return NULL;
+
+ char **res = NULL, **tmp;
+ char *p = strtok(s, sep);
+ int n = 0;
+
+ while (p) {
+ tmp = realloc(res, sizeof(char *) * ++n);
+ if (tmp == NULL) {
+ free(res);
+ die_perror("realloc");
+ }
+ res = tmp;
+ res[n - 1] = strdup(p);
+ p = strtok(NULL, sep);
+ }
+
+ /* add a NULL terminator */
+ tmp = realloc(res, sizeof(char *) * (n + 1));
+ if (tmp == NULL) {
+ free(res);
+ die_perror("realloc");
+ }
+ res = tmp;
+ res[n] = NULL;
+
+ return res;
+}
+
+char *
+find_in_path(char *name, char **path) {
+ for (int i = 0; path[i] != NULL; i++) {
+ char *file = calloc(strlen(path[i]) + strlen(name) + 2, 1);
+ strcpy(file, path[i]);
+ strcat(file, "/");
+ strcat(file, name);
+ if (access(file, R_OK) == 0) {
+ return file;
+ }
+ free(file);
+ }
+ return NULL;
+}
+
+int
+available_cmd(char **path, char *cmd, ...) {
+ char *s;
+ va_list ap;
+ int n = 0;
+ va_start(ap, cmd);
+ while (cmd != 0) {
+ s = find_in_path(cmd, path);
+ if (s != NULL) {
+ free(s);
+ va_end(ap);
+ return n;
+ }
+ free(s);
+ n++;
+ cmd = va_arg(ap, char *);
+ }
+ va_end(ap);
+ return -1;
+}
+
+struct env *
+setup_env(void) {
+ char *t;
+ struct env *e = calloc(1, sizeof(struct env));
+ if (e == NULL) die_perror("calloc");
+
+ t = getenv("KISS_COLOR");
+ e->color = !(t && *t == '0');
+
+ t = getenv("KISS_DEBUG");
+ e->debug = (t && *t == '1');
+
+ t = getenv("KISS_FORCE");
+ e->force = (t && *t == '1');
+
+ t = getenv("KISS_KEEPLOG");
+ e->keeplog = (t && *t == '1');
+
+ t = getenv("KISS_PROMPT");
+ e->prompt = !(t && *t == '0');
+
+ t = getenv("KISS_HOOK");
+ e->hooks = split(t, ":");
+
+ t = getenv("KISS_PATH");
+ e->kiss_path = split(t, ":");
+
+ t = getenv("PATH");
+ e->path = split(t, ":");
+
+ t = getenv("PWD");
+ if (t == NULL) die("PWD is not set");
+ e->pwd = t;
+
+ e->root = getenv("KISS_ROOT");
+
+ time_t dt = time(NULL);
+ struct tm *tm = localtime(&dt);
+ if (tm == NULL) die_perror("localtime");
+ strftime(e->date, sizeof(e->date), "%Y-%m-%d-%H:%M", tm);
+
+ e->tmpdir = getenv("KISS_TMPDIR"); /* TODO */
+
+ t = getenv("KISS_PID");
+ if (t && *t != '\0') {
+ e->pid = strdup(t);
+ } else {
+ pid_t p = getpid();
+ int n = snprintf(NULL, 0, "%d", p);
+ if (n < 0) die_perror("snprintf");
+ e->pid = malloc(n+1);
+ if (e->pid == NULL) die_perror("malloc");
+ snprintf(e->pid, n, "%d", p);
+ }
+
+ switch (available_cmd(e->path, "b3sum", 0)) {
+ case 0:
+ e->b3[0] = "b3sum";
+ e->b3[1] = "-l";
+ e->b3[2] = "33";
+ e->b3[4] = NULL;
+ break;
+ default:
+ die("b3sum utility not found");
+ }
+
+ t = getenv("KISS_COMPRESS");
+ e->compress = (t && *t != '\0') ? t : "gz";
+
+ switch (available_cmd(e->path, "aria2c", "axel", "curl", "wget", "wget2", 0)) {
+ case 0:
+ e->get[0] = "aria2c";
+ e->get[1] = "-d";
+ e->get[2] = "/";
+ e->get[3] = "-o";
+ e->get[4] = NULL;
+ break;
+ case 1:
+ e->get[0] = "axel";
+ e->get[1] = "-o";
+ e->get[2] = NULL;
+ break;
+ case 2:
+ e->get[0] = "curl";
+ e->get[1] = "-fLo";
+ e->get[2] = NULL;
+ break;
+ case 3:
+ e->get[0] = "wget";
+ e->get[1] = "-O";
+ e->get[2] = NULL;
+ break;
+ case 4:
+ e->get[0] = "wget2";
+ e->get[1] = "-O";
+ e->get[2] = NULL;
+ break;
+ default:
+ die("No download utility found (aria2c, axel, curl, wget, wget2)");
+ }
+
+ /* su args are handled in as_user because 'su' needs a different order to
+ * the others */
+ t = getenv("KISS_SU");
+ if (t && *t != '\0') {
+ e->su = t;
+ } else {
+ switch (available_cmd(e->path, "ssu", "sudo", "doas", "su", 0)) {
+ case 0:
+ e->su = "ssu";
+ break;
+ case 1:
+ e->su = "sudo";
+ break;
+ case 2:
+ e->su = "doas";
+ break;
+ case 3:
+ e->su = "su";
+ break;
+ default:
+ die("No su utility found (ssu, sudo, doas, su)");
+ }
+ }
+
+ t = getenv("KISS_ELF");
+ if (t && *t != '\0') {
+ e->elf = t;
+ } else {
+ switch (available_cmd(e->path, "readelf", "eu-readelf", "llvm-readelf", "ldd", 0)) {
+ case 0:
+ e->elf = "readelf";
+ break;
+ case 1:
+ e->elf = "eu-readelf";
+ break;
+ case 2:
+ e->elf = "llvm-readelf";
+ break;
+ case 3:
+ e->elf = "ldd";
+ break;
+ default:
+ e->elf = NULL;
+ warn("No readelf utility found (readelf, eu-readelf, llvm-readelf, ldd)");
+ }
+ }
+
+ return e;
+}
+
+void
+destroy_env(struct env *e) {
+ for (int i = 0; e->hooks[i] != NULL; i++)
+ free(e->hooks[i]);
+ free(e->hooks);
+
+ for (int i = 0; e->kiss_path[i] != NULL; i++)
+ free(e->kiss_path[i]);
+ free(e->kiss_path);
+
+ for (int i = 0; e->path[i] != NULL; i++)
+ free(e->path[i]);
+ free(e->path);
+
+ free(e->pid);
+ free(e);
+}
diff --git a/src/test.c b/src/test.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include "kiss.h"
+
+int
+main(int argc, char **argv) {
+ struct env *e = setup_env();
+
+ printf("%s\t%d\n", "color", e->color);
+ printf("%s\t%d\n", "debug", e->debug);
+ printf("%s\t%d\n", "force", e->force);
+ printf("%s\t%d\n", "keeplog", e->keeplog);
+ printf("%s\t%d\n", "prompt", e->prompt);
+
+ printf("hooks:\t");
+ for (int i = 0; e->hooks[i] != NULL; i++)
+ printf("%s, ", e->hooks[i]);
+ printf("\n");
+
+ printf("kiss_path:\t");
+ for (int i = 0; e->kiss_path[i] != NULL; i++)
+ printf("%s, ", e->kiss_path[i]);
+ printf("\n");
+
+ printf("path:\t");
+ for (int i = 0; e->path[i] != NULL; i++)
+ printf("%s, ", e->path[i]);
+ printf("\n");
+
+ printf("b3:\t");
+ for (int i = 0; e->b3[i] != NULL; i++)
+ printf("%s, ", e->b3[i]);
+ printf("\n");
+
+ printf("%s\t%s\n", "compress", e->compress);
+ printf("%s\t%s\n", "elf", e->elf);
+
+ printf("get:\t");
+ for (int i = 0; e->get[i] != NULL; i++)
+ printf("%s, ", e->get[i]);
+ printf("\n");
+
+ printf("%s\t%s\n", "pwd", e->pwd);
+ printf("%s\t%s\n", "root", e->root);
+ printf("%s\t%s\n", "su", e->su);
+ printf("%s\t%s\n", "tmpdir", e->tmpdir);
+ printf("%s\t%s\n", "date", e->date);
+ printf("%s\t%s\n", "pid", e->pid);
+
+ destroy_env(e);
+ return 0;
+}