diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/npassd/service.c | 26 | ||||
-rw-r--r-- | src/npassd/session.c | 101 |
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; -} |