#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#include <libudev.h>
#include <systemd/sd-daemon.h>
#include "netlink.h"
#include "queue.h"
#include "sensors.h"
+#include "string.h"
#include "source.h"
#include "sources.h"
+#include "util.h"
struct td_daemon {
td_ctx* ctx;
// Netlink
td_netlink* netlink;
+
+ // Path
+ char path[PATH_MAX];
};
static int td_daemon_init(sd_event_source* source, void* data) {
free(self);
}
-int td_daemon_create(td_daemon** daemon, td_ctx* ctx, char** enabled_sources) {
+int td_daemon_create(td_daemon** daemon, td_ctx* ctx, const char* path, char** enabled_sources) {
td_daemon* self = NULL;
int r;
// Store a reference to the context
self->ctx = td_ctx_ref(ctx);
+ // Set the path
+ r = td_daemon_set_path(self, path);
+ if (r < 0)
+ goto ERROR;
+
// Store the enabled sources
self->enabled_sources = enabled_sources;
return NULL;
}
+const char* td_daemon_get_path(td_daemon* self) {
+ if (unlikely(!*self->path))
+ return NULL;
+
+ return self->path;
+}
+
+static int td_daemon_check_path(td_daemon* self) {
+ struct stat st;
+ int fd = -EBADF;
+ int r;
+
+ // Stat the directory
+ r = stat(self->path, &st);
+ if (r < 0) {
+ switch (errno) {
+ case ENOENT:
+ ERROR(self->ctx, "%s does not exist\n", self->path);
+ r = -ENOENT;
+ break;
+
+ default:
+ ERROR(self->ctx, "Failed to stat %s: %m\n", self->path);
+ r = -errno;
+ break;
+ }
+
+ goto ERROR;
+ }
+
+ // Check if this is a directory
+ if (!S_ISDIR(st.st_mode)) {
+ ERROR(self->ctx, "%s is not a directory\n", self->path);
+ r = -ENOTDIR;
+ goto ERROR;
+ }
+
+ // Check if we have permission to write
+ fd = open(self->path, O_WRONLY|O_TMPFILE, 0600);
+ if (fd < 0) {
+ ERROR(self->ctx, "Cannot write to %s: %m\n", self->path);
+ r = -errno;
+ goto ERROR;
+ }
+
+ERROR:
+ if (fd >= 0)
+ close(fd);
+
+ return r;
+}
+
+int td_daemon_set_path(td_daemon* self, const char* path) {
+ int r;
+
+ // Use a default path if nothing has been set
+ if (!path)
+ path = DATABASE_PATH;
+
+ // Store the path
+ r = td_string_set(self->path, path);
+ if (r < 0)
+ return r;
+
+ // Check if the path exists
+ return td_daemon_check_path(self);
+}
+
sd_event* td_daemon_loop(td_daemon* self) {
return sd_event_ref(self->loop);
}
#include "source.h"
#include "sources.h"
-int td_daemon_create(td_daemon** daemon, td_ctx* ctx, char** enabled_sources);
+int td_daemon_create(td_daemon** daemon, td_ctx* ctx,
+ const char* path, char** enabled_sources);
td_daemon* td_daemon_ref(td_daemon* daemon);
td_daemon* td_daemon_unref(td_daemon* daemon);
+const char* td_daemon_get_path(td_daemon* self);
+int td_daemon_set_path(td_daemon* self, const char* path);
+
sd_event* td_daemon_loop(td_daemon* self);
struct udev* td_daemon_get_udev(td_daemon* self);
td_sources* td_daemon_get_sources(td_daemon* self);