#include <unistd.h>
#include "alloc-util.h"
+#include "chase.h"
#include "color-util.h"
#include "conf-files.h"
#include "constants.h"
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
+#include "fs-util.h"
#include "log.h"
#include "path-util.h"
#include "pretty-print.h"
return terminal_urlify(url, text, ret);
}
-static int cat_file(const char *filename, bool *newline, CatFlags flags) {
+static int cat_file(const ConfFile *c, bool *newline, CatFlags flags) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *urlified = NULL, *section = NULL, *old_section = NULL;
int r;
- assert(filename);
+ assert(c);
+ assert(c->original_path);
+ assert(c->resolved_path);
+ assert(c->fd >= 0);
if (newline) {
if (*newline)
*newline = true;
}
- r = terminal_urlify_path(filename, NULL, &urlified);
+ bool resolved = !path_equal(c->original_path, c->resolved_path);
+
+ r = terminal_urlify_path(c->resolved_path, NULL, &urlified);
if (r < 0)
- return log_error_errno(r, "Failed to urlify path \"%s\": %m", filename);
+ return log_error_errno(r, "Failed to urlify path \"%s\": %m", c->resolved_path);
- printf("%s# %s%s\n",
+ printf("%s# %s%s%s%s\n",
ansi_highlight_blue(),
+ resolved ? c->original_path : "",
+ resolved ? " -> " : "",
urlified,
ansi_normal());
- f = fopen(filename, "re");
+ f = fopen(FORMAT_PROC_FD_PATH(c->fd), "re");
if (!f)
- return log_error_errno(errno, "Failed to open \"%s\": %m", filename);
+ return log_error_errno(errno, "Failed to open \"%s\": %m", c->resolved_path);
for (bool continued = false;;) {
_cleanup_free_ char *line = NULL;
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
- return log_error_errno(r, "Failed to read \"%s\": %m", filename);
+ return log_error_errno(r, "Failed to read \"%s\": %m", c->resolved_path);
if (r == 0)
break;
return 0;
}
-int cat_files(const char *file, char **dropins, CatFlags flags) {
+int cat_files_full(const ConfFile *file, ConfFile * const *dropins, size_t n_dropins, CatFlags flags) {
bool newline = false;
int ret = 0;
+ assert(dropins || n_dropins == 0);
+
if (file)
ret = cat_file(file, &newline, flags);
+ FOREACH_ARRAY(i, dropins, n_dropins)
+ RET_GATHER(ret, cat_file(*i, &newline, flags));
+
+ return ret;
+}
+
+static int cat_file_by_path(const char *p, bool *newline, CatFlags flags) {
+ _cleanup_(conf_file_freep) ConfFile *c = NULL;
+ int r;
+
+ assert(p);
+
+ r = conf_file_new(p, /* root = */ NULL, CHASE_MUST_BE_REGULAR, &c);
+ if (r < 0)
+ return log_error_errno(r, "Failed to chase '%s': %m", p);
+
+ return cat_file(c, newline, flags);
+}
+
+int cat_files(const char *file, char **dropins, CatFlags flags) {
+ bool newline = false;
+ int ret = 0;
+
+ if (file)
+ ret = cat_file_by_path(file, &newline, flags);
+
STRV_FOREACH(path, dropins)
- RET_GATHER(ret, cat_file(*path, &newline, flags));
+ RET_GATHER(ret, cat_file_by_path(*path, &newline, flags));
return ret;
}
}
int conf_files_cat(const char *root, const char *name, CatFlags flags) {
- _cleanup_strv_free_ char **dirs = NULL, **files = NULL;
- _cleanup_free_ char *path = NULL;
+ _cleanup_strv_free_ char **dirs = NULL;
char **prefixes = NULL; /* explicit initialization to appease gcc */
bool is_collection;
const char *extension;
}
/* First locate the main config file, if any */
+ _cleanup_(conf_file_freep) ConfFile *c = NULL;
if (!is_collection) {
STRV_FOREACH(prefix, prefixes) {
- path = path_join(root, *prefix, name);
- if (!path)
+ _cleanup_free_ char *p = path_join(*prefix, name);
+ if (!p)
return log_oom();
- if (access(path, F_OK) == 0)
+
+ if (conf_file_new(p, root, CHASE_MUST_BE_REGULAR, &c) >= 0)
break;
- path = mfree(path);
}
- if (!path)
+ if (!c)
printf("%s# Main configuration file %s not found%s\n",
ansi_highlight_magenta(),
name,
}
/* Then locate the drop-ins, if any */
- r = conf_files_list_strv(&files, extension, root, 0, (const char* const*) dirs);
+ ConfFile **dropins = NULL;
+ size_t n_dropins = 0;
+ CLEANUP_ARRAY(dropins, n_dropins, conf_file_free_many);
+ r = conf_files_list_strv_full(extension, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, (const char* const*) dirs, &dropins, &n_dropins);
if (r < 0)
return log_error_errno(r, "Failed to query file list: %m");
if (is_collection)
flags |= CAT_FORMAT_HAS_SECTIONS;
- return cat_files(path, files, flags);
+ return cat_files_full(c, dropins, n_dropins, flags);
}
int terminal_tint_color(double hue, char **ret) {