#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;
}