| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-04-22 22:24:06 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-04-22 22:24:06 +0200 | 
| commit | 7c321d614e8d91b23434b13bfcf89274797815ec (patch) | |
| tree | 58b8e4fcba63b38a052423401df413606a7e8076 /src/meta_net | |
Initial Commit.
Diffstat (limited to 'src/meta_net')
| -rw-r--r-- | src/meta_net/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/meta_net/meta_net.c | 158 | ||||
| -rw-r--r-- | src/meta_net/meta_net.h | 82 | ||||
| -rw-r--r-- | src/meta_net/meta_net_handle_reply.c | 74 | ||||
| -rw-r--r-- | src/meta_net/meta_net_select.c | 53 | ||||
| -rw-r--r-- | src/meta_net/meta_net_try_request.c | 232 | ||||
| -rw-r--r-- | src/meta_net/meta_net_types.h | 26 | 
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 | 


