| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | src/error/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/error/error.h | 143 | ||||
| -rw-r--r-- | src/main.c | 209 | ||||
| -rw-r--r-- | src/pervasive.h | 28 | 
5 files changed, 394 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..f99ceed --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,8 @@ +add_subdirectory(error) + +set( +   SRC_FILES ${SRC_FILES} +   ${CMAKE_CURRENT_SOURCE_DIR}/main.c +) + +set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) diff --git a/src/error/CMakeLists.txt b/src/error/CMakeLists.txt new file mode 100644 index 0000000..fa07534 --- /dev/null +++ b/src/error/CMakeLists.txt @@ -0,0 +1,6 @@ +set( +   SRC_FILES ${SRC_FILES} +) + +set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) + diff --git a/src/error/error.h b/src/error/error.h new file mode 100644 index 0000000..145c838 --- /dev/null +++ b/src/error/error.h @@ -0,0 +1,143 @@ +#ifndef _JH_ERROR_ERROR_H_ +#define _JH_ERROR_ERROR_H_ + +#include <stdio.h> + +#include "../pervasive.h" + +#ifndef JH_DEBUG_PROGRAM_FLOW +   #define JH_DEBUG_PROGRAM_FLOW   (0 || JH_DEBUG_ALL) +#endif + +#ifndef JH_DEBUG_CONFIG +   #define JH_DEBUG_CONFIG         (0 || JH_DEBUG_ALL) +#endif + +#ifndef JH_DEBUG_LEARNING +   #define JH_DEBUG_LEARNING       (0 || JH_DEBUG_ALL) +#endif + +#ifndef JH_DEBUG_NETWORK +   #define JH_DEBUG_NETWORK  1 +#endif + +#ifndef JH_DEBUG_NETWORK +   #define JH_DEBUG_NETWORK        (0 || JH_DEBUG_ALL) +#endif + +#define JH_ENABLE_WARNINGS_OUTPUT              1 +#define JH_ENABLE_RUNTIME_ERRORS_OUTPUT        1 +#define JH_ENABLE_PROGRAMMING_ERRORS_OUTPUT    1 +#define JH_ENABLE_FATAL_ERROR_OUTPUT           1 + +#ifdef JH_ENABLE_ERROR_LOCATION +   #define JH_LOCATION " [" __FILE__ "][" JH_TO_STRING(__LINE__) "]" +#else +   #define JH_LOCATION "" +#endif + +#define JH_PRINT_STDERR(io, symbol, str, ...)\ +   fprintf(io, "[" symbol "]" JH_LOCATION " " str "\n", __VA_ARGS__); + +/* + * Given that we use preprocessor contants as flags, we can expect the compilers + * to remove the test condition for disabled flags. No need to be shy about + * allowing many debug options. + */ + +#define JH_DEBUG(io, flag, str, ...)\ +   JH_ISOLATE\ +   (\ +      if (flag)\ +      {\ +         JH_PRINT_STDERR(io, "D", str, __VA_ARGS__);\ +      }\ +   ) + + +#define JH_WARNING(io, str, ...)\ +   JH_ISOLATE\ +   (\ +      if (JH_ENABLE_WARNINGS_OUTPUT)\ +      {\ +         JH_PRINT_STDERR(io, "W", str, __VA_ARGS__);\ +      }\ +   ) + +#define JH_ERROR(io, str, ...)\ +   JH_ISOLATE\ +   (\ +      if (JH_ENABLE_RUNTIME_ERRORS_OUTPUT)\ +      {\ +         JH_PRINT_STDERR(io, "E", str, __VA_ARGS__);\ +      }\ +   ) + +#define JH_PROG_ERROR(io, str, ...)\ +   JH_ISOLATE\ +   (\ +      if (JH_ENABLE_PROGRAMMING_ERRORS_OUTPUT)\ +      {\ +         JH_PRINT_STDERR(io, "P", str, __VA_ARGS__);\ +      }\ +   ) + +#define JH_FATAL(io, str, ...)\ +   JH_ISOLATE\ +   (\ +     if (JH_ENABLE_FATAL_ERROR_OUTPUT)\ +      {\ +         JH_PRINT_STDERR(io, "F", str, __VA_ARGS__);\ +      }\ +   ) + +/* For outputs without dynamic content (static). ******************************/ + +#define JH_PRINT_S_STDERR(io, symbol, str)\ +   fprintf(io, "[" symbol "]" JH_LOCATION " " str "\n"); + +#define JH_S_DEBUG(io, flag, str)\ +   JH_ISOLATE\ +   (\ +      if (flag)\ +      {\ +         JH_PRINT_S_STDERR(io, "D", str);\ +      }\ +   ) + +#define JH_S_WARNING(io, str)\ +   JH_ISOLATE\ +   (\ +      if (JH_ENABLE_WARNINGS_OUTPUT)\ +      {\ +         JH_PRINT_S_STDERR(io, "W", str);\ +      }\ +   ) + +#define JH_S_ERROR(io, str)\ +   JH_ISOLATE\ +   (\ +      if (JH_ENABLE_RUNTIME_ERRORS_OUTPUT)\ +      {\ +         JH_PRINT_S_STDERR(io, "E", str);\ +      }\ +   ) + +#define JH_S_PROG_ERROR(io, str)\ +   JH_ISOLATE\ +   (\ +      if (JH_ENABLE_PROGRAMMING_ERRORS_OUTPUT)\ +      {\ +         JH_PRINT_S_STDERR(io, "P", str);\ +      }\ +   ) + +#define JH_S_FATAL(io, str)\ +   JH_ISOLATE\ +   (\ +     if (JH_ENABLE_FATAL_ERROR_OUTPUT)\ +      {\ +         JH_PRINT_S_STDERR(io, "F", str);\ +      }\ +   ) +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..9b8be44 --- /dev/null +++ b/src/main.c @@ -0,0 +1,209 @@ +#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" + +static void print_help (const char runnable []) +{ +   printf +   ( +      "JabberHive - CLI Gateway\n" +      "Software Version %d\n" +      "Protocol Version %d\n" +      "\nUsages:\n" +      "   JH GATEWAY:\t%s SOCKET_NAME\n" +      "   SHOW HELP:\tAnything else\n" +      "\nParameters:\n" +      "   SOCKET_NAME: valid UNIX socket.\n", +      JH_PROGRAM_VERSION, +      JH_PROTOCOL_VERSION, +      runnable +   ); +} + +static int 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; +} + +static void gateway +( +   FILE socket [const restrict static 1] +) +{ +   int is_sending; +   int data, data_prev, is_last_message; + +   is_sending = 1; + +   for (;;) +   { +      if (is_sending) +      { +         data = fgetc(stdin); + +         if (data == EOF) +         { +            return; +         } +         else +         { +            if (fputc(data, socket) == EOF) +            { +               JH_S_FATAL(stderr, "Unable to write to socket."); + +               return; +            } +         } + +         if (data == '\n') +         { +            is_sending = 0; +            data = 0; +            is_last_message = 0; +         } +      } +      else +      { +         data_prev = data; +         data = fgetc(socket); + +         if (data == EOF) +         { +            JH_S_FATAL(stderr, "Unable to read from socket."); + +            return; +         } +         else +         { +            if (fputc(data, stdout) == EOF) +            { +               /* ... seems like it wouldn't work. */ +               JH_S_FATAL(stderr, "Unable to write to stdout."); + +               return; +            } +         } + +         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; +         } +      } +   } +} + +int main (int const argc, const char * argv [const static argc]) +{ +   FILE * socket; + +   if (argc != 2) +   { +      print_help(argv[0]); + +      return -1; +   } + +   if (open_socket(&socket, argv[1]) < 0) +   { +      return -1; +   } + +   gateway(socket); + +   fclose(socket); + +   return 0; +} diff --git a/src/pervasive.h b/src/pervasive.h new file mode 100644 index 0000000..27d832d --- /dev/null +++ b/src/pervasive.h @@ -0,0 +1,28 @@ +#ifndef _JH_PERVASIVE_H_ +#define _JH_PERVASIVE_H_ + +#include <string.h> + +#define JH_PROGRAM_VERSION   1 +#define JH_PROTOCOL_VERSION  1 + +#ifdef __FRAMA_C__ +   #define JH_RUNNING_FRAMA_C   1 +#endif + +#define JH_DEBUG_ALL 1 + +#ifndef JH_DEBUG_ALL +   #define JH_DEBUG_ALL 0 +#endif + +#define JH__TO_STRING(x) #x +#define JH_TO_STRING(x) JH__TO_STRING(x) +#define JH_ISOLATE(a) do {a} while (0) + +/* strncmp stops at '\0' and strlen does not count '\0'. */ +#define JH_IS_PREFIX(a, b) (strncmp(a, b, strlen(a)) == 0) + +#define JH_STRING_EQUALS(a, b) (strcmp(a, b) == 0) + +#endif  | 


