diff options
Diffstat (limited to 'src/boot.c')
-rw-r--r-- | src/boot.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/boot.c b/src/boot.c new file mode 100644 index 0000000..c58f332 --- /dev/null +++ b/src/boot.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2020-2024 Soleta Networks <info@soleta.eu> + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <syslog.h> +#include <sys/stat.h> +#include <errno.h> +#include "boot.h" +#include "utils.h" + +#define OGRELIVE_TEMPLATE \ +"# Autogenerated by ogserver on %s - do not edit this file!\n" \ +"set ogserver=%s\n" \ +"set ogrepo=%s\n" \ +"set ogreliveversion=%s\n" \ +"set ogrelivedir=ogrelive/$ogreliveversion\n" \ +"set username=%s\n" \ +"set passwd=%s\n" \ +"\n" \ +"set timeout=0\n" \ +"set timeout_style=hidden\n" \ +"\n" \ +"echo \"checking for vmlinuz in cache...\"\n" \ +"set root=''\n" \ +"search --file --set root /boot/$ogreliveversion/vmlinuz\n" \ +"if [ \"$root\" == \"\" ]; then\n" \ +" echo \"no vmlinuz found in cache, booting from network\"\n" \ +" set default=1;\n" \ +"else\n" \ +" echo \"vmlinuz found, booting from cache\"\n" \ +" set default=0;\n" \ +"fi\n" \ +"\n" \ +"menuentry \"ogReLive HTTP boot\" {\n" \ +" insmod http\n" \ +" insmod net\n" \ +" net_bootp\n" \ +" linux (http,$ogrepo)/$ogrelivedir/vmlinuz ro boot=live quiet splash oglivedir=$ogrelivedir ip=$ogserver ogrepo=$ogrepo username=$username passwd=$passwd fetch=http://$ogrepo/$ogrelivedir/filesystem.squashfs\n" \ +" initrd (http,$ogrepo)/$ogrelivedir/initrd.img\n" \ +" boot\n" \ +"}\n" + +/* Same as OG_TFTP_BOOT_UEFI. */ +#define OG_BOOT_GRUB_DIR "/opt/opengnsys/tftpboot/grub" + +static void ogrelive_grub2_file_path(char *grub2_filename, + size_t grub2_filename_size, + const char *mac) +{ + snprintf(grub2_filename, grub2_filename_size, + OG_BOOT_GRUB_DIR"/01-%c%c:%c%c:%c%c:%c%c:%c%c:%c%c", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + mac[6], mac[7], mac[8], mac[9], mac[10], mac[11]); + str_tolower(grub2_filename); +} + +int ogrelive_generate_grub2_file(const struct og_boot_cfg *cfg, const char *mac) +{ + char grub2_tmp_filename[] = "/tmp/grub_template_XXXXXX"; + char grub2_filename[FILENAME_MAX] = {}; + time_t now = time(NULL); + char *date; + FILE *fp; + int fd; + + date = asctime(localtime(&now)); + date[strlen(date) - 1] = '\0'; + + fd = mkstemp(grub2_tmp_filename); + if (fd < 0) { + syslog(LOG_ERR, "Cannot open %s to %s (%s:%u)\n", + grub2_tmp_filename, grub2_filename, __FILE__, __LINE__); + return -1; + } + + fp = fdopen(fd, "w+"); + if (!fp) { + close(fd); + syslog(LOG_ERR, "Cannot open %s to %s (%s:%u)\n", + grub2_tmp_filename, grub2_filename, __FILE__, __LINE__); + return -1; + } + + fprintf(fp, OGRELIVE_TEMPLATE, date, + cfg->ogserver, cfg->ogrepo, cfg->ogrelivedir, cfg->username, cfg->passwd); + + fclose(fp); + + if (unlink(grub2_filename) < 0) { + if (errno != ENOENT) { + syslog(LOG_ERR, "Failed to delete %s (%s:%u)\n", + grub2_filename, __FILE__, __LINE__); + return -1; + } + } + + ogrelive_grub2_file_path(grub2_filename, sizeof(grub2_filename), mac); + + if (rename(grub2_tmp_filename, grub2_filename) < 0) { + unlink(grub2_tmp_filename); + syslog(LOG_ERR, "Failed to rename %s to %s (%s:%u)\n", + grub2_tmp_filename, grub2_filename, __FILE__, __LINE__); + return -1; + } + + chmod(grub2_filename, 0644); + + return 0; +} |