#include "bootspec-fundamental.h"
#include "bootspec.h"
+#include "chase-symlinks.h"
#include "conf-files.h"
#include "devnum-util.h"
#include "dirent-util.h"
return 1;
}
-static int boot_loader_read_conf_path(BootConfig *config, const char *path) {
+static int boot_loader_read_conf_path(BootConfig *config, const char *root, const char *path) {
+ _cleanup_free_ char *full = NULL;
_cleanup_fclose_ FILE *f = NULL;
+ int r;
assert(config);
assert(path);
- f = fopen(path, "re");
- if (!f) {
- if (errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open \"%s\": %m", path);
- }
+ r = chase_symlinks_and_fopen_unlocked(path, root, CHASE_PREFIX_ROOT, "re", &full, &f);
+ if (r == -ENOENT)
+ return 0;
+ if (r < 0)
+ return log_error_errno(r, "Failed to open '%s/%s': %m", root, path);
- return boot_loader_read_conf(config, f, path);
+ return boot_loader_read_conf(config, f, full);
}
static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
const char *dir) {
_cleanup_free_ DirectoryEntries *dentries = NULL;
+ _cleanup_free_ char *full = NULL;
_cleanup_close_ int dir_fd = -1;
int r;
assert(root);
assert(dir);
- dir_fd = open(dir, O_DIRECTORY|O_CLOEXEC);
- if (dir_fd < 0) {
- if (errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open '%s': %m", dir);
- }
+ dir_fd = chase_symlinks_and_open(dir, root, CHASE_PREFIX_ROOT, O_DIRECTORY|O_CLOEXEC, &full);
+ if (dir_fd == -ENOENT)
+ return 0;
+ if (dir_fd < 0)
+ return log_error_errno(dir_fd, "Failed to open '%s/%s': %m", root, dir);
r = readdir_all(dir_fd, RECURSE_DIR_IGNORE_DOT, &dentries);
if (r < 0)
- return log_error_errno(r, "Failed to read directory '%s': %m", dir);
+ return log_error_errno(r, "Failed to read directory '%s': %m", full);
for (size_t i = 0; i < dentries->n_entries; i++) {
const struct dirent *de = dentries->entries[i];
r = xfopenat(dir_fd, de->d_name, "re", 0, &f);
if (r < 0) {
- log_warning_errno(r, "Failed to open %s/%s, ignoring: %m", dir, de->d_name);
+ log_warning_errno(r, "Failed to open %s/%s, ignoring: %m", full, de->d_name);
continue;
}
if (r == 0) /* inode already seen or otherwise not relevant */
continue;
- r = boot_config_load_type1(config, f, root, dir, de->d_name);
+ r = boot_config_load_type1(config, f, root, full, de->d_name);
if (r == -ENOMEM) /* ignore all other errors */
return r;
}
const char *dir) {
_cleanup_(closedirp) DIR *d = NULL;
+ _cleanup_free_ char *full = NULL;
int r;
assert(config);
assert(dir);
- d = opendir(dir);
- if (!d) {
- if (errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open %s: %m", dir);
- }
+ r = chase_symlinks_and_opendir(dir, root, CHASE_PREFIX_ROOT, &full, &d);
+ if (r == -ENOENT)
+ return 0;
+ if (r < 0)
+ return log_error_errno(r, "Failed to open '%s/%s': %m", root, dir);
- FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read %s: %m", dir)) {
+ FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read %s: %m", full)) {
_cleanup_free_ char *j = NULL, *osrelease = NULL, *cmdline = NULL;
_cleanup_close_ int fd = -1;
fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
if (fd < 0) {
- log_warning_errno(errno, "Failed to open %s/%s, ignoring: %m", dir, de->d_name);
+ log_warning_errno(errno, "Failed to open %s/%s, ignoring: %m", full, de->d_name);
continue;
}
if (r == 0) /* inode already seen or otherwise not relevant */
continue;
- j = path_join(dir, de->d_name);
+ j = path_join(full, de->d_name);
if (!j)
return log_oom();
const char *esp_path,
const char *xbootldr_path) {
- const char *p;
int r;
assert(config);
if (esp_path) {
- p = strjoina(esp_path, "/loader/loader.conf");
- r = boot_loader_read_conf_path(config, p);
+ r = boot_loader_read_conf_path(config, esp_path, "/loader/loader.conf");
if (r < 0)
return r;
- p = strjoina(esp_path, "/loader/entries");
- r = boot_entries_find_type1(config, esp_path, p);
+ r = boot_entries_find_type1(config, esp_path, "/loader/entries");
if (r < 0)
return r;
- p = strjoina(esp_path, "/EFI/Linux/");
- r = boot_entries_find_unified(config, esp_path, p);
+ r = boot_entries_find_unified(config, esp_path, "/EFI/Linux/");
if (r < 0)
return r;
}
if (xbootldr_path) {
- p = strjoina(xbootldr_path, "/loader/entries");
- r = boot_entries_find_type1(config, xbootldr_path, p);
+ r = boot_entries_find_type1(config, xbootldr_path, "/loader/entries");
if (r < 0)
return r;
- p = strjoina(xbootldr_path, "/EFI/Linux/");
- r = boot_entries_find_unified(config, xbootldr_path, p);
+ r = boot_entries_find_unified(config, xbootldr_path, "/EFI/Linux/");
if (r < 0)
return r;
}
return 0;
}
-static int boot_entry_file_check(const char *root, const char *p) {
- _cleanup_free_ char *path = NULL;
-
- path = path_join(root, p);
- if (!path)
- return log_oom();
-
- return RET_NERRNO(access(path, F_OK));
-}
-
BootEntry* boot_config_find_entry(BootConfig *config, const char *id) {
assert(config);
assert(id);
return NULL;
}
-static void boot_entry_file_list(const char *field, const char *root, const char *p, int *ret_status) {
- int status = boot_entry_file_check(root, p);
+static void boot_entry_file_list(
+ const char *field,
+ const char *root,
+ const char *p,
+ int *ret_status) {
+
+ assert(p);
+ assert(ret_status);
+
+ int status = chase_symlinks_and_access(p, root, CHASE_PREFIX_ROOT, F_OK, NULL, NULL);
printf("%13s%s ", strempty(field), field ? ":" : " ");
if (status < 0) {