aboutsummaryrefslogtreecommitdiff
path: root/src/npassd/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/npassd/session.c')
-rw-r--r--src/npassd/session.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/npassd/session.c b/src/npassd/session.c
new file mode 100644
index 0000000..e674bb7
--- /dev/null
+++ b/src/npassd/session.c
@@ -0,0 +1,81 @@
+#include <errno.h>
+#include <linux/limits.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <systemd/sd-bus.h>
+
+#include "npassd/common.h"
+#include "npassd/session.h"
+#include "util.h"
+
+static int handle_close(__attribute__((unused)) sd_bus_message *msg, void *data,
+ __attribute__((unused)) sd_bus_error *ret_error);
+
+static const sd_bus_vtable session_vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_METHOD("Close", "", "", handle_close,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_VTABLE_END,
+};
+
+static int handle_close(__attribute__((unused)) sd_bus_message *msg, void *data,
+ __attribute__((unused)) sd_bus_error *ret_error)
+{
+ int ret;
+
+ ret = session_free((struct session *)data);
+ if (ret < 0)
+ print_err("Failed to free session: %s", strerror(-ret));
+
+ return ret;
+}
+
+int session_slot_available(struct session *s, size_t n)
+{
+ static pthread_mutex_t lock;
+
+ pthread_mutex_lock(&lock);
+ for (size_t i = 0; i < n; i++) {
+ if (s[i].isactive == false) {
+ pthread_mutex_unlock(&lock);
+ return i;
+ }
+ }
+
+ pthread_mutex_unlock(&lock);
+ return -ENOMEM;
+}
+
+int session_new(sd_bus *bus, struct session *session, unsigned session_no)
+{
+ int ret;
+
+ snprintf(session->path, sizeof(session->path),
+ DBUS_OBJECT_PATH "/session/%d", session_no);
+ ret = sd_bus_add_object_vtable(bus, &session->slot, session->path,
+ SESSION_IFACE, session_vtable, session);
+ if (ret < 0)
+ print_err("Failed to create session: %s", strerror(-ret));
+ else
+ session->isactive = true;
+
+ return ret;
+}
+
+int session_free(struct session *s)
+{
+ if (!s->isactive)
+ return -EINVAL;
+
+ s->isactive = false;
+ sd_bus_slot_unref(s->slot);
+
+ return 0;
+}
+
+void session_init(struct session *s, size_t n)
+{
+ for (size_t i = 0; i < n; i++)
+ s[i].isactive = false;
+}