Skip to content

Commit

Permalink
Add daemon using varlink for communication
Browse files Browse the repository at this point in the history
  • Loading branch information
thkukuk committed Dec 17, 2024
1 parent afab979 commit c238619
Show file tree
Hide file tree
Showing 19 changed files with 1,864 additions and 81 deletions.
10 changes: 9 additions & 1 deletion include/wtmpdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@

#define _PATH_WTMPDB "/var/lib/wtmpdb/wtmp.db"

#define _VARLINK_WTMPDB_SOCKET_DIR "/run/wtmpdb"
#define _VARLINK_WTMPDB_SOCKET_WRITER _VARLINK_WTMPDB_SOCKET_DIR"/writer.socket"
#define _VARLINK_WTMPDB_SOCKET_READER _VARLINK_WTMPDB_SOCKET_DIR"/reader.socket"

#define EMPTY 0 /* No valid user accounting information. */
#define BOOT_TIME 1 /* Time of system boot. */
#define RUNLEVEL 2 /* The system's runlevel. Unused with systemd. */
Expand All @@ -54,7 +58,11 @@ extern int wtmpdb_read_all (const char *db_path,
int (*cb_func) (void *unused, int argc,
char **argv, char **azColName),
char **error);
extern int wtmpdb_rotate (const char *db_path, const int days, char **error,
extern int wtmpdb_read_all_v2 (const char *db_path,
int (*cb_func) (void *unused, int argc,
char **argv, char **azColName),
void *userdata, char **error);
extern int wtmpdb_rotate (const char *db_path, const int days, char **error,
char **wtmpdb_name, uint64_t *entries);

/* Returns last "BOOT_TIME" entry as usec */
Expand Down
17 changes: 17 additions & 0 deletions lib/basics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: BSD-2-Clause

#pragma once

#define _cleanup_(x) __attribute__((__cleanup__(x)))
#define _unused_(x) x __attribute__((unused))

#define mfree(memory) \
({ \
free(memory); \
(typeof(memory)) NULL; \
})

static inline void freep(void *p) {
*(void**)p = mfree(*(void**) p);
}

126 changes: 117 additions & 9 deletions lib/libwtmpdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@
POSSIBILITY OF SUCH DAMAGE.
*/

#include <errno.h>
#include <stddef.h>
#include <stdlib.h>

#include "basics.h"
#include "wtmpdb.h"
#include "sqlite.h"
#include "varlink.h"

static int varlink_is_active = 1;

/*
Add new wtmp entry to db.
Expand All @@ -40,8 +46,27 @@ wtmpdb_login (const char *db_path, int type, const char *user,
uint64_t usec_login, const char *tty, const char *rhost,
const char *service, char **error)
{
return sqlite_login (db_path?db_path:_PATH_WTMPDB, type, user, usec_login, tty, rhost,
service, error);
/* we can use varlink only if no specific database is requested */
if (varlink_is_active && db_path == NULL)
{
int64_t id;

id = varlink_login (type, user, usec_login, tty, rhost,
service, error);
if (id >= 0)
return id;

if (id == -ECONNREFUSED)
{
varlink_is_active = 0;
*error = mfree (*error);
}
else
return id; /* return the error if wtmpdbd is active */
}

return sqlite_login (db_path?db_path:_PATH_WTMPDB, type, user,
usec_login, tty, rhost, service, error);
}

/*
Expand All @@ -54,40 +79,123 @@ int
wtmpdb_logout (const char *db_path, int64_t id, uint64_t usec_logout,
char **error)
{
/* we can use varlink only if no specific database is requested */
if (varlink_is_active && db_path == NULL)
{
int r;

r = varlink_logout (id, usec_logout, error);
if (r >= 0)
return r;

if (id == -ECONNREFUSED)
{
varlink_is_active = 0;
*error = mfree (*error);
}
else
return r; /* return the error if wtmpdbd is active */
}

return sqlite_logout (db_path?db_path:_PATH_WTMPDB, id, usec_logout, error);
}

int64_t
wtmpdb_get_id (const char *db_path, const char *tty, char **error)
{
/* we can use varlink only if no specific database is requested */
if (varlink_is_active && db_path == NULL)
{
int64_t id;

id = varlink_get_id (tty, error);
if (id >= 0)
return id;

if (id == -ECONNREFUSED)
{
varlink_is_active = 0;
*error = mfree (*error);
}
else
return id; /* return the error if wtmpdbd is active */
}

return sqlite_get_id (db_path?db_path:_PATH_WTMPDB, tty, error);
}

/* Reads all entries from database and calls the callback function for
each entry.
Returns 0 on success, -1 on failure. */
int
wtmpdb_read_all (const char *db_path,
int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
char **error)
wtmpdb_read_all (const char *db_path,
int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
char **error)
{
return sqlite_read_all (db_path?db_path:_PATH_WTMPDB, cb_func, error);
return sqlite_read_all (db_path?db_path:_PATH_WTMPDB, cb_func, NULL, error);
}

int
wtmpdb_read_all_v2 (const char *db_path,
int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
void *userdata, char **error)
{
return sqlite_read_all (db_path?db_path:_PATH_WTMPDB, cb_func, userdata, error);
}


/* Reads all entries from database and calls the callback function for
each entry.
Returns 0 on success, -1 on failure. */
Returns 0 on success, < 0 on failure. */
int
wtmpdb_rotate (const char *db_path, const int days, char **error,
char **wtmpdb_name, uint64_t *entries)
{
return sqlite_rotate (db_path, days, wtmpdb_name, entries, error);
/* we can use varlink only if no specific database is requested */
if (varlink_is_active && db_path == NULL)
{
int r;

r = varlink_rotate (days, wtmpdb_name, entries, error);
if (r >= 0)
return r;

if (r == -ECONNREFUSED)
{
varlink_is_active = 0;
*error = mfree (*error);
}
else
return r; /* return the error if wtmpdbd is active */
}

return sqlite_rotate (db_path?db_path:_PATH_WTMPDB, days, wtmpdb_name, entries, error);
}

/* returns boottime entry on success or 0 in error case */
uint64_t
wtmpdb_get_boottime (const char *db_path, char **error)
{
/* we can use varlink only if no specific database is requested */
if (varlink_is_active && db_path == NULL)
{
int r;
uint64_t boottime;

r = varlink_get_boottime (&boottime, error);
if (r >= 0)
return boottime;

if (r == -ECONNREFUSED)
{
varlink_is_active = 0;
*error = mfree (*error);
}
else
return 0; /* return the error if wtmpdbd is active */
}

return sqlite_get_boottime (db_path?db_path:_PATH_WTMPDB, error);
}
5 changes: 4 additions & 1 deletion lib/libwtmpdb.map
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ LIBWTMPDB_0.8 {
global:
wtmpdb_get_boottime;
} LIBWTMPDB_0.7;

LIBWTMPDB_0.50 {
global:
wtmpdb_read_all_v2;
} LIBWTMPDB_0.8;
8 changes: 4 additions & 4 deletions lib/logwtmpdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ logwtmpdb (const char *db_path, const char *tty, const char *name,

if (name != NULL && strlen (name) > 0)
{ /* login */
retval = wtmpdb_login (db_path ? db_path : _PATH_WTMPDB, USER_PROCESS,
name, time, tty, host, service, error);
retval = wtmpdb_login (db_path, USER_PROCESS, name, time, tty,
host, service, error);
}
else
{ /* logout */
int64_t id = wtmpdb_get_id (db_path ? db_path : _PATH_WTMPDB, tty, error);
retval = wtmpdb_logout (db_path ? db_path : _PATH_WTMPDB, id, time, error);
int64_t id = wtmpdb_get_id (db_path, tty, error);
retval = wtmpdb_logout (db_path, id, time, error);
}

return retval;
Expand Down
77 changes: 77 additions & 0 deletions lib/mkdir_p.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* SPDX-License-Identifier: BSD-2-Clause
Copyright (c) 2024, Thorsten Kukuk <[email protected]>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>

#include "mkdir_p.h"

int
mkdir_p(const char *path, mode_t mode)
{
if (path == NULL)
return -EINVAL;

if (mkdir(path, mode) == 0)
return 0;

if (errno == EEXIST)
{
struct stat st;

/* Check if the existing path is a directory */
if (stat(path, &st) != 0)
return -errno;

/* If not, fail with ENOTDIR */
if (!S_ISDIR(st.st_mode))
return -ENOTDIR;

/* if it is a directory, return */
return 0;
}

/* If it fails for any reason but ENOENT, fail */
if (errno != ENOENT)
return -errno;

char *buf = strdup(path);
if (buf == NULL)
return -ENOMEM;

int r = mkdir_p(dirname(buf), mode);
free(buf);
/* if we couldn't create the parent, fail, too */
if (r < 0)
return r;

return mkdir(path, mode);
}

33 changes: 33 additions & 0 deletions lib/mkdir_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: BSD-2-Clause
Copyright (c) 2024, Thorsten Kukuk <[email protected]>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#include <sys/stat.h>

extern int mkdir_p(const char *path, mode_t mode);

Loading

0 comments on commit c238619

Please sign in to comment.