From 390576c3839ee7abb845e27b7267de45495e6b2f Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Mon, 23 Dec 2019 15:44:19 +0100 Subject: Starting to turn relabsd into a proper daemon... --- src/CMakeLists.txt | 10 - src/axis.c | 285 --------------- src/axis.h | 61 ---- src/client.c | 189 ++++++++++ src/config.c | 821 ------------------------------------------- src/config.h | 100 ------ src/config/config_file.c | 821 +++++++++++++++++++++++++++++++++++++++++++ src/config/parameters.c | 287 +++++++++++++++ src/device/axis/axis_name.c | 302 ++++++++++++++++ src/device/physical_device.c | 276 +++++++++++++++ src/device/virtual_device.c | 272 ++++++++++++++ src/error.h | 141 -------- src/input.c | 276 --------------- src/input.h | 53 --- src/main.c | 171 ++------- src/pervasive.h | 16 - src/relabsd_device.c | 298 ---------------- src/relabsd_device.h | 64 ---- src/server/daemon.c | 126 +++++++ src/server/main_loop.c | 165 +++++++++ src/server/server.c | 113 ++++++ src/util/string.c | 36 ++ 22 files changed, 2613 insertions(+), 2270 deletions(-) delete mode 100644 src/CMakeLists.txt delete mode 100644 src/axis.c delete mode 100644 src/axis.h create mode 100644 src/client.c delete mode 100644 src/config.c delete mode 100644 src/config.h create mode 100644 src/config/config_file.c create mode 100644 src/config/parameters.c create mode 100644 src/device/axis/axis_name.c create mode 100644 src/device/physical_device.c create mode 100644 src/device/virtual_device.c delete mode 100644 src/error.h delete mode 100644 src/input.c delete mode 100644 src/input.h delete mode 100644 src/pervasive.h delete mode 100644 src/relabsd_device.c delete mode 100644 src/relabsd_device.h create mode 100644 src/server/daemon.c create mode 100644 src/server/main_loop.c create mode 100644 src/server/server.c create mode 100644 src/util/string.c (limited to 'src') 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/axis.c b/src/axis.c deleted file mode 100644 index c4729ba..0000000 --- a/src/axis.c +++ /dev/null @@ -1,285 +0,0 @@ -#include - -#include "pervasive.h" - -#include "axis.h" -#include "error.h" - -enum relabsd_axis relabsd_axis_from_name (const char * const name) -{ - if (RELABSD_STRING_EQUALS("X", name)) - { - return RELABSD_X; - } - else if (RELABSD_STRING_EQUALS("Y", name)) - { - return RELABSD_Y; - } - else if (RELABSD_STRING_EQUALS("Z", name)) - { - return RELABSD_Z; - } - else if (RELABSD_STRING_EQUALS("RX", name)) - { - return RELABSD_RX; - } - else if (RELABSD_STRING_EQUALS("RY", name)) - { - return RELABSD_RY; - } - else if (RELABSD_STRING_EQUALS("RZ", name)) - { - return RELABSD_RZ; - } - else if (RELABSD_STRING_EQUALS("WL", name)) - { - return RELABSD_WHEEL; - } - else if (RELABSD_STRING_EQUALS("MC", name)) - { - return RELABSD_MISC; - } - - return RELABSD_UNKNOWN; -} - -char * relabsd_axis_to_name (enum relabsd_axis const e) -{ - switch (e) - { - case RELABSD_X: - return "X"; - - case RELABSD_Y: - return "Y"; - - case RELABSD_Z: - return "Z"; - - case RELABSD_RX: - return "RX"; - - case RELABSD_RY: - return "RY"; - - case RELABSD_RZ: - return "RZ"; - - case RELABSD_WHEEL: - return "WL"; - - case RELABSD_MISC: - return "MC"; - - case RELABSD_UNKNOWN: - return "??"; - - default: - break; - } - - RELABSD_S_PROG_ERROR("relabsd_axis_to_name is missing at least 1 case."); - - return ".."; -} - -enum relabsd_axis relabsd_axis_convert_evdev_rel -( - unsigned int const rel_code, - unsigned int * const abs_code -) -{ - switch (rel_code) - { - case REL_X: - *abs_code = ABS_X; - return RELABSD_X; - - case REL_Y: - *abs_code = ABS_Y; - return RELABSD_Y; - - case REL_Z: - *abs_code = ABS_Z; - return RELABSD_Z; - - case REL_RX: - *abs_code = ABS_RX; - return RELABSD_RX; - - case REL_RY: - *abs_code = ABS_RY; - return RELABSD_RY; - - case REL_RZ: - *abs_code = ABS_RZ; - return RELABSD_RZ; - - case REL_WHEEL: - *abs_code = ABS_WHEEL; - return RELABSD_WHEEL; - - case REL_MISC: - *abs_code = ABS_MISC; - return RELABSD_MISC; - - default: - return RELABSD_UNKNOWN; - } -} - -unsigned int relabsd_axis_to_rel (enum relabsd_axis const e) -{ - switch (e) - { - case RELABSD_X: - return REL_X; - - case RELABSD_Y: - return REL_Y; - - case RELABSD_Z: - return REL_Z; - - case RELABSD_RX: - return REL_RX; - - case RELABSD_RY: - return REL_RY; - - case RELABSD_RZ: - return REL_RZ; - - case RELABSD_WHEEL: - return REL_WHEEL; - - case RELABSD_MISC: - return REL_MISC; - - case RELABSD_UNKNOWN: - RELABSD_S_PROG_ERROR - ( - "relabsd_axis_to_rel(RELABSD_UNKNOWN) is forbidden." - ); - return REL_MAX; - - default: - break; - } - - RELABSD_S_PROG_ERROR("relabsd_axis_to_rel is missing at least 1 case."); - - return REL_MAX; -} - -unsigned int relabsd_axis_to_abs (enum relabsd_axis const e) -{ - switch (e) - { - case RELABSD_X: - return ABS_X; - - case RELABSD_Y: - return ABS_Y; - - case RELABSD_Z: - return ABS_Z; - - case RELABSD_RX: - return ABS_RX; - - case RELABSD_RY: - return ABS_RY; - - case RELABSD_RZ: - return ABS_RZ; - - case RELABSD_WHEEL: - return ABS_WHEEL; - - case RELABSD_MISC: - return ABS_MISC; - - case RELABSD_UNKNOWN: - RELABSD_S_PROG_ERROR - ( - "relabsd_axis_to_abs(RELABSD_UNKNOWN) is forbidden." - ); - return ABS_MAX; - - default: - break; - } - - RELABSD_S_PROG_ERROR("relabsd_axis_to_abs is missing at least 1 case."); - - return REL_MAX; -} - -/* - * Returns the relabsd_axis equivalent of a EV_REL/EV_ABS code. - */ -enum relabsd_axis relabsd_axis_from_rel (unsigned int const rel) -{ - switch (rel) - { - case REL_X: - return RELABSD_X; - - case REL_Y: - return RELABSD_Y; - - case REL_Z: - return RELABSD_Z; - - case REL_RX: - return RELABSD_RX; - - case REL_RY: - return RELABSD_RY; - - case REL_RZ: - return RELABSD_RZ; - - case REL_WHEEL: - return RELABSD_WHEEL; - - case REL_MISC: - return RELABSD_MISC; - - default: - return RELABSD_UNKNOWN; - } -} -enum relabsd_axis relabsd_axis_from_abs (unsigned int const abs) -{ - switch (abs) - { - case ABS_X: - return RELABSD_X; - - case ABS_Y: - return RELABSD_Y; - - case ABS_Z: - return RELABSD_Z; - - case ABS_RX: - return RELABSD_RX; - - case ABS_RY: - return RELABSD_RY; - - case ABS_RZ: - return RELABSD_RZ; - - case ABS_WHEEL: - return RELABSD_WHEEL; - - case ABS_MISC: - return RELABSD_MISC; - - default: - return RELABSD_UNKNOWN; - } -} diff --git a/src/axis.h b/src/axis.h deleted file mode 100644 index 2c4ea72..0000000 --- a/src/axis.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef RELABSD_AXIS_H -#define RELABSD_AXIS_H - -/* Number of axes that can be configured. */ -#define RELABSD_VALID_AXES_COUNT 8 - -enum relabsd_axis -{ - RELABSD_X, - RELABSD_Y, - RELABSD_Z, - RELABSD_RX, - RELABSD_RY, - RELABSD_RZ, - RELABSD_WHEEL, - RELABSD_MISC, - RELABSD_UNKNOWN -}; - - -/* - * Gives the relabsd_axis and EV_ABS event code equivalent to an EV_REL event - * code. - * If the returned relabsd_axis is RELABSD_UNKNOWN, no value is inserted into - * 'abs_code'. - */ -enum relabsd_axis relabsd_axis_convert_evdev_rel -( - unsigned int const rel_code, - unsigned int * const abs_code -); - -/* - * Returns the EV_REL/EV_ABS equivalent of 'e'. - * 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); - -/* - * 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); - -/* - * Returns the relabsd_axis whose name is 'name', according to the configuration - * file syntax. - * 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); - -/* - * 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 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 +#include +#include +#include +#include + +#include +#include + +/**** RELABSD *****************************************************************/ +#include +#include +#include + +#include + +/******************************************************************************/ +/**** 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.c deleted file mode 100644 index ad060a5..0000000 --- a/src/config.c +++ /dev/null @@ -1,821 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "error.h" -#include "pervasive.h" -#include "axis.h" -#include "config.h" - -#ifndef RELABSD_OPTION_MAX_SIZE - #define RELABSD_OPTION_MAX_SIZE 64 -#endif -/* - * "errno is never set to zero by any system call or library function." - * This file makes use of this, by setting it to zero and checking if - * it was modified after calling an function (I'm guessing this is common - * practice, but I think it's worth explaining). - * Following the principle of least astonishment, if a function sets errno to - * zero, it will not return before setting it back either to its previous - * value or to a arbitrary nonzero value. - */ - -/* - * Returns -1 on (fatal) error, - * 0 on EOF, - * 1 on newline. - */ -static int reach_next_line_or_eof (FILE * const f) -{ - int prev_errno; - char c; - - prev_errno = errno; - - errno = 0; - - c = (char) getc(f); - - while ((c != '\n') && c != EOF) - { - c = (char) getc(f); - } - - if (errno != 0) - { - RELABSD_FATAL - ( - "[CONFIG] Error while attempting to reach EOF or next line: %s.", - strerror(errno) - ); - - errno = prev_errno; - - return -1; - } - - errno = prev_errno; - - if (c == EOF) - { - return 0; - } - - return 1; -} - -/* - * Returns -1 if the option was discarded (an error has been reported), - * 0 if the option was successfully parsed. - * - * ('length' - 1) is the number of relevant characters in 'name'. - * 'name' must support 'length' characters. - * name[length] will be set to \0, so it does not need to be when calling - * this function. - */ -static int parse_option -( - struct relabsd_config * const conf, - enum relabsd_axis const axis, - char * const name, - int const length -) -{ - name[length] = '\0'; - - if (strcmp(name, "direct") == 0) - { - conf->axis[axis].option[RELABSD_DIRECT_OPTION] = 1; - - RELABSD_DEBUG - ( - RELABSD_DEBUG_CONFIG, - "Axis '%s' enabled option 'direct'.", - relabsd_axis_to_name(axis) - ); - - if (conf->axis[axis].option[RELABSD_FRAMED_OPTION]) - { - RELABSD_WARNING - ( - "[CONFIG] Axis '%s': using option 'direct' discards option" - "'framed'.", - relabsd_axis_to_name(axis) - ); - } - } - else if (strcmp(name, "real_fuzz") == 0) - { - conf->axis[axis].option[RELABSD_REAL_FUZZ_OPTION] = 1; - - RELABSD_DEBUG - ( - RELABSD_DEBUG_CONFIG, - "Axis '%s' enabled option 'real_fuzz'.", - relabsd_axis_to_name(axis) - ); - } - else if (strcmp(name, "framed") == 0) - { - conf->axis[axis].option[RELABSD_FRAMED_OPTION] = 1; - - RELABSD_DEBUG - ( - RELABSD_DEBUG_CONFIG, - "Axis '%s' enabled option 'framed'.", - relabsd_axis_to_name(axis) - ); - - if (conf->axis[axis].option[RELABSD_DIRECT_OPTION]) - { - RELABSD_WARNING - ( - "[CONFIG] Axis '%s': using option 'direct' discards option" - "'framed'.", - relabsd_axis_to_name(axis) - ); - } - } - else - { - RELABSD_ERROR - ( - "[CONFIG] Unknown option '%s' for axis '%s'.", - name, - relabsd_axis_to_name(axis) - ); - - return -1; - } - - return 0; -} - -/* - * Returns -1 on error, - * 0 on EOF, - * 1 on newline. - */ -static int read_axis_options -( - struct relabsd_config * const conf, - FILE * const f, - enum relabsd_axis const axis -) -{ - char option[(RELABSD_OPTION_MAX_SIZE + 1)]; - int i, prev_errno; - char c; - - option[RELABSD_OPTION_MAX_SIZE] = '\0'; - - prev_errno = errno; - - errno = 0; - - memset(conf->axis[axis].option, 0, RELABSD_OPTIONS_COUNT * sizeof(int)); - - i = 0; - - while (i <= RELABSD_OPTION_MAX_SIZE) - { - c = (char) getc(f); - - if ((errno != 0) && (c == EOF)) - { - RELABSD_FATAL - ( - "[CONFIG] Reading error while parsing option name (axis '%s'): %s.", - relabsd_axis_to_name(axis), - strerror(errno) - ); - - errno = prev_errno; - - return -1; - } - - switch (c) - { - case ' ': - case '\t': - break; - - case ',': - /* We parsed a new option and there is a least another. */ - parse_option(conf, axis, option, i); - - i = 0; - - break; - - case '\n': - parse_option(conf, axis, option, i); - errno = prev_errno; - - return 1; - - case EOF: - parse_option(conf, axis, option, i); - errno = prev_errno; - - return 0; - - default: - option[i] = c; - i++; - - break; - } - } - - RELABSD_FATAL - ( - "[CONFIG] Option name '%s[...]' (axis '%s') is too long (%d chars max).", - option, - relabsd_axis_to_name(axis), - RELABSD_OPTION_MAX_SIZE - ); - - return -1; -} - -static int parse_timeout_option -( - struct relabsd_config * const conf, - const char * const param -) -{ - int timeout_msec; - const int prev_errno = errno; - - conf->enable_timeout = 1; - - errno = 0; - - timeout_msec = atoi(param); - - if (timeout_msec <= 0) - { - RELABSD_FATAL - ( - "Illegal value for timeout \"%d\": accepted range is [1, %d].", - timeout_msec, - INT_MAX - ); - - return -1; - } - - memset((void *) &(conf->timeout), 0, sizeof(struct timeval)); - - conf->timeout.tv_sec = (time_t) (timeout_msec / 1000); - - conf->timeout.tv_usec = - ( - ((suseconds_t) timeout_msec) - * ((suseconds_t) 1000) - ); - - return 0; -} - -/* - * Returns -1 on (fatal) error, - * 0 on succes. - */ -static int parse_axis_configuration_line -( - struct relabsd_config * const conf, - FILE * const f, - const char * const buffer -) -{ - int valc, prev_errno; - enum relabsd_axis axis; - - axis = relabsd_axis_from_name(buffer); - - if (axis == RELABSD_UNKNOWN) - { - RELABSD_FATAL - ( - "[CONFIG] Unknown axis '%s'.", - buffer - ); - - return -1; - } - - prev_errno = errno; - errno = 0; - - valc = - fscanf - ( - f, - "%d %d %d %d %d", - &(conf->axis[axis].min), - &(conf->axis[axis].max), - &(conf->axis[axis].fuzz), - &(conf->axis[axis].flat), - &(conf->axis[axis].resolution) - ); - - if (valc == EOF) - { - if (errno == 0) - { - RELABSD_FATAL - ( - "[CONFIG] Unexpected end of file while reading axis '%s'.", - buffer - ); - } - else - { - RELABSD_FATAL - ( - "[CONFIG] An error occured while reading axis '%s': %s.", - buffer, - strerror(errno) - ); - } - - errno = prev_errno; - - return -1; - } - else if (valc < 5) - { - RELABSD_FATAL - ( - "[CONFIG] Invalid parameter count for axis '%s'.", - buffer - ); - - errno = prev_errno; - - return -1; - } - - RELABSD_DEBUG - ( - RELABSD_DEBUG_CONFIG, - "Axis '%s': {min = %d; max = %d; fuzz = %d; flat = %d; resolution = %d}", - buffer, - conf->axis[axis].min, - conf->axis[axis].max, - conf->axis[axis].fuzz, - conf->axis[axis].flat, - conf->axis[axis].resolution - ); - - errno = prev_errno; - - conf->axis[axis].enabled = 1; - conf->axis[axis].previous_value = 0; - - return read_axis_options(conf, f, axis); -} - -/* - * Returns -1 on (fatal) error, - * 0 on EOF, - * 1 on newline. - */ -static int read_config_line -( - struct relabsd_config * const conf, - FILE * const f, - const char * const prefix -) -{ - if (!RELABSD_IS_PREFIX("#", prefix)) - { - return parse_axis_configuration_line(conf, f, prefix); - } - - return reach_next_line_or_eof(f); -} - -/* - * Returns -1 on (fatal) error, - * 0 on success. - */ -static int read_config_file -( - struct relabsd_config * const conf, - char * const filename -) -{ - FILE * f; - char buffer[(RELABSD_CONF_AXIS_CODE_SIZE + 1)]; - int continue_reading, prev_errno; - - buffer[RELABSD_CONF_AXIS_CODE_SIZE] = '\0'; - - f = fopen(filename, "r"); - - if (f == (FILE *) NULL) - { - RELABSD_FATAL - ( - "[CONFIG] Could not open file: %s.", - strerror(errno) - ); - - return -1; - } - - - prev_errno = errno; - errno = 0; - - continue_reading = 1; - - while - ( - (continue_reading == 1) - && - ( - fscanf - ( - f, - "%" RELABSD_TO_STRING(RELABSD_CONF_AXIS_CODE_SIZE) "s", - buffer - ) - != EOF - ) - ) - { - switch (read_config_line(conf, f, buffer)) - { - case 1: - /* Everything is going well. */ - break; - - case 0: - /* EOF reached. */ - continue_reading = 0; - break; - - case -1: - /* A fatal error occured. */ - errno = prev_errno; - - fclose(f); - return -1; - } - } - - if (errno != 0) - { - /* An error happened in the while loop condition. */ - RELABSD_FATAL - ( - "[CONFIG] Error while reading file: %s, last read '%s'.", - strerror(errno), - buffer - ); - - errno = prev_errno; - - fclose(f); - - return -1; - } - - errno = prev_errno; - - fclose(f); - - return 0; -} - -static void print_usage -( - const char * const exec -) -{ - RELABSD_FATAL - ( - "USAGE: %s input_device config_file [