| summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/cli.h | 15 | ||||
| -rw-r--r-- | src/main.c | 244 | ||||
| -rw-r--r-- | src/signal.c | 91 | ||||
| -rw-r--r-- | src/socket.c | 90 |
5 files changed, 317 insertions, 125 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f99ceed..61aeb77 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,8 @@ add_subdirectory(error) set( SRC_FILES ${SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/signal.c + ${CMAKE_CURRENT_SOURCE_DIR}/socket.c ) set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) diff --git a/src/cli.h b/src/cli.h new file mode 100644 index 0000000..ca42f76 --- /dev/null +++ b/src/cli.h @@ -0,0 +1,15 @@ +#ifndef _JH_CLI_CLI_H_ +#define _JH_CLI_CLI_H_ + +#include <stdio.h> + +int JH_cli_open_socket +( + FILE * s [const restrict static 1], + const char socket_name [const restrict static 1] +); + +int JH_cli_is_running (void); +int JH_cli_set_signal_handlers (void); + +#endif @@ -1,6 +1,3 @@ -#include <sys/socket.h> -#include <sys/un.h> - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -11,6 +8,8 @@ #include "pervasive.h" +#include "./cli.h" + static void print_help (const char runnable [const restrict static 1]) { printf @@ -29,160 +28,139 @@ static void print_help (const char runnable [const restrict static 1]) ); } -static int open_socket +static int send_to_network ( - FILE * s [const restrict static 1], - const char socket_name [const restrict static 1] + FILE socket [const restrict static 1] ) { - int fd; - struct sockaddr_un addr; - - const int old_errno = errno; - - errno = 0; - - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - { - JH_FATAL - ( - stderr, - "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) - { - JH_FATAL - ( - stderr, - "Unable to connect to address: %s.", - strerror(errno) - ); - - errno = old_errno; - - close(fd); - - return -1; - } - - errno = 0; + int data; - *s = fdopen(fd, "w+"); - - if (*s == (FILE *) NULL) + while (JH_cli_is_running()) { - JH_FATAL - ( - stderr, - "Unable to open socket as a file: %s.", - strerror(errno) - ); + data = fgetc(stdin); - errno = old_errno; + if (data == EOF) + { + return -1; + } + else + { + if (fputc(data, socket) == EOF) + { + JH_S_FATAL(stderr, "Unable to write to socket."); - close(fd); + return -2; + } + } - return -1; + if (data == '\n') + { + return 0; + } } - errno = old_errno; - - return 0; + return -1; } -static void gateway +static int receive_from_network ( FILE socket [const restrict static 1] ) { - int is_sending; - int data, data_prev, is_last_message; + int data; + int match_index; - is_sending = 1; + match_index = 0; - for (;;) + while (JH_cli_is_running()) { - if (is_sending) + data = fgetc(socket); + + if (data == EOF) { - data = fgetc(stdin); + JH_S_FATAL(stderr, "Unable to read from socket."); - if (data == EOF) - { - return; - } - else + return -1; + } + else + { + if (fputc(data, stdout) == EOF) { - if (fputc(data, socket) == EOF) - { - JH_S_FATAL(stderr, "Unable to write to socket."); - - return; - } - } + /* ... seems like it wouldn't work. */ + JH_S_FATAL(stderr, "Unable to write to stdout."); - if (data == '\n') - { - is_sending = 0; - data = 0; - is_last_message = 0; + return -2; } } - else + + switch (match_index) { - data_prev = data; - data = fgetc(socket); + case -1: + if (data == '\n') + { + match_index = 0; + } + break; - if (data == EOF) - { - JH_S_FATAL(stderr, "Unable to read from socket."); + case 0: + if (data == '!') + { + match_index = 1; + } + else if (data == '\n') + { + match_index = 0; + } + else + { + match_index = -1; + } + break; - return; - } - else - { - if (fputc(data, stdout) == EOF) + case 1: + if ((data == 'P') || (data == 'N')) + { + match_index = 2; + } + else if (data == '\n') { - /* ... seems like it wouldn't work. */ - JH_S_FATAL(stderr, "Unable to write to stdout."); + match_index = 0; + } + else + { + match_index = -1; + } + break; - return; + case 2: + if (data == ' ') + { + match_index = 3; } - } + else if (data == '\n') + { + match_index = 0; + } + else + { + match_index = -1; + } + break; - is_last_message = - ( - is_last_message - || ( - (data_prev == '!') - && ( - (data == 'P') - || (data == 'N') - ) - // TODO: check for the ' '. - ) - ); - - if (is_last_message && (data == '\n')) - { - is_sending = 1; - } + case 3: + if (data == '\n') + { + return 0; + } + else + { + match_index = -1; + } + break; } } + + return -1; } int main (int const argc, const char * argv [const static argc]) @@ -196,12 +174,28 @@ int main (int const argc, const char * argv [const static argc]) return -1; } - if (open_socket(&socket, argv[1]) < 0) + if (JH_cli_set_signal_handlers() < 0) { return -1; } - gateway(socket); + if (JH_cli_open_socket(&socket, argv[1]) < 0) + { + return -1; + } + + while (JH_cli_is_running()) + { + if (send_to_network(socket) < 0) + { + break; + } + + if (receive_from_network(socket) < 0) + { + break; + } + } fclose(socket); diff --git a/src/signal.c b/src/signal.c new file mode 100644 index 0000000..eb9584e --- /dev/null +++ b/src/signal.c @@ -0,0 +1,91 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <errno.h> + +#include "error/error.h" + +#include "pervasive.h" + +#include "./cli.h" + +static volatile char JH_GATEWAY_IS_RUNNING = (char) 1; + +static void request_termination (int const signo) +{ + if ((signo == SIGINT) || (signo == SIGTERM)) + { + JH_GATEWAY_IS_RUNNING = (char) 0; + } +} + +int JH_cli_is_running (void) +{ + return (int) JH_GATEWAY_IS_RUNNING; +} + +int JH_cli_set_signal_handlers (void) +{ + struct sigaction act; + const int old_errno = errno; + + memset((void *) &act, 0, sizeof(struct sigaction)); + + act.sa_handler = request_termination; + + errno = 0; + + if (sigaction(SIGHUP, &act, (struct sigaction * restrict) NULL) == -1) + { + JH_FATAL + ( + stderr, + "Could not set sigaction for SIGHUP (errno: %d): %s", + errno, + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + errno = 0; + + if (sigaction(SIGINT, &act, (struct sigaction * restrict) NULL) == -1) + { + JH_FATAL + ( + stderr, + "Could not set sigaction for SIGINT (errno: %d): %s", + errno, + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + act.sa_handler = SIG_IGN; + + if (sigaction(SIGPIPE, &act, (struct sigaction * restrict) NULL) == -1) + { + JH_FATAL + ( + stderr, + "Could not set sigaction for SIGPIPE (errno: %d): %s", + errno, + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + errno = old_errno; + + return 0; +} diff --git a/src/socket.c b/src/socket.c new file mode 100644 index 0000000..343e1a3 --- /dev/null +++ b/src/socket.c @@ -0,0 +1,90 @@ +#include <sys/socket.h> +#include <sys/un.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> + +#include "error/error.h" + +#include "pervasive.h" + +#include "./cli.h" + +int JH_cli_open_socket +( + FILE * s [const restrict static 1], + const char socket_name [const restrict static 1] +) +{ + int fd; + struct sockaddr_un addr; + + const int old_errno = errno; + + errno = 0; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + { + JH_FATAL + ( + stderr, + "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) + { + JH_FATAL + ( + stderr, + "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) + { + JH_FATAL + ( + stderr, + "Unable to open socket as a file: %s.", + strerror(errno) + ); + + errno = old_errno; + + close(fd); + + return -1; + } + + errno = old_errno; + + return 0; +} |


