149 lines
3.9 KiB
C
149 lines
3.9 KiB
C
#include "include/conf.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "include/dirs.h"
|
|
#include "include/stages.h"
|
|
#include "include/deploy.h"
|
|
#include "include/metadata.h"
|
|
|
|
#include "include/main.h"
|
|
|
|
static char *sh_load_script(const char *script);
|
|
static bool sh_read_meta(const char *buffer,
|
|
sh_Metadata *meta,
|
|
sh_PtrRange *sysadm,
|
|
uint8_t *stages);
|
|
|
|
int main(int argc, const char *argv[]) {
|
|
if (getuid() != 0 || getgid() != 0) {
|
|
sh_print_error("Give me root!");
|
|
return 1;
|
|
}
|
|
|
|
if (argc < 2) {
|
|
sh_print_errorf("Usage: %s <script> [--force-unlock] [subcommand]",
|
|
argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
puts("Ensuring directorites...");
|
|
if (!sh_dirs_ensure()) {
|
|
return 1;
|
|
}
|
|
|
|
const char *script = argv[1];
|
|
const bool force_unlock =
|
|
(argc > 2 && strcmp(argv[2], "--force-unlock") == 0);
|
|
const char *subcommand = NULL;
|
|
if (force_unlock) {
|
|
if (argc > 3) {
|
|
subcommand = argv[3];
|
|
}
|
|
} else {
|
|
if (argc > 2) {
|
|
subcommand = argv[2];
|
|
}
|
|
}
|
|
|
|
/* Load script */
|
|
puts("Loading deployer script into memory...");
|
|
char *buffer = sh_load_script(script);
|
|
if (!buffer) {
|
|
return 1;
|
|
}
|
|
|
|
/* Read metadata */
|
|
puts("Ready metadata...");
|
|
sh_Metadata meta = {0};
|
|
sh_PtrRange sysadm = {0};
|
|
uint8_t stages = 0;
|
|
if (!sh_read_meta(buffer, &meta, &sysadm, &stages)) {
|
|
SH_FREE(buffer);
|
|
return 1;
|
|
}
|
|
/* Run deploy */
|
|
printf("Running deployer %s...\n", meta.name);
|
|
const int ret =
|
|
sh_run_deploy(force_unlock, subcommand, buffer, &meta, &sysadm, stages);
|
|
|
|
/* Cleanup */
|
|
puts("Cleaning up resources...");
|
|
SH_FREE(buffer);
|
|
|
|
printf("Deploy finished with exit code %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
static char *sh_load_script(const char *script) {
|
|
FILE *file = fopen(script, "r");
|
|
if (!file) {
|
|
sh_print_perrorf("Failed to open '%s'", script);
|
|
return NULL;
|
|
}
|
|
|
|
if (fseek(file, 0, SEEK_END) != 0) {
|
|
sh_print_perrorf("Failed to seek to end of '%s'", script);
|
|
(void)fclose(file);
|
|
return NULL;
|
|
}
|
|
const long filesize = ftell(file);
|
|
if (filesize < 0) {
|
|
sh_print_perrorf("Failed to get file size for '%s'", script);
|
|
(void)fclose(file);
|
|
return NULL;
|
|
}
|
|
if (fseek(file, 0, SEEK_SET) != 0) {
|
|
sh_print_perrorf("Failed to seek to beginning of '%s'", script);
|
|
(void)fclose(file);
|
|
return NULL;
|
|
}
|
|
|
|
char *buffer = SH_MALLOC((size_t)(filesize + 1));
|
|
if (!buffer) {
|
|
sh_print_perrorf("Failed to allocate memory for file '%s'", script);
|
|
(void)fclose(file);
|
|
return NULL;
|
|
}
|
|
const size_t readsize = fread(buffer, 1, (size_t)filesize, file);
|
|
if (readsize != (size_t)filesize) {
|
|
if (ferror(file)) {
|
|
sh_print_perrorf("Error reading from file '%s'", script);
|
|
} else if (feof(file)) {
|
|
sh_print_perrorf("Unexpected end of file '%s'", script);
|
|
} else {
|
|
sh_print_perrorf("Failed to read entire file '%s'", script);
|
|
}
|
|
SH_FREE(buffer);
|
|
(void)fclose(file);
|
|
return NULL;
|
|
}
|
|
|
|
buffer[filesize] = '\0';
|
|
(void)fclose(file);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
static bool sh_read_meta(const char *buffer,
|
|
sh_Metadata *meta,
|
|
sh_PtrRange *sysadm,
|
|
uint8_t *stages) {
|
|
if (!sh_Metadata_read(meta, buffer)) {
|
|
sh_print_error("Failed to read metadata");
|
|
return false;
|
|
}
|
|
if (!sh_Metadata_is_full_script(meta)) {
|
|
sh_print_error("Script has missing metadata");
|
|
return false;
|
|
}
|
|
|
|
*stages = sh_find_stages(buffer, sysadm);
|
|
if ((*stages & SH_STAGE_ERROR) != 0) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|