From: Andreas Reichel <[email protected]> For unit test support, code must be more modular. This also avoids inline functions and static functions where possible.
Signed-off-by: Andreas Reichel <[email protected]> --- Makefile.am | 4 +- env/env_api_fat.c | 224 ++-------------------------------------- env/env_config_file.c | 90 ++++++++++++++++ env/env_config_partitions.c | 83 +++++++++++++++ env/env_disk_utils.c | 99 ++++++++++++++++++ include/env_config_file.h | 20 ++++ include/env_config_partitions.h | 18 ++++ include/env_disk_utils.h | 20 ++++ 8 files changed, 339 insertions(+), 219 deletions(-) create mode 100644 env/env_config_file.c create mode 100644 env/env_config_partitions.c create mode 100644 env/env_disk_utils.c create mode 100644 include/env_config_file.h create mode 100644 include/env_config_partitions.h create mode 100644 include/env_disk_utils.h diff --git a/Makefile.am b/Makefile.am index 51e2658..1e0dc1c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,6 +72,9 @@ lib_LIBRARIES = libebgenv.a libebgenv_a_SOURCES = \ env/@[email protected] \ env/env_api.c \ + env/env_config_file.c \ + env/env_config_partitions.c \ + env/env_disk_utils.c \ env/uservars.c \ tools/ebgpart.c @@ -91,7 +94,6 @@ pkginclude_HEADERS = \ bin_PROGRAMS = bg_setenv bg_setenv_SOURCES = \ - tools/ebgpart.c \ tools/bg_setenv.c bg_setenv_CFLAGS = \ diff --git a/env/env_api_fat.c b/env/env_api_fat.c index 653d3f8..a344fcb 100644 --- a/env/env_api_fat.c +++ b/env/env_api_fat.c @@ -11,11 +11,12 @@ */ #include "env_api.h" -#include "ebgpart.h" +#include "env_disk_utils.h" +#include "env_config_partitions.h" +#include "env_config_file.h" #include "uservars.h" #include "test-interface.h" - -const char *tmp_mnt_dir = "/tmp/mnt-XXXXXX"; +#include "ebgpart.h" bool bgenv_verbosity = false; @@ -46,219 +47,6 @@ void bgenv_be_verbose(bool v) ebgpart_beverbose(v); } -static char *get_mountpoint(char *devpath) -{ - struct mntent *part = NULL; - FILE *mtab = NULL; - - if ((mtab = setmntent("/proc/mounts", "r")) == NULL) - return NULL; - - while ((part = getmntent(mtab)) != NULL) { - if ((part->mnt_fsname != NULL) && - (strcmp(part->mnt_fsname, devpath)) == 0) { - char *mntpoint; - - if (!(mntpoint = - malloc(strlen(part->mnt_dir) + 1))) { - break; - }; - strncpy(mntpoint, part->mnt_dir, - strlen(part->mnt_dir) + 1); - return mntpoint; - } - } - endmntent(mtab); - - return NULL; -} - -__attribute__((noinline)) -bool mount_partition(CONFIG_PART *cfgpart) -{ - char tmpdir_template[256]; - char *mountpoint; - (void)snprintf(tmpdir_template, 256, "%s", tmp_mnt_dir); - if (!cfgpart) { - return false; - } - if (!cfgpart->devpath) { - return false; - } - if (!(mountpoint = mkdtemp(tmpdir_template))) { - VERBOSE(stderr, "Error creating temporary mount point.\n"); - return false; - } - if (mount(cfgpart->devpath, mountpoint, "vfat", 0, "")) { - VERBOSE(stderr, "Error mounting to temporary mount point.\n"); - if (rmdir(tmpdir_template)) { - VERBOSE(stderr, - "Error deleting temporary directory.\n"); - } - return false; - } - cfgpart->mountpoint = (char *)malloc(strlen(mountpoint) + 1); - if (!cfgpart->mountpoint) { - VERBOSE(stderr, "Error, out of memory.\n"); - return false; - } - strncpy(cfgpart->mountpoint, mountpoint, strlen(mountpoint) + 1); - return true; -} - -static void unmount_partition(CONFIG_PART *cfgpart) -{ - if (!cfgpart) { - return; - } - if (!cfgpart->mountpoint) { - return; - } - if (umount(cfgpart->mountpoint)) { - VERBOSE(stderr, "Error unmounting temporary mountpoint %s.\n", - cfgpart->mountpoint); - } - if (rmdir(cfgpart->mountpoint)) { - VERBOSE(stderr, "Error deleting temporary directory %s.\n", - cfgpart->mountpoint); - } - free(cfgpart->mountpoint); - cfgpart->mountpoint = NULL; -} - -static FILE *open_config_file(CONFIG_PART *cfgpart, char *mode) -{ - char *configfilepath; - configfilepath = (char *)malloc(strlen(FAT_ENV_FILENAME) + - strlen(cfgpart->mountpoint) + 2); - if (!configfilepath) { - return NULL; - } - strncpy(configfilepath, cfgpart->mountpoint, - strlen(cfgpart->mountpoint) + 1); - strncat(configfilepath, "/", 1); - strncat(configfilepath, FAT_ENV_FILENAME, strlen(FAT_ENV_FILENAME)); - VERBOSE(stdout, "Probing config file at %s.\n", configfilepath); - FILE *config = fopen(configfilepath, mode); - free(configfilepath); - return config; -} - -__attribute__((noinline)) -bool probe_config_file(CONFIG_PART *cfgpart) -{ - bool do_unmount = false; - if (!cfgpart) { - return false; - } - printf_debug("Checking device: %s\n", cfgpart->devpath); - if (!(cfgpart->mountpoint = get_mountpoint(cfgpart->devpath))) { - /* partition is not mounted */ - cfgpart->not_mounted = true; - VERBOSE(stdout, "Partition %s is not mounted.\n", - cfgpart->devpath); - if (!mount_partition(cfgpart)) { - return false; - } - do_unmount = true; - } else { - cfgpart->not_mounted = false; - } - - if (cfgpart->mountpoint) { - /* partition is mounted to mountpoint, either before or by this - * program */ - VERBOSE(stdout, "Partition %s is mounted to %s.\n", - cfgpart->devpath, cfgpart->mountpoint); - bool result = false; - FILE *config; - if (!(config = open_config_file(cfgpart, "rb"))) { - printf_debug( - "Could not open config file on partition %s.\n", - FAT_ENV_FILENAME); - } else { - result = true; - if (fclose(config)) { - VERBOSE(stderr, "Error closing config file on " - "partition %s.\n", - cfgpart->devpath); - } - } - if (do_unmount) { - unmount_partition(cfgpart); - } - return result; - } - return false; -} - -bool probe_config_partitions(CONFIG_PART *cfgpart) -{ - PedDevice *dev = NULL; - char devpath[4096]; - int count = 0; - - if (!cfgpart) { - return false; - } - - ped_device_probe_all(); - - while ((dev = ped_device_get_next(dev))) { - printf_debug("Device: %s\n", dev->model); - PedDisk *pd = ped_disk_new(dev); - if (!pd) { - continue; - } - PedPartition *part = pd->part_list; - while (part) { - if (!part->fs_type || !part->fs_type->name || - (strcmp(part->fs_type->name, "fat12") != 0 && - strcmp(part->fs_type->name, "fat16") != 0 && - strcmp(part->fs_type->name, "fat32") != 0)) { - part = ped_disk_next_partition(pd, part); - continue; - } - if (strncmp("/dev/mmcblk", dev->path, 11) == 0) { - (void)snprintf(devpath, 4096, "%sp%u", - dev->path, part->num); - } else { - (void)snprintf(devpath, 4096, "%s%u", - dev->path, part->num); - } - if (!cfgpart[count].devpath) { - cfgpart[count].devpath = - malloc(strlen(devpath) + 1); - if (!cfgpart[count].devpath) { - VERBOSE(stderr, "Out of memory."); - return false; - } - } - strncpy(cfgpart[count].devpath, devpath, - strlen(devpath) + 1); - if (probe_config_file(&cfgpart[count])) { - printf_debug("%s", "Environment file found.\n"); - if (count >= ENV_NUM_CONFIG_PARTS) { - VERBOSE(stderr, "Error, there are " - "more than %d config " - "partitions.\n", - ENV_NUM_CONFIG_PARTS); - return false; - } - count++; - } - part = ped_disk_next_partition(pd, part); - } - } - if (count < ENV_NUM_CONFIG_PARTS) { - VERBOSE(stderr, - "Error, less than %d config partitions exist.\n", - ENV_NUM_CONFIG_PARTS); - return false; - } - return true; -} - bool read_env(CONFIG_PART *part, BG_ENVDATA *env) { if (!part) { @@ -286,7 +74,7 @@ bool read_env(CONFIG_PART *part, BG_ENVDATA *env) } result = false; } - if (fclose(config)) { + if (close_config_file(config)) { VERBOSE(stderr, "Error closing environment file after reading.\n"); }; @@ -321,7 +109,7 @@ bool write_env(CONFIG_PART *part, BG_ENVDATA *env) part->devpath); result = false; } - if (fclose(config)) { + if (close_config_file(config)) { VERBOSE(stderr, "Error closing environment file after writing.\n"); result = false; diff --git a/env/env_config_file.c b/env/env_config_file.c new file mode 100644 index 0000000..3a802f2 --- /dev/null +++ b/env/env_config_file.c @@ -0,0 +1,90 @@ +/* + * EFI Boot Guard + * + * Copyright (c) Siemens AG, 2017 + * + * Authors: + * Andreas Reichel <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include <stdlib.h> +#include <stdio.h> +#include "env_api.h" +#include "env_disk_utils.h" +#include "env_config_file.h" + +FILE *open_config_file(CONFIG_PART *cfgpart, char *mode) +{ + char *configfilepath; + configfilepath = (char *)malloc(strlen(FAT_ENV_FILENAME) + + strlen(cfgpart->mountpoint) + 2); + if (!configfilepath) { + return NULL; + } + strncpy(configfilepath, cfgpart->mountpoint, + strlen(cfgpart->mountpoint) + 1); + strncat(configfilepath, "/", 1); + strncat(configfilepath, FAT_ENV_FILENAME, strlen(FAT_ENV_FILENAME)); + VERBOSE(stdout, "Probing config file at %s.\n", configfilepath); + FILE *config = fopen(configfilepath, mode); + free(configfilepath); + return config; +} + +int close_config_file(FILE *config_file_handle) +{ + if (config_file_handle) + { + return fclose(config_file_handle); + } +} + +bool probe_config_file(CONFIG_PART *cfgpart) +{ + bool do_unmount = false; + if (!cfgpart) { + return false; + } + printf_debug("Checking device: %s\n", cfgpart->devpath); + if (!(cfgpart->mountpoint = get_mountpoint(cfgpart->devpath))) { + /* partition is not mounted */ + cfgpart->not_mounted = true; + VERBOSE(stdout, "Partition %s is not mounted.\n", + cfgpart->devpath); + if (!mount_partition(cfgpart)) { + return false; + } + do_unmount = true; + } else { + cfgpart->not_mounted = false; + } + + if (cfgpart->mountpoint) { + /* partition is mounted to mountpoint, either before or by this + * program */ + VERBOSE(stdout, "Partition %s is mounted to %s.\n", + cfgpart->devpath, cfgpart->mountpoint); + bool result = false; + FILE *config; + if (!(config = open_config_file(cfgpart, "rb"))) { + printf_debug( + "Could not open config file on partition %s.\n", + FAT_ENV_FILENAME); + } else { + result = true; + if (fclose(config)) { + VERBOSE(stderr, "Error closing config file on " + "partition %s.\n", + cfgpart->devpath); + } + } + if (do_unmount) { + unmount_partition(cfgpart); + } + return result; + } + return false; +} diff --git a/env/env_config_partitions.c b/env/env_config_partitions.c new file mode 100644 index 0000000..b4ffc6c --- /dev/null +++ b/env/env_config_partitions.c @@ -0,0 +1,83 @@ +/* + * EFI Boot Guard + * + * Copyright (c) Siemens AG, 2017 + * + * Authors: + * Andreas Reichel <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include "env_api.h" +#include "ebgpart.h" +#include "env_config_partitions.h" +#include "env_config_file.h" + +bool probe_config_partitions(CONFIG_PART *cfgpart) +{ + PedDevice *dev = NULL; + char devpath[4096]; + int count = 0; + + if (!cfgpart) { + return false; + } + + ped_device_probe_all(); + + while ((dev = ped_device_get_next(dev))) { + printf_debug("Device: %s\n", dev->model); + PedDisk *pd = ped_disk_new(dev); + if (!pd) { + continue; + } + PedPartition *part = pd->part_list; + while (part) { + if (!part->fs_type || !part->fs_type->name || + (strcmp(part->fs_type->name, "fat12") != 0 && + strcmp(part->fs_type->name, "fat16") != 0 && + strcmp(part->fs_type->name, "fat32") != 0)) { + part = ped_disk_next_partition(pd, part); + continue; + } + if (strncmp("/dev/mmcblk", dev->path, 11) == 0) { + (void)snprintf(devpath, 4096, "%sp%u", + dev->path, part->num); + } else { + (void)snprintf(devpath, 4096, "%s%u", + dev->path, part->num); + } + if (!cfgpart[count].devpath) { + cfgpart[count].devpath = + malloc(strlen(devpath) + 1); + if (!cfgpart[count].devpath) { + VERBOSE(stderr, "Out of memory."); + return false; + } + } + strncpy(cfgpart[count].devpath, devpath, + strlen(devpath) + 1); + if (probe_config_file(&cfgpart[count])) { + printf_debug("%s", "Environment file found.\n"); + if (count >= ENV_NUM_CONFIG_PARTS) { + VERBOSE(stderr, "Error, there are " + "more than %d config " + "partitions.\n", + ENV_NUM_CONFIG_PARTS); + return false; + } + count++; + } + part = ped_disk_next_partition(pd, part); + } + } + if (count < ENV_NUM_CONFIG_PARTS) { + VERBOSE(stderr, + "Error, less than %d config partitions exist.\n", + ENV_NUM_CONFIG_PARTS); + return false; + } + return true; +} diff --git a/env/env_disk_utils.c b/env/env_disk_utils.c new file mode 100644 index 0000000..344cd59 --- /dev/null +++ b/env/env_disk_utils.c @@ -0,0 +1,99 @@ +/* + * EFI Boot Guard + * + * Copyright (c) Siemens AG, 2017 + * + * Authors: + * Andreas Reichel <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include <stdlib.h> +#include <mntent.h> +#include <string.h> +#include "env_api.h" +#include "env_disk_utils.h" + +const char *tmp_mnt_dir = "/tmp/mnt-XXXXXX"; + +char *get_mountpoint(char *devpath) +{ + struct mntent *part = NULL; + FILE *mtab = NULL; + + if ((mtab = setmntent("/proc/mounts", "r")) == NULL) + return NULL; + + while ((part = getmntent(mtab)) != NULL) { + if ((part->mnt_fsname != NULL) && + (strcmp(part->mnt_fsname, devpath)) == 0) { + char *mntpoint; + + if (!(mntpoint = + malloc(strlen(part->mnt_dir) + 1))) { + break; + }; + strncpy(mntpoint, part->mnt_dir, + strlen(part->mnt_dir) + 1); + return mntpoint; + } + } + endmntent(mtab); + + return NULL; +} + +bool mount_partition(CONFIG_PART *cfgpart) +{ + char tmpdir_template[256]; + char *mountpoint; + (void)snprintf(tmpdir_template, 256, "%s", tmp_mnt_dir); + if (!cfgpart) { + return false; + } + if (!cfgpart->devpath) { + return false; + } + if (!(mountpoint = mkdtemp(tmpdir_template))) { + VERBOSE(stderr, "Error creating temporary mount point.\n"); + return false; + } + if (mount(cfgpart->devpath, mountpoint, "vfat", 0, "")) { + VERBOSE(stderr, "Error mounting to temporary mount point.\n"); + if (rmdir(tmpdir_template)) { + VERBOSE(stderr, + "Error deleting temporary directory.\n"); + } + return false; + } + cfgpart->mountpoint = (char *)malloc(strlen(mountpoint) + 1); + if (!cfgpart->mountpoint) { + VERBOSE(stderr, "Error, out of memory.\n"); + return false; + } + strncpy(cfgpart->mountpoint, mountpoint, strlen(mountpoint) + 1); + return true; +} + +void unmount_partition(CONFIG_PART *cfgpart) +{ + if (!cfgpart) { + return; + } + if (!cfgpart->mountpoint) { + return; + } + if (umount(cfgpart->mountpoint)) { + VERBOSE(stderr, "Error unmounting temporary mountpoint %s.\n", + cfgpart->mountpoint); + } + if (rmdir(cfgpart->mountpoint)) { + VERBOSE(stderr, "Error deleting temporary directory %s.\n", + cfgpart->mountpoint); + } + free(cfgpart->mountpoint); + cfgpart->mountpoint = NULL; +} + diff --git a/include/env_config_file.h b/include/env_config_file.h new file mode 100644 index 0000000..b172142 --- /dev/null +++ b/include/env_config_file.h @@ -0,0 +1,20 @@ +/* + * EFI Boot Guard + * + * Copyright (c) Siemens AG, 2017 + * + * Authors: + * Andreas Reichel <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#ifndef __ENV_CONFIG_FILE_H__ +#define __ENV_CONFIG_FILE_H__ + +FILE *open_config_file(CONFIG_PART *cfgpart, char *mode); +int close_config_file(FILE *config_file_handle); +bool probe_config_file(CONFIG_PART *cfgpart); + +#endif // __ENV_CONFIG_FILE_H__ diff --git a/include/env_config_partitions.h b/include/env_config_partitions.h new file mode 100644 index 0000000..01f8d94 --- /dev/null +++ b/include/env_config_partitions.h @@ -0,0 +1,18 @@ +/* + * EFI Boot Guard + * + * Copyright (c) Siemens AG, 2017 + * + * Authors: + * Andreas Reichel <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#ifndef __ENV_CONFIG_PARTITIONS_H__ +#define __ENV_CONFIG_PARTITIONS_H__ + +bool probe_config_partitions(CONFIG_PART *cfgpart); + +#endif // __ENV_CONFIG_PARTITIONS_H__ diff --git a/include/env_disk_utils.h b/include/env_disk_utils.h new file mode 100644 index 0000000..9ceb019 --- /dev/null +++ b/include/env_disk_utils.h @@ -0,0 +1,20 @@ +/* + * EFI Boot Guard + * + * Copyright (c) Siemens AG, 2017 + * + * Authors: + * Andreas Reichel <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#ifndef __ENV_DISK_UTILS_H__ +#define __ENV_DISK_UTILS_H__ + +char *get_mountpoint(char *devpath); +bool mount_partition(CONFIG_PART *cfgpart); +void unmount_partition(CONFIG_PART *cfgpart); + +#endif // __ENV_DISK_UTILS_H__ -- 2.14.2 -- You received this message because you are subscribed to the Google Groups "EFI Boot Guard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/efibootguard-dev/20171102155648.16140-5-andreas.reichel.ext%40siemens.com. For more options, visit https://groups.google.com/d/optout.
