summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/daemon.c126
-rw-r--r--src/server/main_loop.c165
-rw-r--r--src/server/server.c113
3 files changed, 404 insertions, 0 deletions
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;
+}