# #
#############################################################################*/
+#include <dirent.h>
#include <errno.h>
+#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <stdlib.h>
struct nw_daemon {
int nrefs;
- char config_path[PATH_MAX];
+ DIR* config_dir;
nw_config* config;
// Event Loop
return 0;
}
+/*
+ Configuration
+*/
+
+static int nw_daemon_config_open(nw_daemon* daemon, const char* path) {
+ daemon->config_dir = opendir(path);
+ if (!daemon->config_dir) {
+ ERROR("Could not open %s: %m\n", path);
+ return -errno;
+ }
+
+ return 0;
+}
+
+static FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode) {
+ int r;
+
+ // If no configuration path has been opened yet, we will open something
+ if (!daemon->config_dir) {
+ r = nw_daemon_config_open(daemon, CONFIG_DIR);
+ if (r < 0) {
+ errno = -r;
+ return NULL;
+ }
+ }
+
+ // Open the file
+ int fd = openat(dirfd(daemon->config_dir), path, 0);
+ if (fd < 0) {
+ ERROR("Could not open configuration file %s: %m\n", path);
+ return NULL;
+ }
+
+ // Return a file handle
+ return fdopen(fd, mode);
+}
+
static int nw_daemon_parse_argv(nw_daemon* daemon, int argc, char* argv[]) {
enum {
ARG_CONFIG,
switch (c) {
case ARG_CONFIG:
- r = nw_string_set(daemon->config_path, optarg);
+ r = nw_daemon_config_open(daemon, optarg);
if (r < 0)
return r;
-
break;
// Abort on any unrecognised option
}
static int nw_daemon_load_config(nw_daemon* daemon) {
+ FILE* f = NULL;
int r;
- // Read configuration file
- r = nw_config_create(&daemon->config, CONFIG_DIR "/settings");
- if (r)
- return r;
+ // Open the configuration file
+ f = nw_daemon_config_fopen(daemon, "settings", "r");
+ if (!f) {
+ r = -errno;
+ goto ERROR;
+ }
+
+ // Create configuration
+ r = nw_config_create(&daemon->config, NULL);
+ if (r < 0)
+ goto ERROR;
+
+ // Parse configuration
+ r = nw_config_readf(daemon->config, f);
+ if (r < 0)
+ goto ERROR;
+
+ERROR:
+ if (f)
+ fclose(f);
return r;
}
// Cleanup common objects
nw_daemon_cleanup(daemon);
+ if (daemon->config_dir)
+ closedir(daemon->config_dir);
if (daemon->stats_collector_event)
sd_event_source_unref(daemon->stats_collector_event);
if (daemon->bus)