| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-12-23 15:44:19 +0100 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-12-23 15:44:19 +0100 |
| commit | 390576c3839ee7abb845e27b7267de45495e6b2f (patch) | |
| tree | c481c37c868ccc65a3476f60b17369b21a90b79b | |
| parent | 4355548f79375a62bb5e3bb5695190d48e4c0bc3 (diff) | |
Starting to turn relabsd into a proper daemon...
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | include/relabsd/client.h | 0 | ||||
| -rw-r--r-- | include/relabsd/config.h | 0 | ||||
| -rw-r--r-- | include/relabsd/config/config_file.h (renamed from src/config.h) | 0 | ||||
| -rw-r--r-- | include/relabsd/config/parameters.h | 0 | ||||
| -rw-r--r-- | include/relabsd/debug.h (renamed from src/error.h) | 16 | ||||
| -rw-r--r-- | include/relabsd/device/axis.h (renamed from src/axis.h) | 45 | ||||
| -rw-r--r-- | include/relabsd/device/physical_device.h (renamed from src/input.h) | 5 | ||||
| -rw-r--r-- | include/relabsd/device/virtual_device.h (renamed from src/relabsd_device.h) | 21 | ||||
| -rw-r--r-- | include/relabsd/server.h | 0 | ||||
| -rw-r--r-- | include/relabsd/util/macro.h | 6 | ||||
| -rw-r--r-- | include/relabsd/util/string.h (renamed from src/pervasive.h) | 16 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | src/client.c | 189 | ||||
| -rw-r--r-- | src/config/config_file.c (renamed from src/config.c) | 0 | ||||
| -rw-r--r-- | src/config/parameters.c | 287 | ||||
| -rw-r--r-- | src/device/axis/axis_name.c (renamed from src/axis.c) | 45 | ||||
| -rw-r--r-- | src/device/physical_device.c (renamed from src/input.c) | 14 | ||||
| -rw-r--r-- | src/device/virtual_device.c (renamed from src/relabsd_device.c) | 46 | ||||
| -rw-r--r-- | src/main.c | 171 | ||||
| -rw-r--r-- | src/server/daemon.c | 126 | ||||
| -rw-r--r-- | src/server/main_loop.c | 165 | ||||
| -rw-r--r-- | src/server/server.c | 113 | ||||
| -rw-r--r-- | src/util/string.c | 36 |
24 files changed, 1064 insertions, 251 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0697bcb..f5da0f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,9 +7,11 @@ include(FindPkgConfig) # ${SRC_FILES} is recursively defined in the subdirectories. # Each subdirectory adds only the source files that are present at its level. -add_subdirectory(src) +file(GLOB_RECURSE SRC_FILES src/ true *.c) add_executable(relabsd ${SRC_FILES}) +include_directories(include/) + # Language parameters. enable_language(C) target_compile_features(relabsd PUBLIC c_variadic_macros) diff --git a/include/relabsd/client.h b/include/relabsd/client.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/include/relabsd/client.h diff --git a/include/relabsd/config.h b/include/relabsd/config.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/include/relabsd/config.h diff --git a/src/config.h b/include/relabsd/config/config_file.h index 3aa1a13..3aa1a13 100644 --- a/src/config.h +++ b/include/relabsd/config/config_file.h diff --git a/include/relabsd/config/parameters.h b/include/relabsd/config/parameters.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/include/relabsd/config/parameters.h diff --git a/src/error.h b/include/relabsd/debug.h index 863a1bb..025c312 100644 --- a/src/error.h +++ b/include/relabsd/debug.h @@ -1,10 +1,8 @@ -#ifndef RELABSD_ERROR_H -#define RELABSD_ERROR_H +#pragma once #include <stdio.h> -#include "config.h" -#include "pervasive.h" +#include <relabsd/util/macro.h> #ifndef RELABSD_DEBUG_PROGRAM_FLOW #define RELABSD_DEBUG_PROGRAM_FLOW 0 @@ -22,10 +20,18 @@ #define RELABSD_DEBUG_VIRTUAL_EVENTS 0 #endif +#ifndef RELABSD_ENABLE_WARNINGS_OUTPUT #define RELABSD_ENABLE_WARNINGS_OUTPUT 1 +#endif +#ifndef RELABSD_ENABLE_RUNTIME_ERRORS_OUTPUT #define RELABSD_ENABLE_RUNTIME_ERRORS_OUTPUT 1 +#endif +#ifndef RELABSD_ENABLE_PROGRAMMING_ERRORS_OUTPUT #define RELABSD_ENABLE_PROGRAMMING_ERRORS_OUTPUT 1 +#endif +#ifndef RELABSD_ENABLE_FATAL_ERROR_OUTPUT #define RELABSD_ENABLE_FATAL_ERROR_OUTPUT 1 +#endif #ifdef RELABSD_ENABLE_ERROR_LOCATION #define RELABSD_LOCATION "[" __FILE__ "][" RELABSD_TO_STRING(__LINE__) "]" @@ -137,5 +143,3 @@ RELABSD_PRINT_S_STDERR("F", str);\ }\ ) - -#endif diff --git a/src/axis.h b/include/relabsd/device/axis.h index 2c4ea72..3829b51 100644 --- a/src/axis.h +++ b/include/relabsd/device/axis.h @@ -1,10 +1,9 @@ -#ifndef RELABSD_AXIS_H -#define RELABSD_AXIS_H +#pragma once /* Number of axes that can be configured. */ -#define RELABSD_VALID_AXES_COUNT 8 +#define RELABSD_AXIS_AXES_COUNT 8 -enum relabsd_axis +enum relabsd_axis_name { RELABSD_X, RELABSD_Y, @@ -17,6 +16,15 @@ enum relabsd_axis RELABSD_UNKNOWN }; +struct relabsd_axis +{ + int min; + int max; + int fuzz; + int flat; + int resolution; + int flags; +}; /* * Gives the relabsd_axis and EV_ABS event code equivalent to an EV_REL event @@ -24,10 +32,10 @@ enum relabsd_axis * If the returned relabsd_axis is RELABSD_UNKNOWN, no value is inserted into * 'abs_code'. */ -enum relabsd_axis relabsd_axis_convert_evdev_rel +enum relabsd_axis_name relabsd_axis_name_and_evdev_abs_from_evdev_rel ( - unsigned int const rel_code, - unsigned int * const abs_code + const unsigned int rel_code, + unsigned int abs_code [const restrict static 1] ); /* @@ -35,14 +43,21 @@ enum relabsd_axis relabsd_axis_convert_evdev_rel * There is no equivalent for RELABSD_UNKNOWN, so 'e' is forbidden from * taking this value. */ -unsigned int relabsd_axis_to_rel (enum relabsd_axis const e); -unsigned int relabsd_axis_to_abs (enum relabsd_axis const e); +unsigned int relabsd_axis_name_to_evdev_rel (const enum relabsd_axis_name e); +unsigned int relabsd_axis_name_to_evdev_abs (const enum relabsd_axis_name e); /* * Returns the relabsd_axis equivalent of a EV_REL/EV_ABS code. */ -enum relabsd_axis relabsd_axis_from_rel (unsigned int const rel); -enum relabsd_axis relabsd_axis_from_abs (unsigned int const abs); +enum relabsd_axis_name relabsd_axis_name_from_evdev_rel +( + const unsigned int rel +); + +enum relabsd_axis_name relabsd_axis_name_from_evdev_abs +( + const unsigned int abs +); /* * Returns the relabsd_axis whose name is 'name', according to the configuration @@ -50,12 +65,14 @@ enum relabsd_axis relabsd_axis_from_abs (unsigned int const abs); * RELABSD_UNKNOWN is returned for any name that didn't match any other * possibility. */ -enum relabsd_axis relabsd_axis_from_name (const char * const name); +enum relabsd_axis_name relabsd_axis_parse_name +( + const char name [const restrict static 1] +); /* * Gives an string representation of an relabsd_axis. * "??" is returned for RELABSD_UNKNOWN. * Returned values should be coherent with the configuration file syntax. */ -char * relabsd_axis_to_name (enum relabsd_axis const e); -#endif +const char * relabsd_axis_name_to_string (const enum relabsd_axis_name e); diff --git a/src/input.h b/include/relabsd/device/physical_device.h index 2e1b502..17866f7 100644 --- a/src/input.h +++ b/include/relabsd/device/physical_device.h @@ -1,10 +1,7 @@ -#ifndef RELABSD_INPUT_H -#define RELABSD_INPUT_H +#pragma once #include <libevdev/libevdev.h> -#include "config.h" - struct relabsd_input { struct libevdev * dev; diff --git a/src/relabsd_device.h b/include/relabsd/device/virtual_device.h index 4aa181d..d398c7f 100644 --- a/src/relabsd_device.h +++ b/include/relabsd/device/virtual_device.h @@ -1,10 +1,20 @@ -#ifndef RELABSD_RELABSD_DEVICE_H -#define RELABSD_RELABSD_DEVICE_H +#pragma once #include <libevdev/libevdev.h> +#include <libevdev/libevdev-uinput.h> -#include "config.h" -#include "input.h" +/* + LIBEVDEV_UINPUT_OPEN_MANAGED is not defined on my machines. + It is not my place to define it, so I'll avoid the issue by defining my own + constant. +*/ +#ifndef LIBEVDEV_UINPUT_OPEN_MANAGED + #pragma message "[WARNING] libevdev did not define " \ + "LIBEVDEV_UINPUT_OPEN_MANAGED, using value '-2' instead." + #define RELABSD_UINPUT_OPEN_MANAGED -2 +#else + #define RELABSD_UINPUT_OPEN_MANAGED LIBEVDEV_UINPUT_OPEN_MANAGED +#endif struct relabsd_device { @@ -59,6 +69,3 @@ void relabsd_device_set_axes_to_zero const struct relabsd_device * const dev, const struct relabsd_config * const config ); - - -#endif diff --git a/include/relabsd/server.h b/include/relabsd/server.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/include/relabsd/server.h diff --git a/include/relabsd/util/macro.h b/include/relabsd/util/macro.h new file mode 100644 index 0000000..b9adb5e --- /dev/null +++ b/include/relabsd/util/macro.h @@ -0,0 +1,6 @@ +#pragma once + +#define RELABSD_ISOLATE(a) do {a} while (0) + +#define RELABSD__TO_STRING(x) #x +#define RELABSD_TO_STRING(x) RELABSD__TO_STRING(x) diff --git a/src/pervasive.h b/include/relabsd/util/string.h index 6c08305..d632720 100644 --- a/src/pervasive.h +++ b/include/relabsd/util/string.h @@ -1,16 +1,18 @@ -#ifndef RELABSD_PERVASIVE_H -#define RELABSD_PERVASIVE_H +#pragma once #include <string.h> -#define RELABSD__TO_STRING(x) #x -#define RELABSD_TO_STRING(x) RELABSD__TO_STRING(x) - -#define RELABSD_ISOLATE(a) do {a} while (0) +#include <relabsd/util/macro.h> /* strncmp stops at '\0' and strlen does not count '\0'. */ #define RELABSD_IS_PREFIX(a, b) (strncmp(a, b, strlen(a)) == 0) #define RELABSD_STRING_EQUALS(a, b) (strcmp(a, b) == 0) -#endif +int relabsd_util_parse_int +( + const char string [const restrict static 1], + const int min, + const int max, + int output [const restrict static 1] +); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 98af72c..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -set( - SRC_FILES ${SRC_FILES} - ${CMAKE_CURRENT_SOURCE_DIR}/main.c - ${CMAKE_CURRENT_SOURCE_DIR}/config.c - ${CMAKE_CURRENT_SOURCE_DIR}/input.c - ${CMAKE_CURRENT_SOURCE_DIR}/axis.c - ${CMAKE_CURRENT_SOURCE_DIR}/relabsd_device.c -) - -set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) diff --git a/src/client.c b/src/client.c new file mode 100644 index 0000000..d03a768 --- /dev/null +++ b/src/client.c @@ -0,0 +1,189 @@ +/**** POSIX *******************************************************************/ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/socket.h> +#include <sys/un.h> + +/**** RELABSD *****************************************************************/ +#include <relabsd/client.h> +#include <relabsd/config.h> +#include <relabsd/debug.h> + +#include <relabsd/config/parameters.h> + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ +static int open_socket +( + FILE * s [const restrict static 1], + const char socket_name [const restrict static 1] +) +{ + const int old_errno = errno; + int fd; + struct sockaddr_un addr; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Opening socket to server..."); + + errno = 0; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + { + RELABSD_FATAL + ( + "Unable to create socket: %s.", + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + errno = old_errno; + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socket_name, (sizeof(addr.sun_path) - 1)); + + errno = 0; + + if (connect(fd, ((struct sockaddr*) &addr), sizeof(addr)) == -1) + { + RELABSD_FATAL + ( + "Unable to connect to address: %s.", + strerror(errno) + ); + + errno = old_errno; + + close(fd); + + return -1; + } + + errno = 0; + + *s = fdopen(fd, "w+"); + + if (*s == ((FILE *) NULL)) + { + RELABSD_FATAL + ( + "Unable to open socket as a file: %s.", + strerror(errno) + ); + + errno = old_errno; + + close(fd); + + return -1; + } + + errno = old_errno; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Opened socket to server."); + + return 0; +} + +static int send_commands +( + const int argc, + const char * argv [const restrict static argc], + FILE socket [const restrict static 1] +) +{ + int i, j; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Sending commands to server..."); + + for (i = 3; i < argc;) + { + + if (fputs(argv[i], socket) == EOF) + { + // TODO: error + } + + for + ( + j = relabsd_parameters_argument_count_for(argv[i]), + i++; + ((j > 0) && (i < argc)); + j++, i-- + ) + { + if (fputc(' ', socket) == EOF) + { + // TODO: error + } + if (fputs(argv[i], socket) == EOF) + { + // TODO: error + } + } + + if (fputc('\0', socket) == EOF) + { + // TODO: error + } + } + + if (fputc('\0', socket) == EOF) + { + } + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Sent commands to server."); + + return 0; +} + +static int receive_reply +( + FILE socket [const restrict static 1] +) +{ + return 0; +} + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_client +( + const int argc, + const char * argv [const restrict static argc], + struct relabsd_parameters params [const restrict static 1] +) +{ + FILE * socket; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Started client mode."); + + if (open_socket(&socket, relabsd_parameters_get_node(params)) < 0) + { + return -1; + } + + if (send_commands(argc, argv, socket) < 0) + { + return -2; + } + + if (receive_reply(socket) < 0) + { + return -3; + } + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Completed client mode."); + + return 0; +} diff --git a/src/config.c b/src/config/config_file.c index ad060a5..ad060a5 100644 --- a/src/config.c +++ b/src/config/config_file.c diff --git a/src/config/parameters.c b/src/config/parameters.c new file mode 100644 index 0000000..308e5db --- /dev/null +++ b/src/config/parameters.c @@ -0,0 +1,287 @@ +/**** POSIX *******************************************************************/ +#include <limits.h> + +/**** RELABSD *****************************************************************/ +#include <relabsd/config.h> +#include <relabsd/debug.h> + +#include <relabsd/device/axis.h> + +#include <relabsd/util/string.h> + +#include <relabsd/config/parameters.h> + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ +static void print_usage (const char exec [const restrict static 1]) +{ + printf + ( + "USAGE: %s [<MODE>] [<OPTION>+]\n\n" + + "<MODE>:\n" + "\t[-c | --client] <server_file>:\n" + "\t\tSends the commands to a given server instance.\n\n" + + "\t[-s | --server] <server_file>:\n" + "\t\tCreates a named server instance.\n\n" + + "\t[-1 | --self]:\n" + "\t\tCreates a unnamed server instance.\n\n" + + "<OPTION>:\n" + "\t[-d | --daemon]:\n" + "\t\tRuns server instance in the background.\n\n" + + "\t[-n | --name] <relabsd_device_name>:\n" + "\t\tNames the virtual device.\n\n" + + "\t[-t | --timeout] <timeout_in_ms>:\n" + "\t\tSets a zeroing timeout (0 to disable).\n\n" + + "\t[-a | --axis] <name> <min> <max> <fuzz> <flat> <resolution> " + "<options>:\n" + "\t\t(Re)defines an axis.\n\n" + + "\t[-f | --config] <config_file>" + "<options>:\n" + "\t\t(Re)defines an axis.\n", + exec + ); +} + +static int parse_axis +( + const int argc, + const char * argv [const restrict static argc], + struct relabsd_axis axes [const restrict static RELABSD_AXIS_AXES_COUNT] +) +{ + enum relabsd_axis_name axis_name; + struct relabsd_axis *axis; + + if (argc < 7) + { + RELABSD_S_FATAL("7 parameters must be provided for axis definition."); + + return -1; + } + + axis_index = relabsd_axis_from_name(argv[0]); + + if (axis_index == RELABSD_UNKNOWN) + { + RELABSD_FATAL("Unknown axis \"%s\".", argv[0]); + + return -1; + } + + axis = (axes + axis_index); + + axis->min = atoi(argv[1]); + axis->max = atoi(argv[2]); + axis->fuzz = atoi(argv[3]); + axis->flat = atoi(argv[4]); + axis->resolution = atoi(argv[5]); + + + return 0; +} + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_parameters_parse_execution_mode +( + const int argc, + const char * argv [const restrict static argc], + struct relabsd_parameters params [const restrict static 1] +) +{ + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Parsing exec mode..."); + + if (argc < 3) + { + print_usage(argv[0]); + + return -1; + } + + if + ( + RELABSD_STRING_EQUALS("-c", argv[1]) + || RELABSD_STRING_EQUALS("--client", argv[1]) + ) + { + params->mode = RELABSD_PARAMETERS_CLIENT_MODE; + params->node = argv[2]; + params->read_argc = 2; + } + else if + ( + RELABSD_STRING_EQUALS("-s", argv[1]) + || RELABSD_STRING_EQUALS("--server", argv[1]) + ) + { + params->mode = RELABSD_PARAMETERS_CLIENT_MODE; + params->node = argv[2]; + params->read_argc = 2; + } + else if + ( + RELABSD_STRING_EQUALS("-1", argv[1]) + || RELABSD_STRING_EQUALS("--self", argv[1]) + ) + { + params->mode = RELABSD_PARAMETERS_SERVER_MODE; + params->node = (char *) NULL; + params->read_argc = 1; + } + else + { + print_usage(argv[0]); + + return -1; + } + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Parsed exec mode."); + + return 0; +} + +int relabsd_parameters_parse_options +( + const int argc, + const char * argv [const restrict static argc], + struct relabsd_parameters params [const restrict static 1] +) +{ + int i; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Parsing options..."); + + set_default_options(params); + + for (i = params->read_argc; i < argc; ++i) + { + if + ( + RELABSD_STRING_EQUALS("-d", argv[i]) + || RELABSD_STRING_EQUALS("--daemon", argv[i]) + ) + { + params->run_as_daemon = 1; + + if (params->node == ((char *) NULL)) + { + RELABSD_S_WARNING + ( + "Running as a daemon without any communication file." + ); + } + } + else if + ( + RELABSD_STRING_EQUALS("-n", argv[i]) + || RELABSD_STRING_EQUALS("--name", argv[i]) + ) + { + if (argc == i) + { + RELABSD_FATAL("Missing value for \"%s\" <OPTION>.", argv[i]); + + return -1; + } + + ++i; + params->name = argv[i]; + } + else if + ( + RELABSD_STRING_EQUALS("-t", argv[i]) + || RELABSD_STRING_EQUALS("--timeout", argv[i]) + ) + { + if (argc == i) + { + RELABSD_FATAL("Missing value for \"%s\" <OPTION>.", argv[i]); + print_usage(argv[0]); + + return -1; + } + + ++i; + + if + ( + relabsd_util_parse_int(argv[i], 0, INT_MAX, &(params->timeout)) + < 0 + ) + { + RELABSD_FATAL + ( + "Invalid value for \"%s\" <OPTION> (valid range is [%d, %d]).", + argv[i - 1], + 0, + INT_MAX + ); + + print_usage(argv[0]); + + return -1; + } + } + else if + ( + RELABSD_STRING_EQUALS("-a", argv[i]) + || RELABSD_STRING_EQUALS("--axis", argv[i]) + ) + { + if (argc == i) + { + RELABSD_FATAL("Missing values for \"%s\" <OPTION>.", argv[i]); + print_usage(argv[0]); + + return -1; + } + + ++i; + + if (parse_axis((argc - i), (argv + i), params->axes) < 0) + { + print_usage(argv[0]); + + return -1; + } + } + else if + ( + RELABSD_STRING_EQUALS("-f", argv[i]) + || RELABSD_STRING_EQUALS("--config", argv[i]) + ) + { + if (argc == i) + { + RELABSD_FATAL("Missing value for \"%s\" <OPTION>.", argv[i]); + print_usage(argv[0]); + + return -1; + } + + ++i; + params->config_file = argv[i]; + } + else + { + RELABSD_FATAL("Unknown <OPTION> \"%s\".", argv[i]); + print_usage(argv[0]); + + return -1; + } + } + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Parsed options."); + + return 0; +} diff --git a/src/axis.c b/src/device/axis/axis_name.c index c4729ba..c18a28f 100644 --- a/src/axis.c +++ b/src/device/axis/axis_name.c @@ -1,11 +1,24 @@ +/**** LIBEVDEV ****************************************************************/ #include <libevdev/libevdev.h> -#include "pervasive.h" +/**** RELABSD *****************************************************************/ +#include <relabsd/debug.h> -#include "axis.h" -#include "error.h" +#include <relabsd/util/string.h> -enum relabsd_axis relabsd_axis_from_name (const char * const name) +#include <relabsd/device/axis.h> + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +enum relabsd_axis_name relabsd_axis_parse_name +( + const char name [const restrict static 1] +) { if (RELABSD_STRING_EQUALS("X", name)) { @@ -43,7 +56,7 @@ enum relabsd_axis relabsd_axis_from_name (const char * const name) return RELABSD_UNKNOWN; } -char * relabsd_axis_to_name (enum relabsd_axis const e) +const char * relabsd_axis_name_to_string (const enum relabsd_axis_name e) { switch (e) { @@ -83,10 +96,10 @@ char * relabsd_axis_to_name (enum relabsd_axis const e) return ".."; } -enum relabsd_axis relabsd_axis_convert_evdev_rel +enum relabsd_axis_name relabsd_axis_name_and_evdev_abs_from_evdev_rel ( - unsigned int const rel_code, - unsigned int * const abs_code + const unsigned int rel_code, + unsigned int abs_code [const restrict static 1] ) { switch (rel_code) @@ -128,7 +141,7 @@ enum relabsd_axis relabsd_axis_convert_evdev_rel } } -unsigned int relabsd_axis_to_rel (enum relabsd_axis const e) +unsigned int relabsd_axis_name_to_evdev_rel (const enum relabsd_axis_name e) { switch (e) { @@ -159,7 +172,7 @@ unsigned int relabsd_axis_to_rel (enum relabsd_axis const e) case RELABSD_UNKNOWN: RELABSD_S_PROG_ERROR ( - "relabsd_axis_to_rel(RELABSD_UNKNOWN) is forbidden." + "relabsd_axis_name_to_evdev_rel(RELABSD_UNKNOWN) is forbidden." ); return REL_MAX; @@ -167,12 +180,15 @@ unsigned int relabsd_axis_to_rel (enum relabsd_axis const e) break; } - RELABSD_S_PROG_ERROR("relabsd_axis_to_rel is missing at least 1 case."); + RELABSD_S_PROG_ERROR + ( + "relabsd_axis_name_to_evdev_rel is missing at least 1 case." + ); return REL_MAX; } -unsigned int relabsd_axis_to_abs (enum relabsd_axis const e) +unsigned int relabsd_axis_name_to_evdev_abs (const enum relabsd_axis_name e) { switch (e) { @@ -219,7 +235,7 @@ unsigned int relabsd_axis_to_abs (enum relabsd_axis const e) /* * Returns the relabsd_axis equivalent of a EV_REL/EV_ABS code. */ -enum relabsd_axis relabsd_axis_from_rel (unsigned int const rel) +enum relabsd_axis_name relabsd_axis_name_from_evdev_rel (const unsigned int rel) { switch (rel) { @@ -251,7 +267,8 @@ enum relabsd_axis relabsd_axis_from_rel (unsigned int const rel) return RELABSD_UNKNOWN; } } -enum relabsd_axis relabsd_axis_from_abs (unsigned int const abs) + +enum relabsd_axis_name relabsd_axis_name_from_evdev_abs (const unsigned int abs) { switch (abs) { diff --git a/src/input.c b/src/device/physical_device.c index e8e1bab..a518750 100644 --- a/src/input.c +++ b/src/device/physical_device.c @@ -79,9 +79,9 @@ static int device_is_compatible return 0; } -int relabsd_input_open +int relabsd_physical_device_open ( - struct relabsd_input * const input, + struct relabsd_physical_device * const input, const struct relabsd_config * const conf ) { @@ -126,7 +126,7 @@ int relabsd_input_open return 0; } -void relabsd_input_close (const struct relabsd_input * const input) +void relabsd_physical_device_close (const struct relabsd_physical_device * const input) { RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Closing input device..."); @@ -134,9 +134,9 @@ void relabsd_input_close (const struct relabsd_input * const input) close(input->fd); } -int relabsd_input_read +int relabsd_physical_device_read ( - const struct relabsd_input * const input, + const struct relabsd_physical_device * const input, unsigned int * const input_type, unsigned int * const input_code, int * const input_value @@ -190,9 +190,9 @@ int relabsd_input_read return 0; } -int relabsd_input_wait_for_next_event +int relabsd_physical_device_wait_for_next_event ( - const struct relabsd_input * const input, + const struct relabsd_physical_device * const input, const struct relabsd_config * const config ) { diff --git a/src/relabsd_device.c b/src/device/virtual_device.c index 51dd6c0..19d1097 100644 --- a/src/relabsd_device.c +++ b/src/device/virtual_device.c @@ -1,34 +1,8 @@ -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> - -#include <libevdev/libevdev-uinput.h> - -#include "error.h" -#include "axis.h" -#include "config.h" - -#include "relabsd_device.h" - -/* - LIBEVDEV_UINPUT_OPEN_MANAGED is not defined on my machines. - It is not my place to define it, so I'll avoid the issue by defining my own - constant. -*/ -#ifndef LIBEVDEV_UINPUT_OPEN_MANAGED - #pragma message "[WARNING] libevdev did not define "\ - "LIBEVDEV_UINPUT_OPEN_MANAGED, using value '-2' instead." - #define RELABSD_UINPUT_OPEN_MANAGED -2 -#else - #define RELABSD_UINPUT_OPEN_MANAGED LIBEVDEV_UINPUT_OPEN_MANAGED -#endif + static void replace_rel_axes ( - struct relabsd_device * const dev, + struct relabsd_virtual_device * const dev, const struct relabsd_config * const config ) { @@ -132,9 +106,9 @@ static int rename_device return 0; } -int relabsd_device_create +int relabsd_virtual_device_create ( - struct relabsd_device * const dev, + struct relabsd_virtual_device * const dev, const struct relabsd_config * const config ) { @@ -208,7 +182,7 @@ int relabsd_device_create return 0; } -void relabsd_device_destroy (const struct relabsd_device * const dev) +void relabsd_virtual_device_destroy (const struct relabsd_virtual_device * const dev) { RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Destroying virtual device..."); @@ -216,9 +190,9 @@ void relabsd_device_destroy (const struct relabsd_device * const dev) libevdev_free(dev->dev); } -int relabsd_device_write_evdev_event +int relabsd_virtual_device_write_evdev_event ( - const struct relabsd_device * const dev, + const struct relabsd_virtual_device * const dev, unsigned int const type, unsigned int const code, int const value @@ -262,9 +236,9 @@ int relabsd_device_write_evdev_event return -1; } -void relabsd_device_set_axes_to_zero +void relabsd_virtual_device_set_axes_to_zero ( - const struct relabsd_device * const dev, + const struct relabsd_virtual_device * const dev, const struct relabsd_config * const config ) { @@ -274,7 +248,7 @@ void relabsd_device_set_axes_to_zero { if (config->axis[i].enabled) { - relabsd_device_write_evdev_event + relabsd_virtual_device_write_evdev_event ( dev, EV_ABS, @@ -1,163 +1,44 @@ -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> +/**** RELABSD *****************************************************************/ +#include <relabsd/client.h> +#include <relabsd/config.h> +#include <relabsd/debug.h> +#include <relabsd/server.h> -#include "pervasive.h" -#include "error.h" -#include "config.h" -#include "input.h" -#include "relabsd_device.h" +#include <relabsd/config/parameters.h> -static int RELABSD_RUN = 1; - -static void interrupt (int unused_mandatory_parameter) -{ - RELABSD_RUN = 0; - - RELABSD_S_WARNING("Interrupted, will exit at the next input device event."); -} - -static void handle_relative_axis_event -( - struct relabsd_config * const conf, - const struct relabsd_device * const dev, - unsigned int const input_type, - unsigned int const input_code, - int value -) -{ - unsigned int abs_code; - enum relabsd_axis rad_code; - - rad_code = relabsd_axis_convert_evdev_rel(input_code, &abs_code); - - switch (relabsd_config_filter(conf, rad_code, &value)) - { - case -1: - /* 'conf' doesn't want the event to be transmitted. */ - break; - - case 0: - /* 'conf' wants the event to be transmitted as is. */ - relabsd_device_write_evdev_event(dev, input_type, input_code, value); - break; - - case 1: - /* 'conf' allows the value to be emitted */ - relabsd_device_write_evdev_event(dev, EV_ABS, abs_code, value); - break; - } -} - -static void convert_input -( - struct relabsd_config * const conf, - struct relabsd_input * const input, - const struct relabsd_device * const dev -) -{ - unsigned int input_type, input_code; - int value; - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Handling input events..."); - - input->timed_out = 1; - - while (RELABSD_RUN == 1) - { - if (conf->enable_timeout) - { - switch (relabsd_input_wait_for_next_event(input, conf)) - { - case 1: - input->timed_out = 0; - break; - - case 0: - relabsd_device_set_axes_to_zero(dev, conf); - input->timed_out = 1; - break; - - case -1: - continue; - } - } - - if (relabsd_input_read(input, &input_type, &input_code, &value) < 0) - { - /* - * The next event should not be retransmitted, or some kind of error - * happened. - */ - /* TODO: error handling. */ - continue; - } - - if (input_type == EV_REL) - { - /* We might have to convert the event. */ - handle_relative_axis_event(conf, dev, input_type, input_code, value); - } - else - { - /* Any other event is retransmitted as is. */ - relabsd_device_write_evdev_event(dev, input_type, input_code, value); - } - } -} - -static int set_signal_handlers () -{ - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Setting signal handlers."); - - if (signal(SIGINT, interrupt) == SIG_ERR) - { - RELABSD_S_FATAL("Unable to set the SIGINT signal handler."); - - return -1; - } - - return 0; -} +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ int main (int argc, char ** argv) { - struct relabsd_config conf; - struct relabsd_input input; - struct relabsd_device dev; + int retval; + struct relabsd_parameters params; RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd started."); - if (set_signal_handlers() < 0) + if (relabsd_parameters_parse_execution_mode(argc, argv, ¶ms) < 0) { - return -1; - } + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd crashing"); - if (relabsd_config_parse(&conf, argc, argv) < 0) - { - return -2; + return -1; } - if (relabsd_input_open(&input, &conf) < 0) + switch (relabsd_parameters_get_execution_mode(¶ms)) { - return -3; - } + case RELABSD_PARAMETERS_CLIENT_MODE: + retval = relabsd_client_main(argc, argv, ¶ms); + break; - if (relabsd_device_create(&dev, &conf) < 0) - { - return -4; + case RELABSD_PARAMETERS_RUN_SERVER_MODE: + retval = relabsd_server_main(argc, argv, ¶ms); + break; } - convert_input(&conf, &input, &dev); - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Terminating..."); - - relabsd_device_destroy(&dev); - relabsd_input_close(&input); - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Done."); + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd terminating."); - return 0; + return retval; } diff --git a/src/server/daemon.c b/src/server/daemon.c new file mode 100644 index 0000000..7b8e736 --- /dev/null +++ b/src/server/daemon.c @@ -0,0 +1,126 @@ +/**** POSIX *******************************************************************/ +#include <sys/types.h> + +#include <unistd.h> + +/**** RELABSD *****************************************************************/ +#include <relabsd/config.h> +#include <relabsd/debug.h> +#include <relabsd/server.h> + +#include <relabsd/config/parameters.h> + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +/* + * Daemon creation function made using the instructions for old-school daemons + * at https://www.freedesktop.org/software/systemd/man/daemon.html + * Only meant to be used before things really start. This won't properly create + * a daemon on an already running server instance with a virtual device and so + * on... + */ +int relabsd_server_create_daemon (void) +{ + pid_t proc_id; + + /* 1/ Close all open file descriptors ... **********************************/ + /* None were opened at this point. */ + + /* 2/ Reset all signal handlers ... ****************************************/ + /* Those were not modified at this point. */ + + /* 3/ Reset the signal mask using sigprocmask() ****************************/ + /* Not modified at this point. */ + + /* 4/ Sanitize the environment block ... ***********************************/ + /* What? */ + + /* 5/ fork() ***************************************************************/ + errno = 0; + proc_id = fork(); + + if (proc_id == ((pid_t) -1)) + { + RELABSD_FATAL + ( + "Step 5 of the daemon creation process, fork(), failed: %s.", + strerror(errno) + ); + + return -1; + } + + if (proc_id != ((pid_t) 0)) + { + /* Awaiting step 14...*/ + /* TODO: insert unnamed pipe */ + /* 15/ Original process exits *******************************************/ + exit(); + } + + /* 6/ setsid() *************************************************************/ + errno = 0; + + proc_id = setsid(); + + if (proc_id == ((pid_t) -1)) + { + RELABSD_FATAL + ( + "Step 6 of the daemon creation process, setsid(), failed: %s.", + strerror(errno) + ); + + return -1; + } + + /* 7/ fork() again *********************************************************/ + errno = 0; + proc_id = fork(); + + if (proc_id == ((pid_t) -1)) + { + RELABSD_FATAL + ( + "Step 5 of the daemon creation process, fork(), failed: %s.", + strerror(errno) + ); + + return -1; + } + + if (proc_id != ((pid_t) 0)) + { + /* 8/ First child process exits *****************************************/ + exit(); + } + + /* 9/ /dev/null for standard input/outputs *********************************/ + + /* 10/ reset umask to 0 ****************************************************/ + + /* 11/ Set current directory to / ******************************************/ + errno = 0; + + if (chdir("/") == -1) + { + // Can't print an error message at that point though... + return -1; + } + + /* 12/ lock file using PID to assert single instance ***********************/ + /* Don't want to limit to a single instance. */ + + /* 13/ Drop privileges *****************************************************/ + + /* 14/ Signal completion ***************************************************/ + + /* Step 15 is done on the very first process. */ + + return 0; +} diff --git a/src/server/main_loop.c b/src/server/main_loop.c new file mode 100644 index 0000000..7db1423 --- /dev/null +++ b/src/server/main_loop.c @@ -0,0 +1,165 @@ +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> + +#include "pervasive.h" +#include "error.h" +#include "config.h" +#include "input.h" +#include "relabsd_device.h" + +static int RELABSD_RUN = 1; + +static void interrupt (int unused_mandatory_parameter) +{ + RELABSD_RUN = 0; + + RELABSD_S_WARNING("Interrupted, will exit at the next input device event."); +} + +static void handle_relative_axis_event +( + struct relabsd_config * const conf, + const struct relabsd_device * const dev, + unsigned int const input_type, + unsigned int const input_code, + int value +) +{ + unsigned int abs_code; + enum relabsd_axis rad_code; + + rad_code = relabsd_axis_convert_evdev_rel(input_code, &abs_code); + + switch (relabsd_config_filter(conf, rad_code, &value)) + { + case -1: + /* 'conf' doesn't want the event to be transmitted. */ + break; + + case 0: + /* 'conf' wants the event to be transmitted as is. */ + relabsd_device_write_evdev_event(dev, input_type, input_code, value); + break; + + case 1: + /* 'conf' allows the value to be emitted */ + relabsd_device_write_evdev_event(dev, EV_ABS, abs_code, value); + break; + } +} + +static void convert_input +( + struct relabsd_config * const conf, + struct relabsd_input * const input, + const struct relabsd_device * const dev +) +{ + unsigned int input_type, input_code; + int value; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Handling input events..."); + + input->timed_out = 1; + + while (RELABSD_RUN == 1) + { + if (conf->enable_timeout) + { + switch (relabsd_input_wait_for_next_event(input, conf)) + { + case 1: + input->timed_out = 0; + break; + + case 0: + relabsd_device_set_axes_to_zero(dev, conf); + input->timed_out = 1; + break; + + case -1: + continue; + } + } + + if (relabsd_input_read(input, &input_type, &input_code, &value) < 0) + { + /* + * The next event should not be retransmitted, or some kind of error + * happened. + */ + /* TODO: error handling. */ + continue; + } + + if (input_type == EV_REL) + { + /* We might have to convert the event. */ + handle_relative_axis_event(conf, dev, input_type, input_code, value); + } + else + { + /* Any other event is retransmitted as is. */ + relabsd_device_write_evdev_event(dev, input_type, input_code, value); + } + } +} + +static int set_signal_handlers () +{ + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Setting signal handlers."); + + if (signal(SIGINT, interrupt) == SIG_ERR) + { + RELABSD_S_FATAL("Unable to set the SIGINT signal handler."); + + return -1; + } + + return 0; +} + +/* +int main (int argc, char ** argv) +{ + struct relabsd_config conf; + struct relabsd_input input; + struct relabsd_device dev; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd started."); + + if (set_signal_handlers() < 0) + { + return -1; + } + + if (relabsd_config_parse(&conf, argc, argv) < 0) + { + return -2; + } + + if (relabsd_input_open(&input, &conf) < 0) + { + return -3; + } + + if (relabsd_device_create(&dev, &conf) < 0) + { + return -4; + } + + convert_input(&conf, &input, &dev); + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Terminating..."); + + relabsd_device_destroy(&dev); + relabsd_input_close(&input); + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Done."); + + return 0; +} +*/ diff --git a/src/server/server.c b/src/server/server.c new file mode 100644 index 0000000..debeb91 --- /dev/null +++ b/src/server/server.c @@ -0,0 +1,113 @@ +/**** RELABSD *****************************************************************/ +#include <relabsd/config.h> +#include <relabsd/debug.h> +#include <relabsd/server.h> + +#include <relabsd/config/parameters.h> + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ +int initialize +( + struct relabsd_server server [const restrict static 1], + struct relabsd_parameters params [const static 1] +) +{ + server->parameters = params; + + if + ( + relabsd_physical_device_open + ( + relabsd_parameters_get_physical_device_name(params), + &(server->physical_device) + ) + < 0 + ) + { + return -1; + } + + if + ( + relabsd_virtual_device_create + ( + + &(server->virtual_device) + ) + < 0 + ) + { + relabsd_physical_device_close(&(server->physical_device)); + + return -2; + } + + if + ( + (relabsd_parameters_get_communication_node(params) != ((...) NULL)) + && (relabsd_server_spawn_communication_node(server) < 0) + ) + { + relabsd_virtual_device_destroy(&(server->virtual_device)); + relabsd_physical_device_close(&(server->physical_device)); + + return -3; + } + + return 0; +} + +void finalize (struct relabsd_server server [const static 1]) +{ + if (relabsd_parameters_get_communication_node(params) != ((...) NULL)) + { + relabsd_server_join_communication_node(&server); + } + + relabsd_virtual_device_destroy(&(server->virtual_device)); + relabsd_physical_device_close(&(server->physical_device)); + + return 0; +} + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_server +( + const int argc, + const char * const argv [const restrict static argc], + struct relabsd_parameters params [const static 1] +) +{ + struct relabsd_server server; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Started server mode."); + + if (relabsd_parameters_parse_options(argc, argv, params) < 0) + { + return -1; + } + + if + ( + (relabsd_parameters_run_as_daemon(params)) + && (relabsd_server_create_daemon() < 0) + ) + { + return -2; + } + + (void) initialize(&server, params); + + (void) relabsd_server_conversion_loop(&server); + + finalize(&server); + + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Completed server mode."); + + return 0; +} diff --git a/src/util/string.c b/src/util/string.c new file mode 100644 index 0000000..edb5eb6 --- /dev/null +++ b/src/util/string.c @@ -0,0 +1,36 @@ +/**** POSIX *******************************************************************/ +#include <stdlib.h> + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_util_parse_int +( + const char string [const restrict static 1], + const int min, + const int max, + int output [const restrict static 1] +) +{ + char * invalid_char; /* may become an alias of string. */ + long int buffer; + + buffer = strtol(string, &invalid_char, 10); + + if ((invalid_char[0] != '\0') || (string[0] == '\0')) + { + return -1; + } + + if ((buffer < ((long int) min)) || (buffer > ((long int) max))) + { + return -2; + } + + *output = ((int) buffer); + return 0; +} |


