diff options
author | Kay Sievers <kay@vrfy.org> | 2013-02-08 17:24:43 +0100 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2013-02-11 19:35:52 +0100 |
commit | 7b4d7cc08283e5485dcfa49ffdf1915de1d5e81b (patch) | |
tree | fc73d48c2f124bf27a3c47979a3e28f825eb8902 /src/boot/boot-loader.c | |
parent | c937e0d5c579863677e0fcb5508517f7714c332d (diff) |
bootctl: add boot loader and firmware interface tool
Diffstat (limited to 'src/boot/boot-loader.c')
-rw-r--r-- | src/boot/boot-loader.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/boot/boot-loader.c b/src/boot/boot-loader.c new file mode 100644 index 0000000000..bd563da226 --- /dev/null +++ b/src/boot/boot-loader.c @@ -0,0 +1,131 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stdlib.h> +#include <stdbool.h> +#include <unistd.h> +#include <getopt.h> +#include <locale.h> +#include <string.h> +#include <ctype.h> +#include <sys/timex.h> + +#include "boot.h" +#include "boot-loader.h" +#include "build.h" +#include "util.h" +#include "strv.h" +#include "conf-files.h" + +static char *loader_fragment_read_title(const char *fragment) { + FILE *f; + char line[LINE_MAX]; + char *title = NULL; + + f = fopen(fragment, "re"); + if (!f) + return NULL; + + while (fgets(line, sizeof(line), f) != NULL) { + char *s; + size_t l; + + l = strlen(line); + if (l < 1) + continue; + if (line[l-1] == '\n') + line[l-1] = '\0'; + + s = line; + while (isspace(s[0])) + s++; + + if (s[0] == '#') + continue; + + if (!startswith(s, "title")) + continue; + + s += strlen("title"); + if (!isspace(s[0])) + continue; + while (isspace(s[0])) + s++; + + title = strdup(s); + break; + } + + fclose(f); + return title; +} + +int boot_loader_read_entries(struct boot_info *info) { + _cleanup_strv_free_ char **files = NULL; + static const char *loader_dir[] = { "/boot/loader/entries", NULL}; + unsigned int count; + unsigned int i; + int err; + + err = conf_files_list_strv(&files, ".conf", NULL, loader_dir); + if (err < 0) + return err; + + count = strv_length(files); + info->loader_entries = new0(struct boot_info_entry, count); + if (!info->loader_entries) + return -ENOMEM; + + for (i = 0; i < count; i++) { + info->loader_entries[i].title = loader_fragment_read_title(files[i]); + info->loader_entries[i].path = strdup(files[i]); + if (!info->loader_entries[i].title || !info->loader_entries[i].path) { + free(info->loader_entries[i].title); + free(info->loader_entries[i].path); + return -ENOMEM; + } + info->loader_entries_count++; + } + return 0; +} + +int boot_loader_find_active_entry(struct boot_info *info, const char *loader_active) { + char *fn; + unsigned int i; + + if (!loader_active) + return -ENOENT; + if (info->loader_entries_count == 0) + return -ENOENT; + + if (asprintf(&fn, "/boot/loader/entries/%s.conf", loader_active) < 0) + return -ENOMEM; + + for (i = 0; i < info->loader_entries_count; i++) { + if (strcmp(fn, info->loader_entries[i].path) == 0) { + info->loader_entry_active = i; + break; + } + } + + free(fn); + return 0; +} |