summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-04-22 22:24:06 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-04-22 22:24:06 +0200
commit7c321d614e8d91b23434b13bfcf89274797815ec (patch)
tree58b8e4fcba63b38a052423401df413606a7e8076 /src/meta_net
Initial Commit.
Diffstat (limited to 'src/meta_net')
-rw-r--r--src/meta_net/CMakeLists.txt9
-rw-r--r--src/meta_net/meta_net.c158
-rw-r--r--src/meta_net/meta_net.h82
-rw-r--r--src/meta_net/meta_net_handle_reply.c74
-rw-r--r--src/meta_net/meta_net_select.c53
-rw-r--r--src/meta_net/meta_net_try_request.c232
-rw-r--r--src/meta_net/meta_net_types.h26
7 files changed, 634 insertions, 0 deletions
diff --git a/src/meta_net/CMakeLists.txt b/src/meta_net/CMakeLists.txt
new file mode 100644
index 0000000..ca047c3
--- /dev/null
+++ b/src/meta_net/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(
+ SRC_FILES ${SRC_FILES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/meta_net.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/meta_net_handle_reply.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/meta_net_select.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/meta_net_try_request.c
+)
+
+set(SRC_FILES ${SRC_FILES} PARENT_SCOPE)
diff --git a/src/meta_net/meta_net.c b/src/meta_net/meta_net.c
new file mode 100644
index 0000000..fdd0fec
--- /dev/null
+++ b/src/meta_net/meta_net.c
@@ -0,0 +1,158 @@
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "../error/error.h"
+
+#include "../parameters/parameters.h"
+
+#include "meta_net.h"
+
+static int open_socket
+(
+ struct JH_meta_net s [const restrict static 1],
+ const char socket_name [const restrict static 1]
+)
+{
+ struct sockaddr_un addr;
+ int flags;
+ const int old_errno = errno;
+
+ errno = 0;
+
+ s->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ if (s->fd == -1)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Unable to create socket: %s.",
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ return -1;
+ }
+
+ errno = old_errno;
+
+ memset((void *) &addr, 0, sizeof(addr));
+
+ addr.sun_family = AF_UNIX;
+
+ strncpy
+ (
+ (void *) addr.sun_path,
+ (const void *) socket_name,
+ (sizeof(addr.sun_path) - 1)
+ );
+
+ errno = 0;
+
+ if (connect(s->fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Unable to connect to address: %s.",
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ close(s->fd);
+
+ return -1;
+ }
+
+ errno = 0;
+
+ flags = fcntl(s->fd, F_GETFD, 0);
+
+ if (flags < 0)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Unable to get fd flag information for JabberHive socket: %s.",
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ close(s->fd);
+
+ return -1;
+ }
+
+ errno = 0;
+
+ if (fcntl(s->fd, F_SETFL, (flags | O_NONBLOCK)) == -1)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Unable to get fd flag information for JabberHive socket: %s.",
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ close(s->fd);
+
+ return -1;
+ }
+
+ errno = old_errno;
+
+ return 0;
+}
+
+int JH_meta_net_connect
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const struct JH_parameters params [const restrict static 1]
+)
+{
+ return
+ open_socket
+ (
+ socket,
+ JH_parameters_get_socket_name(params)
+ );
+}
+
+void JH_meta_net_initialize
+(
+ struct JH_meta_net socket [const restrict static 1]
+)
+{
+ socket->in.data = (char *) NULL;
+ socket->in.capacity = 0;
+ socket->in.length = 0;
+ socket->in.index = 0;
+
+ socket->out.data = (char *) NULL;
+ socket->out.capacity = 0;
+ socket->out.length = 0;
+ socket->out.index = 0;
+
+ socket->fd = -1;
+ socket->has_request_in_progress = 0;
+}
+
+void JH_meta_net_finalize
+(
+ struct JH_meta_net socket [const restrict static 1]
+)
+{
+ /* TODO */
+}
diff --git a/src/meta_net/meta_net.h b/src/meta_net/meta_net.h
new file mode 100644
index 0000000..ce5c61e
--- /dev/null
+++ b/src/meta_net/meta_net.h
@@ -0,0 +1,82 @@
+#ifndef _JH_META_NET_META_NET_H_
+#define _JH_META_NET_META_NET_H_
+
+#include "../parameters/parameters_types.h"
+
+#include "../irc/irc_types.h"
+
+#include "meta_net_types.h"
+
+void JH_meta_net_initialize
+(
+ struct JH_meta_net socket [const restrict static 1]
+);
+
+int JH_meta_net_connect
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const struct JH_parameters params [const restrict static 1]
+);
+
+void JH_meta_net_finalize
+(
+ struct JH_meta_net socket [const restrict static 1]
+);
+
+int JH_meta_net_try_request
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const char string [const restrict static 1],
+ const size_t string_size
+);
+
+int JH_meta_net_handle_user_message
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const char string [const restrict static 1],
+ const size_t string_size
+);
+
+int JH_meta_net_handle_user_action
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const char string [const restrict static 1],
+ const size_t string_size
+);
+
+int JH_meta_net_read
+(
+ struct JH_meta_net socket [const restrict static 1]
+);
+
+/* TODO */
+int JH_meta_net_write
+(
+ struct JH_meta_net socket [const restrict static 1]
+);
+
+void JH_meta_net_handle_reply
+(
+ struct JH_meta_net socket [const restrict static 1],
+ struct JH_irc irc [const restrict static 1],
+ const struct JH_parameters params [const restrict static 1]
+);
+
+int JH_meta_net_pre_select
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const struct JH_parameters params [const restrict static 1],
+ fd_set in [const restrict static 1],
+ fd_set out [const restrict static 1],
+ int max_fd [const restrict static 1]
+);
+
+int JH_meta_net_post_select
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const struct JH_parameters params [const restrict static 1],
+ fd_set in [const restrict static 1],
+ fd_set out [const restrict static 1]
+);
+
+#endif
diff --git a/src/meta_net/meta_net_handle_reply.c b/src/meta_net/meta_net_handle_reply.c
new file mode 100644
index 0000000..b823078
--- /dev/null
+++ b/src/meta_net/meta_net_handle_reply.c
@@ -0,0 +1,74 @@
+#include "../error/error.h"
+
+#include "../irc/irc.h"
+#include "../parameters/parameters.h"
+
+#include "meta_net.h"
+
+void JH_meta_net_handle_reply
+(
+ struct JH_meta_net socket [const restrict static 1],
+ struct JH_irc irc [const restrict static 1],
+ const struct JH_parameters params [const restrict static 1]
+)
+{
+ if (socket->in.index == 0)
+ {
+ /* No reply to handle. */
+ return;
+ }
+
+ socket->in.data[socket->in.index] = '\0';
+
+ if (JH_IS_PREFIX("!CPV ", socket->in.data))
+ {
+ }
+ else if (JH_IS_PREFIX("!CPS ", socket->in.data))
+ {
+ }
+ else if (JH_IS_PREFIX("!GR ", socket->in.data))
+ {
+ /* TODO: /me vs message should be handled prior to this. */
+ JH_irc_send_message(irc, (socket->in.data + 4));
+
+ JH_DEBUG
+ (
+ stderr,
+ /* TODO: Parameter dependent behavior. */
+ JH_DEBUG_DISPLAY_IRC_MSG_EXCHANGES,
+ "<%s> %s",
+ JH_parameters_get_irc_nick(params),
+ (socket->in.data + 4)
+ );
+ }
+ else if (JH_IS_PREFIX("!AI ", socket->in.data))
+ {
+ /* TODO: Parameter dependent behavior. */
+ JH_DEBUG
+ (
+ stderr,
+ 1,
+ "Received: %s.",
+ socket->in.data
+ );
+ }
+ else if (JH_IS_PREFIX("!P ", socket->in.data))
+ {
+ socket->has_request_in_progress = 0;
+ }
+ else if (JH_IS_PREFIX("!N ", socket->in.data))
+ {
+ JH_S_WARNING(stderr, "Received Negative reply.");
+
+ socket->has_request_in_progress = 0;
+ }
+ else
+ {
+ JH_WARNING
+ (
+ stderr,
+ "Unsupported reply received: %s.",
+ socket->in.data
+ );
+ }
+}
diff --git a/src/meta_net/meta_net_select.c b/src/meta_net/meta_net_select.c
new file mode 100644
index 0000000..069a671
--- /dev/null
+++ b/src/meta_net/meta_net_select.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+#include <sys/select.h>
+
+#include "meta_net.h"
+
+int JH_meta_net_pre_select
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const struct JH_parameters params [const restrict static 1],
+ fd_set in [const restrict static 1],
+ fd_set out [const restrict static 1],
+ int max_fd [const restrict static 1]
+)
+{
+ FD_SET(socket->fd, in);
+ FD_SET(socket->fd, out);
+
+ if ((*max_fd) < socket->fd)
+ {
+ *max_fd = socket->fd;
+ }
+
+ return 0;
+}
+
+int JH_meta_net_post_select
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const struct JH_parameters params [const restrict static 1],
+ fd_set in [const restrict static 1],
+ fd_set out [const restrict static 1]
+)
+{
+ if (FD_ISSET(socket->fd, in))
+ {
+ if (JH_meta_net_read(socket) < 0)
+ {
+ /* TODO: Try to reconnect. */
+ return -1;
+ }
+ }
+
+ if (FD_ISSET(socket->fd, out))
+ {
+ if (JH_meta_net_write(socket) < 0)
+ {
+ /* TODO: Try to reconnect. */
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/meta_net/meta_net_try_request.c b/src/meta_net/meta_net_try_request.c
new file mode 100644
index 0000000..121ef8d
--- /dev/null
+++ b/src/meta_net/meta_net_try_request.c
@@ -0,0 +1,232 @@
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "../error/error.h"
+
+#include "../parameters/parameters.h"
+
+#include "meta_net.h"
+
+/******************************************************************************/
+/** MEMORY ALLOCATION *********************************************************/
+/******************************************************************************/
+static int ensure_string_capacity
+(
+ char * string [const restrict static 1],
+ size_t string_capacity [const restrict static 1],
+ const size_t string_required_capacity
+)
+{
+ char * new_string;
+
+ if (string_required_capacity <= *string_capacity)
+ {
+ return 0;
+ }
+
+ new_string =
+ (char *) realloc
+ (
+ (void *) *string,
+ ((size_t) string_required_capacity) * sizeof(char)
+ );
+
+ if (new_string == (char *) NULL)
+ {
+ JH_S_ERROR
+ (
+ stderr,
+ "Unable to reallocate memory to match string's required size."
+ );
+
+ return -1;
+ }
+
+ *string_capacity = string_required_capacity;
+ *string = new_string;
+
+ return 1;
+}
+
+/******************************************************************************/
+/** EXPORTED ******************************************************************/
+/******************************************************************************/
+int JH_meta_net_handle_user_message
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const char string [const restrict static 1],
+ const size_t string_size
+)
+{
+ if (socket->out.length != 0)
+ {
+ return 1;
+ }
+
+ if
+ (
+ ensure_string_capacity
+ (
+ &(socket->out.data),
+ &(socket->out.capacity),
+ string_size
+ )
+ < 0
+ )
+ {
+ return -1;
+ }
+
+ memcpy
+ (
+ (void *) socket->out.data,
+ (const void *) string,
+ (string_size * sizeof(char))
+ );
+
+ socket->out.length = string_size;
+ socket->out.index = 0;
+
+ socket->has_request_in_progress = 1;
+
+ return 0;
+}
+
+int JH_meta_net_handle_user_action
+(
+ struct JH_meta_net socket [const restrict static 1],
+ const char string [const restrict static 1],
+ const size_t string_size
+)
+{
+ if (socket->out.length != 0)
+ {
+ return 1;
+ }
+
+ if
+ (
+ ensure_string_capacity
+ (
+ &(socket->out.data),
+ &(socket->out.capacity),
+ (string_size + (JH_META_NET_ACTION_STRING_LENGTH + 1))
+ )
+ < 0
+ )
+ {
+ return -1;
+ }
+
+ memcpy
+ (
+ (void *) socket->out.data,
+ (const void *) JH_META_NET_ACTION_STRING,
+ (JH_META_NET_ACTION_STRING_LENGTH * sizeof(char))
+ );
+
+ socket->out.data[JH_META_NET_ACTION_STRING_LENGTH] = ' ';
+
+ memcpy
+ (
+ (void *) (socket->out.data + (JH_META_NET_ACTION_STRING_LENGTH + 1)),
+ (const void *) string,
+ (string_size * sizeof(char))
+ );
+
+ socket->out.length = string_size;
+ socket->out.index = 0;
+
+ socket->has_request_in_progress = 1;
+
+ return 0;
+}
+
+int JH_meta_net_read
+(
+ struct JH_meta_net socket [const restrict static 1]
+)
+{
+ const int old_errno = errno;
+ ssize_t in_bytes_count;
+
+ if ((SIZE_MAX - JH_META_NET_READ_SIZE) < socket->in.length)
+ {
+ JH_S_ERROR
+ (
+ stderr,
+ "Unable to read from JabberHive socket: max buffer size reached."
+ );
+
+ return -1;
+ }
+
+ if
+ (
+ ensure_string_capacity
+ (
+ &(socket->in.data),
+ &(socket->in.capacity),
+ (socket->in.length + JH_META_NET_READ_SIZE)
+ )
+ < 0
+ )
+ {
+ return -1;
+ }
+
+ errno = 0;
+
+ in_bytes_count =
+ read
+ (
+ socket->fd,
+ (&(socket->in.data) + socket->in.length),
+ (size_t) JH_META_NET_READ_SIZE
+ );
+
+ if (in_bytes_count < 0)
+ {
+ if (errno == EAGAIN)
+ {
+ errno = old_errno;
+
+ return 0;
+ }
+
+ JH_ERROR
+ (
+ stderr,
+ "Unable to read from JabberHive socket: %s.",
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ return -1;
+ }
+
+ errno = old_errno;
+
+ /* Safe. */
+ socket->in.length += (size_t) in_bytes_count;
+
+ while (socket->in.index < socket->in.length)
+ {
+ if (socket->in.data[socket->in.index] == '\n')
+ {
+ break;
+ }
+
+ socket->in.index += 1;
+ }
+
+ return 0;
+}
diff --git a/src/meta_net/meta_net_types.h b/src/meta_net/meta_net_types.h
new file mode 100644
index 0000000..251f85b
--- /dev/null
+++ b/src/meta_net/meta_net_types.h
@@ -0,0 +1,26 @@
+#ifndef _JH_META_NET_META_NET_TYPES_H_
+#define _JH_META_NET_META_NET_TYPES_H_
+
+#include <stdio.h>
+
+#define JH_META_NET_READ_SIZE 64
+#define JH_META_NET_ACTION_STRING "/me"
+#define JH_META_NET_ACTION_STRING_LENGTH 3
+
+struct JH_meta_net_buffer
+{
+ char * data;
+ size_t capacity;
+ size_t length;
+ size_t index;
+};
+
+struct JH_meta_net
+{
+ int fd;
+ int has_request_in_progress;
+ struct JH_meta_net_buffer in;
+ struct JH_meta_net_buffer out;
+};
+
+#endif