aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/npassd/service.c26
-rw-r--r--src/npassd/session.c101
2 files changed, 70 insertions, 57 deletions
diff --git a/src/npassd/service.c b/src/npassd/service.c
index b294cf0..b179735 100644
--- a/src/npassd/service.c
+++ b/src/npassd/service.c
@@ -1,5 +1,6 @@
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <systemd/sd-bus.h>
#include "npassd/common.h"
@@ -33,9 +34,10 @@ static int handle_open_session(sd_bus_message *msg, void *data,
sd_bus_error *ret_error)
{
struct service *service = data;
- int ret, session_slot_no;
+ struct session *session;
const char *sender;
char *algo;
+ int ret;
ret = sd_bus_message_read(msg, "s", &algo);
if (ret < 0)
@@ -48,27 +50,21 @@ static int handle_open_session(sd_bus_message *msg, void *data,
return -ENOTSUP;
}
- session_slot_no = session_slot_available(service->session, MAX_SESSION);
- if (session_slot_no < 0) {
- print_err("No free slot available: %s",
- strerror(-session_slot_no));
- return ret;
- }
-
sender = sd_bus_message_get_sender(msg);
- ret = session_new(service->bus, &service->session[session_slot_no],
- session_slot_no, sender);
+ ret = session_new(service->bus, &session, sender);
if (ret < 0)
return ret;
- return sd_bus_reply_method_return(
- msg, "vo", "s", NULL, service->session[session_slot_no].path);
+ LIST_INSERT_HEAD(&service->sessions, session, dlist);
+ return sd_bus_reply_method_return(msg, "vo", "s", NULL, session->path);
}
void service_free(struct service *service)
{
- for (int i = 0; i < MAX_SESSION; i++)
- session_free(&service->session[i]);
+ struct session *p;
+
+ LIST_FOREACH(p, &service->sessions, dlist)
+ session_free(p);
sd_bus_slot_unref(service->slot);
}
@@ -78,7 +74,7 @@ int service_init(sd_bus *bus, struct service *service)
int ret;
service->bus = bus;
- session_init(service->session, MAX_SESSION);
+ LIST_INIT(&service->sessions);
ret = sd_bus_add_object_vtable(service->bus, &service->slot,
DBUS_OBJECT_PATH, SERVICE_IFACE,
diff --git a/src/npassd/session.c b/src/npassd/session.c
index 8d2ecf7..1807ea1 100644
--- a/src/npassd/session.c
+++ b/src/npassd/session.c
@@ -3,6 +3,7 @@
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
+#include <stdlib.h>
#include <systemd/sd-bus.h>
#include "npassd/common.h"
@@ -40,7 +41,9 @@ static int handle_nameownerchanged(sd_bus_message *msg, void *data,
if (ret)
return 0;
+ LIST_REMOVE(session, dlist);
session_free(session);
+
return 0;
}
@@ -58,56 +61,87 @@ static int handle_close(sd_bus_message *msg, void *data,
return -EPERM;
}
- ret = session_free((struct session *)data);
- if (ret < 0)
- print_err("Failed to free session: %s", strerror(-ret));
+ LIST_REMOVE(session, dlist);
+ session_free(session);
return sd_bus_reply_method_return(msg, "");
}
-int session_slot_available(struct session *s, size_t n)
+static int session_id_get(uint64_t *id)
{
- 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;
- }
+ static uint64_t count = 0;
+
+ if (count == UINT64_MAX) {
+ print_err("%s", "Congratulations, we ran out of uint64_t");
+ return -ERANGE;
}
- pthread_mutex_unlock(&lock);
- return -ENOMEM;
+ *id = count++;
+ return 0;
+}
+
+void session_free(struct session *s)
+{
+ if (s == NULL)
+ return;
+
+ if (s->slot_singal != NULL)
+ sd_bus_slot_unref(s->slot_singal);
+ if (s->slot != NULL)
+ sd_bus_slot_unref(s->slot);
+ if (s->owner != NULL)
+ free(s->owner);
+ if (s->path != NULL)
+ free(s->path);
+ free(s);
}
-int session_new(sd_bus *bus, struct session *session, unsigned session_no,
- const char *owner)
+int session_new(sd_bus *bus, struct session **p, const char *owner)
{
+ struct session *session;
+ uint64_t id;
int ret;
- ret = snprintf(session->path, sizeof(session->path),
- DBUS_OBJECT_PATH "/session/%d", session_no);
- if (ret < 0 || (size_t)ret > sizeof(session->path)) {
+ *p = malloc(sizeof(**p));
+ if (*p == NULL) {
+ print_err("Failed to make session: %s", strerror(errno));
+ return -errno;
+ }
+ session = *p;
+ session->slot_singal = NULL;
+ session->slot = NULL;
+ session->owner = NULL;
+ session->path = NULL;
+
+ ret = session_id_get(&id);
+ if (ret < 0) {
+ session_free(session);
+ return ret;
+ }
+
+ ret = asprintf(&session->path, DBUS_OBJECT_PATH "/session/%lu", id);
+ if (ret < 0) {
+ session_free(session);
print_err("%s", "Failed to create session path");
return -ENOMEM;
}
- ret = snprintf(session->owner, sizeof(session->owner), "%s", owner);
- if (ret < 0 || (size_t)ret > sizeof(session->owner)) {
- print_err("%s", "Failed to set session owner");
- return -ENOMEM;
+ session->owner = strdup(owner);
+ if (session->owner == NULL) {
+ session_free(session);
+ print_err("%s", strerror(errno));
+ return -errno;
}
ret = sd_bus_add_object_vtable(bus, &session->slot, session->path,
SESSION_IFACE, session_vtable, session);
if (ret < 0) {
+ session_free(session);
print_err("Failed to create session: %s", strerror(-ret));
return ret;
}
- session->isactive = true;
- ret = sd_bus_match_signal(bus, NULL, "org.freedesktop.DBus",
+ ret = sd_bus_match_signal(bus, &session->slot_singal, "org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus", "NameOwnerChanged",
handle_nameownerchanged, session);
@@ -119,20 +153,3 @@ int session_new(sd_bus *bus, struct session *session, unsigned session_no,
return ret;
}
-
-int session_free(struct session *s)
-{
- if (s->isactive == false)
- 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;
-}