tonarchy

tonarchy

https://git.tonybtw.com/tonarchy.git git://git.tonybtw.com/tonarchy.git

added logger and chroot helper

Commit
85e810a78718aca79d2c0a8f49ea4ad34245c470
Parent
9bb61ac
Author
tonybanters <tonybanters@gmail.com>
Date
2025-12-23 19:16:09

Diff

diff --git a/include/chroot_helper.h b/include/chroot_helper.h
new file mode 100644
index 0000000..4885825
--- /dev/null
+++ b/include/chroot_helper.h
@@ -0,0 +1,32 @@
+#ifndef CHROOT_HELPER_H
+#define CHROOT_HELPER_H
+
+#include "types.h"
+
+int write_file(const char *path, const char *content);
+int write_file_fmt(const char *path, const char *fmt, ...);
+int set_file_perms(const char *path, mode_t mode, const char *owner, const char *group);
+int create_directory(const char *path, mode_t mode);
+
+int chroot_exec(const char *cmd);
+int chroot_exec_fmt(const char *fmt, ...);
+int chroot_exec_as_user(const char *username, const char *cmd);
+int chroot_exec_as_user_fmt(const char *username, const char *fmt, ...);
+
+int git_clone_as_user(const char *username, const char *repo_url, const char *dest_path);
+
+int make_clean_install(const char *build_dir);
+
+int create_user_dotfile(const char *username, const DotFile *dotfile);
+int setup_systemd_override(const SystemdOverride *override);
+
+#define CHECK_OR_FAIL(expr, user_msg) \
+    do { \
+        if (!(expr)) { \
+            LOG_ERROR("%s", #expr); \
+            show_message(user_msg); \
+            return 0; \
+        } \
+    } while(0)
+
+#endif
diff --git a/include/logger.h b/include/logger.h
new file mode 100644
index 0000000..4655033
--- /dev/null
+++ b/include/logger.h
@@ -0,0 +1,24 @@
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include <stdio.h>
+#include <time.h>
+#include <stdarg.h>
+
+typedef enum {
+    LOG_DEBUG,
+    LOG_INFO,
+    LOG_WARN,
+    LOG_ERROR
+} LogLevel;
+
+void logger_init(const char *log_path);
+void logger_close(void);
+void log_msg(LogLevel level, const char *fmt, ...);
+
+#define LOG_DEBUG(...) log_msg(LOG_DEBUG, __VA_ARGS__)
+#define LOG_INFO(...)  log_msg(LOG_INFO, __VA_ARGS__)
+#define LOG_WARN(...)  log_msg(LOG_WARN, __VA_ARGS__)
+#define LOG_ERROR(...) log_msg(LOG_ERROR, __VA_ARGS__)
+
+#endif
diff --git a/src/chroot_helper.c b/src/chroot_helper.c
new file mode 100644
index 0000000..87a8a96
--- /dev/null
+++ b/src/chroot_helper.c
@@ -0,0 +1,182 @@
+#define _POSIX_C_SOURCE 200809L
+#include "chroot_helper.h"
+#include "logger.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+
+#define CHROOT_PATH "/mnt"
+#define MAX_CMD_SIZE 4096
+
+int write_file(const char *path, const char *content) {
+    LOG_INFO("Writing file: %s", path);
+    FILE *fp = fopen(path, "w");
+    if (!fp) {
+        LOG_ERROR("Failed to open file for writing: %s", path);
+        return 0;
+    }
+
+    if (fprintf(fp, "%s", content) < 0) {
+        LOG_ERROR("Failed to write to file: %s", path);
+        fclose(fp);
+        return 0;
+    }
+
+    fclose(fp);
+    LOG_DEBUG("Successfully wrote file: %s", path);
+    return 1;
+}
+
+int write_file_fmt(const char *path, const char *fmt, ...) {
+    char content[MAX_CMD_SIZE];
+    va_list args;
+
+    va_start(args, fmt);
+    vsnprintf(content, sizeof(content), fmt, args);
+    va_end(args);
+
+    return write_file(path, content);
+}
+
+int set_file_perms(const char *path, mode_t mode, const char *owner, const char *group) {
+    LOG_INFO("Setting permissions for %s: mode=%o owner=%s group=%s", path, mode, owner, group);
+
+    if (chmod(path, mode) != 0) {
+        LOG_ERROR("Failed to chmod %s", path);
+        return 0;
+    }
+
+    char chown_cmd[512];
+    snprintf(chown_cmd, sizeof(chown_cmd), "chown %s:%s %s", owner, group, path);
+
+    if (system(chown_cmd) != 0) {
+        LOG_ERROR("Failed to chown %s", path);
+        return 0;
+    }
+
+    return 1;
+}
+
+int create_directory(const char *path, mode_t mode) {
+    LOG_INFO("Creating directory: %s", path);
+    char cmd[512];
+    snprintf(cmd, sizeof(cmd), "mkdir -p %s", path);
+
+    if (system(cmd) != 0) {
+        LOG_ERROR("Failed to create directory: %s", path);
+        return 0;
+    }
+
+    if (chmod(path, mode) != 0) {
+        LOG_WARN("Failed to set permissions on directory: %s", path);
+    }
+
+    return 1;
+}
+
+int chroot_exec(const char *cmd) {
+    char full_cmd[MAX_CMD_SIZE];
+    snprintf(full_cmd, sizeof(full_cmd), "arch-chroot %s /bin/bash -c '%s' >> /tmp/tonarchy-install.log 2>&1",
+             CHROOT_PATH, cmd);
+
+    LOG_INFO("Executing in chroot: %s", cmd);
+    LOG_DEBUG("Full command: %s", full_cmd);
+
+    int result = system(full_cmd);
+    if (result != 0) {
+        LOG_ERROR("Chroot command failed (exit %d): %s", result, cmd);
+        return 0;
+    }
+
+    LOG_DEBUG("Chroot command succeeded: %s", cmd);
+    return 1;
+}
+
+int chroot_exec_fmt(const char *fmt, ...) {
+    char cmd[MAX_CMD_SIZE];
+    va_list args;
+
+    va_start(args, fmt);
+    vsnprintf(cmd, sizeof(cmd), fmt, args);
+    va_end(args);
+
+    return chroot_exec(cmd);
+}
+
+int chroot_exec_as_user(const char *username, const char *cmd) {
+    char full_cmd[MAX_CMD_SIZE * 2];
+    snprintf(full_cmd, sizeof(full_cmd), "sudo -u %s %s", username, cmd);
+    return chroot_exec(full_cmd);
+}
+
+int chroot_exec_as_user_fmt(const char *username, const char *fmt, ...) {
+    char cmd[MAX_CMD_SIZE];
+    va_list args;
+
+    va_start(args, fmt);
+    vsnprintf(cmd, sizeof(cmd), fmt, args);
+    va_end(args);
+
+    return chroot_exec_as_user(username, cmd);
+}
+
+int git_clone_as_user(const char *username, const char *repo_url, const char *dest_path) {
+    LOG_INFO("Cloning %s to %s as user %s", repo_url, dest_path, username);
+    return chroot_exec_as_user_fmt(username, "git clone %s %s", repo_url, dest_path);
+}
+
+int make_clean_install(const char *build_dir) {
+    LOG_INFO("Building and installing from %s", build_dir);
+    return chroot_exec_fmt("cd %s && make clean install", build_dir);
+}
+
+int create_user_dotfile(const char *username, const DotFile *dotfile) {
+    char full_path[512];
+    snprintf(full_path, sizeof(full_path), "%s/home/%s/%s", CHROOT_PATH, username, dotfile->filename);
+
+    LOG_INFO("Creating dotfile %s for user %s", dotfile->filename, username);
+
+    if (!write_file(full_path, dotfile->content)) {
+        return 0;
+    }
+
+    if (!set_file_perms(full_path, dotfile->permissions, username, username)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int setup_systemd_override(const SystemdOverride *override) {
+    char dir_path[1024];
+    char file_path[2048];
+
+    snprintf(dir_path, sizeof(dir_path), "%s/etc/systemd/system/%s",
+             CHROOT_PATH, override->drop_in_dir);
+    snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, override->drop_in_file);
+
+    LOG_INFO("Setting up systemd override: %s/%s", override->drop_in_dir, override->drop_in_file);
+
+    if (!create_directory(dir_path, 0755)) {
+        return 0;
+    }
+
+    FILE *fp = fopen(file_path, "w");
+    if (!fp) {
+        LOG_ERROR("Failed to create systemd override file: %s", file_path);
+        return 0;
+    }
+
+    for (size_t i = 0; i < override->entry_count; i++) {
+        fprintf(fp, "%s=%s\n", override->entries[i].key, override->entries[i].value);
+    }
+
+    fclose(fp);
+    LOG_INFO("Successfully created systemd override");
+    return 1;
+}
diff --git a/src/logger.c b/src/logger.c
new file mode 100644
index 0000000..367891e
--- /dev/null
+++ b/src/logger.c
@@ -0,0 +1,50 @@
+#include "logger.h"
+#include <stdlib.h>
+#include <string.h>
+
+static FILE *log_file = NULL;
+static const char *level_strings[] = {
+    "DEBUG", "INFO", "WARN", "ERROR"
+};
+
+void logger_init(const char *log_path) {
+    log_file = fopen(log_path, "a");
+    if (log_file) {
+        time_t now = time(NULL);
+        char *timestamp = ctime(&now);
+        timestamp[strlen(timestamp) - 1] = '\0';
+        fprintf(log_file, "\n=== Tonarchy Installation Log - %s ===\n", timestamp);
+        fflush(log_file);
+    }
+}
+
+void logger_close(void) {
+    if (log_file) {
+        fclose(log_file);
+        log_file = NULL;
+    }
+}
+
+void log_msg(LogLevel level, const char *fmt, ...) {
+    if (!log_file) return;
+
+    time_t now = time(NULL);
+    struct tm *t = localtime(&now);
+
+    fprintf(
+        log_file,
+        "[%02d:%02d:%02d] [%s] ",
+        t->tm_hour,
+        t->tm_min,
+        t->tm_sec,
+        level_strings[level]
+    );
+
+    va_list args;
+    va_start(args, fmt);
+    vfprintf(log_file, fmt, args);
+    va_end(args);
+
+    fprintf(log_file, "\n");
+    fflush(log_file);
+}