diff options
author | 2025-04-09 13:24:53 -0700 | |
---|---|---|
committer | 2025-04-11 00:15:18 -0700 | |
commit | f277f41d83d450a1f28d350bb7d6da075d1d2741 (patch) | |
tree | e197a7de7e26b47cec57a46acdde4b6c74889ad5 /src/precheck.c | |
download | github-mirror-f277f41d83d450a1f28d350bb7d6da075d1d2741.tar.gz github-mirror-f277f41d83d450a1f28d350bb7d6da075d1d2741.tar.zst github-mirror-f277f41d83d450a1f28d350bb7d6da075d1d2741.zip |
Initial Commit
Add cmake github workflow
Install dependencies in gh action
Fix missing directory
Fix compiler errors
Fix group name to gid conversion
Force cjson to statically link
Add header guards to query headers
Add install and cpack to CMakeLists.txt
Add config search and CLI arg parsing
Improve docs for git.c
Fix program continuing on -h flag
Diffstat (limited to 'src/precheck.c')
-rw-r--r-- | src/precheck.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/precheck.c b/src/precheck.c new file mode 100644 index 0000000..a9fce35 --- /dev/null +++ b/src/precheck.c @@ -0,0 +1,112 @@ +// +// Created by Anshul Gupta on 4/7/25. +// + +#include "precheck.h" + +#include <stdio.h> +#include <sys/errno.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> +#ifdef __linux__ +#include <sys/capability.h> +#endif + +/** + * Check if git is installed and available in the PATH. + * @return 1 if git is available, 0 if not. + */ +static int has_git(void) +{ + pid_t pid = fork(); + if (pid < 0) { + perror("fork"); + return 0; + } + + if (pid == 0) { + // Child process + char *args[] = {"git", "--version", NULL}; + execvp("git", args); + _exit(127); // execvp only returns on error + } + + // Parent process + int status; + pid_t result; + do { + result = waitpid(pid, &status, 0); + } while (result == -1 && errno == EINTR); + if (result == -1) { + perror("waitpid"); + return 0; + } + + // Check exit status + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { + return 1; // git is available + } + + fprintf(stderr, "Error: git is not installed or not found in PATH\n"); + return 0; // git is not available +} + +/** + * Check if we have CAP_CHOWN capability or if we are root. + * @return 1 if we have chown capability, 0 if not. + */ +static int has_chown(void) +{ +#ifdef __linux__ + cap_t caps = cap_get_proc(); + if (caps == NULL) { + perror("cap_get_proc"); + return 0; + } + + cap_flag_value_t cap_value; + if (cap_get_flag(caps, CAP_CHOWN, CAP_EFFECTIVE, &cap_value) == -1) { + perror("cap_get_flag"); + cap_free(caps); + return 0; + } + cap_free(caps); + + if (cap_value == CAP_SET) + return 1; // We have CAP_CHOWN capability + fprintf(stderr, "Error: CAP_CHOWN capability is not set\n"); + return 0; // We don't have CAP_CHOWN capability +#else + if (geteuid() == 0) + return 1; + fprintf(stderr, "Error: not running as root\n"); + return 0; +#endif +} + +/** + * Check if the git base directory exists. + * @param path Path to the directory to check + * @return 1 if the directory exists, 0 if not. + */ +static int git_base_exists(const char *path) +{ + struct stat st; + if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) { + return 1; + } + fprintf(stderr, "Error: git base directory does not exist: %s\n", path); + return 0; +} + +int precheck_self(const struct config *cfg) +{ + if (!has_git()) + return -1; + if (!has_chown()) + return -1; + if (!git_base_exists(cfg->git_base)) + return -1; + return 0; +} |