commit afb8588cf7ed1b14f8ef500287086e3669b16ac7
Author: Dominik Schmidt <das1993@hotmail.com>
Date: Sun, 1 Jun 2014 13:45:41 +0200
Initial commit
Diffstat:
43 files changed, 2164 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+build/
+*.o
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -0,0 +1,105 @@
+cmake_minimum_required (VERSION 2.6)
+function(addlib lib)
+ GET_FILENAME_COMPONENT(libn ${lib} NAME)
+ STRING(REPLACE "/" "_" libn ${lib})
+ add_library("${libn}" "${EGONG_SRCDIR}/${lib}.c")
+ target_link_libraries(EGong "${libn}")
+endfunction(addlib)
+macro(absolute_libs dest libs)
+ foreach(lib ${libs})
+ if(NOT EXISTS ${lib})
+ find_library(ABS_${lib} ${lib})
+ if(NOT ABS_${lib} STREQUAL "ABS_${lib}-NOTFOUND")
+ set(${dest} ${${dest}} ${ABS_${lib}})
+ endif()
+ else(EXISTS ${lib})
+ set(${dest} ${${dest}} ${lib})
+ endif()
+ endforeach(lib)
+endmacro(absolute_libs)
+
+macro(include_pkgconfig)
+include(/mnt/Share/Programme/SelfBuilt/C/EGong/utils/CMakeModules/FindPkgConfig.cmake)
+endmacro(include_pkgconfig)
+
+macro(EGong_link_libs libs)
+ set(EGONG_EXT_LIBS "${EGONG_EXT_LIBS}${libs};")
+endmacro(EGong_link_libs)
+
+project(EGong)
+set(EGong_VERSION_MAJOR 0)
+set(EGong_VERSION_MINOR 1)
+set(EGONG_SRCDIR src/)
+set(EGONG_LIBS Interfaces/CMD Util/Command Interfaces Interfaces/STDIO CNC Util/Config Util/Socket Packet Util/Waiter Util/Log Util/Misc)
+set(EGONG_EXT_LIBS)
+include_directories("${PROJECT_SOURCE_DIR}/include")
+configure_file(
+ "${PROJECT_SOURCE_DIR}/include/Util/Config_Compiletime.h.in"
+ "${PROJECT_SOURCE_DIR}/include/Util/Config_Compiletime.h"
+)
+add_definitions(-std=gnu99)
+if(CMAKE_FIND_ROOT_PATH)
+ link_directories(${CMAKE_FIND_ROOT_PATH}/usr/lib)
+endif(CMAKE_FIND_ROOT_PATH)
+
+option(USE_GTK "Compile an interface for GTK" OFF)
+option(USE_AO "Compile an interface for Audio" OFF)
+option(USE_WINGUI "Compile an interface for the Windows GUI-Shell" OFF)
+
+add_executable(EGong src/EGong.c)
+
+if(USE_GTK)
+ find_package(GTK2)
+ if(GTK2_FOUND)
+ set(EGONG_LIBS ${EGONG_LIBS} Interfaces/GTK Interfaces/GTK/Message Interfaces/GTK/TrayIcon Interfaces/GTK/NewMessage)
+ include_directories(${GTK2_INCLUDE_DIRS})
+ EGong_link_libs("${GTK2_LIBRARIES}")
+ Message("${GTK2_LIBRARIES} vs ${EGONG_EXT_LIBS}")
+ else(NOT GTK2_FOUND)
+ set(USE_GTK OFF)
+ endif(GTK2_FOUND)
+endif(USE_GTK)
+
+if(USE_AO)
+ find_package(PkgConfig)
+ if(PKGCONFIG_FOUND)
+ pkg_check_modules(LIBAO ao)
+ if(LIBAO_FOUND)
+ set(EGONG_LIBS ${EGONG_LIBS} Interfaces/Audio)
+ include_directories(${LIBAO_INCLUDE_DIRS})
+ EGong_link_libs("${LIBAO_LIBRARIES} m")
+ else(NOT LIBAO_FOUND)
+ set(USE_AO OFF)
+ endif(LIBAO_FOUND)
+ endif(PKGCONFIG_FOUND)
+endif(USE_AO)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ EGong_link_libs("ws2_32")
+ if(USE_WINGUI)
+ set(EGONG_LIBS ${EGONG_LIBS} Interfaces/Windows)
+ EGong_link_libs("gdi32 wldap32")
+ endif(USE_WINGUI)
+endif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+
+find_package(OpenSSL REQUIRED)
+include_directories(${OPENSSL_INCLUDE_DIRS})
+target_link_libraries(EGong ${OPENSSL_LIBRARIES})
+
+
+foreach(lib ${EGONG_LIBS})
+ addlib(${lib})
+endforeach(lib)
+target_link_libraries(EGong ${EGONG_EXT_LIBS})
+
+
+#INSTALL
+install(TARGETS EGong DESTINATION bin)
+
+#PACKING
+absolute_libs(ABS_LIBS "${OPENSSL_LIBRARIES};${LIBAO_LIBRARIES}")
+set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${ABS_LIBS})
+include (InstallRequiredSystemLibraries)
+set (CPACK_PACKAGE_VERSION_MAJOR "${EGong_VERSION_MAJOR}")
+set (CPACK_PACKAGE_VERSION_MINOR "${EGong_VERSION_MINOR}")
+include (CPack)
diff --git a/include/CNC.h b/include/CNC.h
@@ -0,0 +1,18 @@
+#pragma once
+
+
+extern int EGong_cnc_init(unsigned int requirements);
+extern int EGong_cnc_sendmessage(const char *msg, const char *dest);
+extern int EGong_cnc_getmessage(char **msg);
+extern void EGong_cnc_freemessage(char *msg);
+extern void EGong_cnc_deinit(void);
+extern int EGong_cnc_sendmessage_broad(const char *msg);
+
+enum EGONG_INTERFACE_REQUIREMENTS{
+ EGONG_REQUIREMENT_NONE=(0),
+ EGONG_REQUIREMENT_LISTENER=(1<<0),
+ EGONG_REQUIREMENT_SOCKETS=(1<<1),
+ EGONG_REQUIREMENT_TERMINAL=(1<<2),
+ EGONG_REQUIREMENT_GTK=(1<<3),
+ EGONG_REQUIREMENT_ALL=(~0)
+};
diff --git a/include/EGong b/include/EGong
@@ -0,0 +1 @@
+./+
\ No newline at end of file
diff --git a/include/Interfaces.h b/include/Interfaces.h
@@ -0,0 +1,37 @@
+#pragma once
+#include <EGong/CNC.h>
+
+
+enum EGONG_INTERFACE_STATE{
+ EGONG_INTERFACE_ACTIVE=(1<<0),
+ EGONG_INTERFACE_SETUP=(1<<1)
+};
+
+struct EGong_interface{
+ char *name;
+ char identifier;
+ unsigned int requirements;
+ unsigned short int state;
+ int(*setup)(struct EGong_interface *interface);
+ int(*shutdown)(struct EGong_interface *interface);
+ int(*display_message)(struct EGong_interface *interface, const char *msg);
+ int(*cycle)(struct EGong_interface *interface, char **msg, char **dest);
+};
+extern unsigned short int EGong_interfaces_userstreams;
+extern int EGong_interface_init(unsigned int requirement_mask);
+extern int EGong_interface_cycle(void);
+extern void EGong_interface_deinit(void);
+extern struct EGong_interface EGong_interfaces[];
+extern int EGong_interface_setup(struct EGong_interface *interface);
+extern int EGong_interface_activate(struct EGong_interface *interface);
+extern int EGong_interface_shutdown(struct EGong_interface *interface);
+extern int EGong_interface_deactivate(struct EGong_interface *interface);
+extern struct EGong_interface *EGong_interface_get_from_id(char identifier);
+
+enum EGONG_INTERFACE_RETURN{
+ EGONG_INTERFACE_RETURN_FATAL=-2,
+ EGONG_INTERFACE_RETURN_ERROR=-1,
+ EGONG_INTERFACE_RETURN_OK=0,
+ EGONG_INTERFACE_RETURN_EXIT=1,
+ EGONG_INTERFACE_RETURN_BREAK=2
+};
diff --git a/include/Interfaces/Audio.h b/include/Interfaces/Audio.h
@@ -0,0 +1,6 @@
+#pragma once
+
+
+int EGong_if_audio_setup(struct EGong_interface *interface);
+int EGong_if_audio_display(struct EGong_interface *interface, const char *msg);
+int EGong_if_audio_shutdown(struct EGong_interface *interface);
diff --git a/include/Interfaces/CMD.h b/include/Interfaces/CMD.h
@@ -0,0 +1,27 @@
+#pragma once
+#include <EGong/Util/Command.h>
+#include <EGong/Interfaces.h>
+
+
+enum EGONG_IF_CMD_EXEC{
+ EGONG_IF_CMD_SETUP=(1<<0),
+ EGONG_IF_CMD_CYCLE=(1<<1),
+ EGONG_IF_CMD_SHUTDOWN=(1<<2)
+};
+
+struct EGong_command_if_cmd{
+ struct EGong_command command;
+ unsigned int execute;
+};
+
+extern int EGong_if_cmd_interfaceselect(const char *data);
+extern struct EGong_command_if_cmd *EGong_if_cmd_get_from_char(const char *commandline);
+extern int EGong_if_cmd_exec(unsigned int execution, struct EGong_interface *interface, char **msg, char **dest);
+extern int EGong_if_cmd_setup(struct EGong_interface *interface);
+extern int EGong_if_cmd_cycle(struct EGong_interface *interface, char **msg, char **dest);
+extern int EGong_if_cmd_shutdown(struct EGong_interface *interface);
+
+extern int EGong_if_cmd_gtk_msg(void);
+extern int EGong_if_cmd_windows_msg(void);
+extern int EGong_if_cmd_send_message(char *msg);
+extern int EGong_if_cmd_help(void);
diff --git a/include/Interfaces/GTK.h b/include/Interfaces/GTK.h
@@ -0,0 +1,17 @@
+#pragma once
+#include <EGong/Interfaces.h>
+#include <gtk/gtk.h>
+
+extern GtkWidget *Egong_if_gtk_root;
+int EGong_if_gtk_int_setup(unsigned int what);
+
+int EGong_if_gtk_setup(struct EGong_interface *interface);
+int EGong_if_gtk_cycle(struct EGong_interface *interface, char **msg, char **dest);
+int EGong_if_gtk_display(struct EGong_interface *interface, const char *msg);
+int EGong_if_gtk_shutdown(struct EGong_interface *interface);
+
+enum EGONG_IF_GTK_INIT{
+ EGONG_IF_GTK_INIT_ROOT=(1<<0),
+ EGONG_IF_GTK_INIT_TRAY=(1<<1),
+ EGONG_IF_GTK_INIT_ALL=(~0)
+};
diff --git a/include/Interfaces/GTK/Message.h b/include/Interfaces/GTK/Message.h
@@ -0,0 +1,2 @@
+#pragma once
+extern void EGong_if_gtk_msg_display(const char *msg);
diff --git a/include/Interfaces/GTK/NewMessage.h b/include/Interfaces/GTK/NewMessage.h
@@ -0,0 +1,8 @@
+#pragma once
+#include <gtk/gtk.h>
+extern GtkWidget *EGong_if_gtk_newmsg_dialog;
+extern void EGong_if_gtk_newmsg_send_callback(GtkDialog *caller, guint button, gpointer data);
+
+extern void EGong_if_gtk_newmsg_display_construct(unsigned short int single);
+extern void EGong_if_gtk_newmsg_display_single(void);
+extern void EGong_if_gtk_newmsg_display(void);
diff --git a/include/Interfaces/GTK/TrayIcon.h b/include/Interfaces/GTK/TrayIcon.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <gtk/gtk.h>
+extern GtkStatusIcon *EGong_if_gtk_tray_root;
+extern GtkWidget *EGong_if_gtk_tray_menu;
+extern void EGong_if_gtk_tray_popup(GtkStatusIcon *icon, guint button, guint activation_time, gpointer data);
+extern int EGong_if_gtk_tray_setup();
+
+struct EGong_if_gtk_tray_menu_call{
+ char *name;
+ char *tooltip;
+ char *message;
+};
diff --git a/include/Interfaces/STDIO.h b/include/Interfaces/STDIO.h
@@ -0,0 +1,7 @@
+#pragma once
+#include <EGong/Interfaces.h>
+
+
+extern int EGong_if_stdio_setup(struct EGong_interface *interface);
+extern int EGong_if_stdio_cycle(struct EGong_interface *interface, char **msg, char **dest);
+extern int EGong_if_stdio_display(struct EGong_interface *interface, const char *msg);
diff --git a/include/Interfaces/Windows.h b/include/Interfaces/Windows.h
@@ -0,0 +1,8 @@
+#pragma once
+
+
+extern int EGong_if_win_setup(struct EGong_interface *interface);
+extern int EGong_if_win_cycle(struct EGong_interface *interface, char **msg, char **dest);
+extern int EGong_if_win_display(struct EGong_interface *interface, const char *msg);
+
+extern int EGong_if_win_getmsgdialog();
diff --git a/include/Packet.h b/include/Packet.h
@@ -0,0 +1,31 @@
+#pragma once
+#include <stdint.h>
+#include <stddef.h>
+#include <openssl/sha.h>
+#include <EGong/Util/Socket.h>
+
+
+#define EGONG_PACKET_RAND_LENGTH 10
+#define EGONG_PACKET_HASH_LENGTH SHA256_DIGEST_LENGTH
+#define EGONG_PACKET_LENGTH_LENGTH sizeof(((struct EGong_packet*) 0)->message.length)
+
+#define EGONG_PACKET_MSGHEADLEN EGONG_PACKET_RAND_LENGTH+EGONG_PACKET_HASH_LENGTH+EGONG_PACKET_LENGTH_LENGTH
+#define EGONG_PACKET_MSGLEN(MSGSIZE) EGONG_PACKET_MSGHEADLEN+MSGSIZE
+
+struct EGong_packet{
+ char rand[EGONG_PACKET_RAND_LENGTH];
+ unsigned char hash[EGONG_PACKET_HASH_LENGTH];
+ struct {
+ uint16_t length;
+ char *data;
+ } message;
+};
+
+
+extern int EGong_calculate_package_hash(struct EGong_packet *packet, unsigned char *dest, char *cookie);
+extern int EGong_generate_packet(struct EGong_packet *packet, const char *msg, unsigned int msg_length);
+extern int EGong_send_packet(struct EGong_packet *packet, const char *dest);
+extern void EGong_packet_free(struct EGong_packet *packet);
+extern int EGong_packet_alloc(struct EGong_packet *packet, char **dest, unsigned int additional);
+extern int EGong_get_packet(SOCKET *sock, struct EGong_packet *packet);
+extern int EGong_packet_verify(struct EGong_packet *packet, char *cookie);
diff --git a/include/Util/Command.h b/include/Util/Command.h
@@ -0,0 +1,44 @@
+#pragma once
+#include <stddef.h>
+#include <stdint.h>
+#include <EGong/Util/Misc.h>
+struct EGong_command_type{
+ unsigned int type;
+ unsigned int args;
+};
+
+enum EGONG_COMMAND_TYPE{
+ EGONG_COMMAND_UINT_INC,
+ EGONG_COMMAND_UINT_DEC,
+ EGONG_COMMAND_UINT_SET,
+ EGONG_COMMAND_STR_SET,
+ EGONG_COMMAND_BOOL_TRUE,
+ EGONG_COMMAND_BOOL_FALSE,
+ EGONG_COMMAND_BOOL_SET,
+ EGONG_COMMAND_FUNC_VOID,
+ EGONG_COMMAND_FUNC_UINT,
+ EGONG_COMMAND_FUNC_CHAR,
+ EGONG_COMMAND_FUNC_2CHAR
+};
+enum EGONG_COMMAND_MATCH{
+ EGONG_COMMAND_MATCH_SHORT=(1<<0),
+ EGONG_COMMAND_MATCH_LONG=(1<<0),
+ EGONG_COMMAND_MATCH_ANY=~0
+};
+
+struct EGong_command{
+ char *longname;
+ char *shortname;
+ char *description;
+
+ struct EGong_command_type type;
+ void *pointer;
+};
+
+struct EGong_command_array{
+ struct EGong_static_array array;
+};
+
+extern struct EGong_command *EGong_command_match(struct EGong_command_array *commands, const char *data, unsigned int match_type);
+extern int EGong_command_exec(struct EGong_command *command, void **data);
+extern void EGong_command_print_help(struct EGong_command_array *commands, int destination, char *appendix);
diff --git a/include/Util/Config.h b/include/Util/Config.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include <EGong/Util/Config_Compiletime.h>
+
+struct EGong_config_log{
+ unsigned short int level;
+ unsigned short int color;
+ unsigned int destinations;
+};
+struct EGong_config_packet{
+ size_t packet_maxlen;
+ char *cookie;
+};
+struct EGong_config_server{
+ unsigned int port;
+ char *bind_ip;
+};
+struct EGong_config{
+ struct EGong_config_log log;
+ struct EGong_config_server server;
+ struct EGong_config_packet packet;
+};
+
+struct EGong_config_file_entry{
+ char *name;
+ unsigned short int type;
+ uintptr_t data_offset;
+};
+enum EGONG_CONFIG_FILE_ENTRY{
+ EGONG_CONFIG_FILE_LOG_LEVEL,
+ EGONG_CONFIG_FILE_LOG_COLOR,
+ EGONG_CONFIG_FILE_LOG_DEST,
+ EGONG_CONFIG_FILE_PACKET_LEN,
+ EGONG_CONFIG_FILE_PACKET_COOKIE,
+ EGONG_CONFIG_FILE_SERVER_PORT,
+ EGONG_CONFIG_FILE_SERVER_BINDIP,
+ EGONG_CONFIG_FILE_ENTRYCOUNT,
+};
+enum EGONG_CONFIG_FILE_TYPE{
+ EGONG_CONFIG_TYPE_STRING,
+ EGONG_CONFIG_TYPE_UINT,
+ EGONG_CONFIG_TYPE_BITMASK,
+ EGONG_CONFIG_TYPE_BOOL,
+};
+extern struct EGong_config_file_entry EGong_configuration_file_interface[EGONG_CONFIG_FILE_ENTRYCOUNT];
+
+extern struct EGong_config EGong_global_configuration;
+
+extern void EGong_config_set_defaults(struct EGong_config *conf);
+extern void EGong_config_init(struct EGong_config *conf);
+
diff --git a/include/Util/Config_Compiletime.h b/include/Util/Config_Compiletime.h
@@ -0,0 +1,4 @@
+/* #undef USE_GTK */
+/* #undef USE_AO */
+/* #undef USE_WINGUI */
+
diff --git a/include/Util/Config_Compiletime.h.in b/include/Util/Config_Compiletime.h.in
@@ -0,0 +1,4 @@
+#cmakedefine USE_GTK
+#cmakedefine USE_AO
+#cmakedefine USE_WINGUI
+
diff --git a/include/Util/File.h b/include/Util/File.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/include/Util/Log.h b/include/Util/Log.h
@@ -0,0 +1,55 @@
+#pragma once
+#define WIDEN2(x) # x
+#define WIDEN(x) WIDEN2(x)
+
+#define LOG_COMPOSE_SRC (const struct log_source){.file={.v=__FILE__, .l=sizeof(__FILE__)}, .line={.v=WIDEN(__LINE__), .l=sizeof(WIDEN(__LINE__))}, .func={.v=__func__, .l=sizeof(__func__)}}
+
+#include <string.h>
+#include <EGong/Util/Config.h>
+struct log_source_string{
+ const char *v;
+ unsigned int l;
+};
+struct log_source{
+ struct log_source_string file;
+ struct log_source_string line;
+ struct log_source_string func;
+};
+enum LOG_LEVELS{
+ LOG_LEVEL_DEBUG,
+ LOG_LEVEL_INFO,
+ LOG_LEVEL_WARNING,
+ LOG_LEVEL_ERROR,
+ LOG_LEVEL_FATAL,
+ LOG_LEVEL_COUNT
+};
+enum LOG_DESTINATIONS{
+ LOG_DEST_STDIO=(1<<0),
+ LOG_DEST_FILE=(1<<1),
+ LOG_DEST_GTK=(1<<2)
+};
+enum LOG_TYPES{
+ LOG_TYPE_NORMAL,
+ LOG_TYPE_RESULT,
+ LOG_TYPE_RAW,
+ LOG_TYPE_SIGNAL
+ #ifdef _WIN32
+ ,LOG_TYPE_SOCKET
+ #endif
+};
+#ifndef _WIN32
+ #define LOG_TYPE_SOCKET LOG_TYPE_SIGNAL
+#endif
+struct log_level{
+ const char *name;
+ char color[10];
+};
+
+
+extern void do_log_call(const struct log_source src, const char *msg, unsigned int msglength, unsigned int type, unsigned int level, unsigned int destmask);
+extern void do_log_call_composite(const struct log_source src, unsigned int type, unsigned int level, unsigned int destmask, ...);
+extern struct log_level log_levels[LOG_LEVEL_COUNT];
+
+#define do_log(MSG, TYPE, LEVEL) do_log_call(LOG_COMPOSE_SRC,MSG,sizeof(MSG),TYPE,LEVEL,EGong_global_configuration.log.destinations)
+#define do_log_comp(TYPE, LEVEL, MSGS) do_log_call_composite(LOG_COMPOSE_SRC,TYPE,LEVEL,EGong_global_configuration.log.destinations, #MSGS, NULL)
+#define do_log_dynamic(MSG, TYPE, LEVEL) do_log_call(LOG_COMPOSE_SRC,MSG,strlen(MSG),TYPE,LEVEL,EGong_global_configuration.log.destinations)
diff --git a/include/Util/Misc.h b/include/Util/Misc.h
@@ -0,0 +1,20 @@
+#pragma once
+#include <stddef.h>
+#include <unistd.h>
+#define CSIZEOF(VAR) (sizeof(VAR))/(sizeof(*(VAR)))
+
+extern int EGong_global_argc;
+extern char **EGong_global_argv;
+extern int EGong_misc_get_rand(char *dest, size_t length);
+
+#define STDNWRITE(str,len) (void)write(STDOUT_FILENO, str, len)
+#define STDWRITE(str) STDNWRITE(str,sizeof(str))
+#define STDWRITED(str) STDNWRITE(str,strlen(str))
+#define STRNCAT(dest,str,len) strncpy(dest,str,len); dest+=len;
+#define STRCAT(dest,str) STRNCAT(dest,str,sizeof(str)-1)
+
+struct EGong_static_array{
+ void *elements;
+ ssize_t element_count;
+ ssize_t element_size;
+};
diff --git a/include/Util/Socket.h b/include/Util/Socket.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <EGong/Util/Config.h>
+#ifdef _WIN32
+ #include <winsock2.h>
+ #define MSG_DONTWAIT 0
+ typedef short sa_family_t;
+#else
+ #include <sys/socket.h>
+ typedef int SOCKET;
+#endif
+extern SOCKET EGong_listen_sock;
+
+extern int EGong_sockets_setup(void);
+extern int EGong_sockets_shutdown(void);
+extern void EGong_socket_close(SOCKET *sock);
+extern int EGong_listener_init(SOCKET *sock, struct EGong_config_server *config);
+extern int EGong_listener_get(SOCKET *sock, char *dest, int length, struct sockaddr *source, int flags);
+extern int EGong_socket_open(SOCKET *sock);
+extern int EGong_sendto(SOCKET *sock, const char *dest, const char *msg, size_t msg_len, struct EGong_config_server *config);
+extern void EGong_listener_close(SOCKET *sock);
+extern int EGong_socket_cmp_ip(SOCKET *sock, struct sockaddr *sockaddr);
diff --git a/include/Util/Waiter.h b/include/Util/Waiter.h
@@ -0,0 +1,13 @@
+#pragma once
+
+extern unsigned int EGong_waiter_highest_fd;
+extern int EGong_waiter_init(void);
+extern int EGong_waiter_add(int sock, unsigned short int type);
+extern int EGong_waiter_del(int sock);
+extern int EGong_waiter_wait(void);
+
+
+enum EGONG_WAITER_TYPE{
+ EGONG_WAITER_FD,
+ EGONG_WAITER_SOCKET
+};
diff --git a/src/CNC.c b/src/CNC.c
@@ -0,0 +1,95 @@
+#define WIN32_LEAN_AND_MEAN
+#include <EGong/CNC.h>
+#include <EGong/Packet.h>
+#include <EGong/Util/Socket.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Waiter.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef EGONG_USE_GTK
+ #include <EGong/Interfaces/GTK.h>
+#endif
+
+
+
+unsigned int EGong_cnc_running=0;
+
+int EGong_cnc_init(unsigned int requirements){
+ if((requirements&(EGONG_REQUIREMENT_SOCKETS|EGONG_REQUIREMENT_LISTENER)&~EGong_cnc_running)>0){
+ if(EGong_sockets_setup()<0){
+ do_log("Couldn't initialize sockets", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
+ return -1;
+ }
+ else{
+ EGong_cnc_running|=EGONG_REQUIREMENT_SOCKETS;
+ }
+ }
+ if((requirements&EGONG_REQUIREMENT_LISTENER&~EGong_cnc_running)>0){
+ if(EGong_listener_init(NULL,NULL)<0){
+ do_log("Couldn't initialize listener", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
+ return -1;
+ }
+ else{
+ EGong_waiter_add(EGong_listen_sock, EGONG_WAITER_SOCKET);
+ EGong_cnc_running|=EGONG_REQUIREMENT_LISTENER;
+ }
+ }
+ #ifdef EGONG_USE_GTK
+ if((requirements&EGONG_REQUIREMENT_GTK&~EGong_cnc_running)>0){
+ if(EGong_if_gtk_int_setup(EGONG_IF_GTK_INIT_ROOT)<0){
+ do_log("Couldn't initialize GTK", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -2;
+ }
+ else{
+ EGong_cnc_running|=EGONG_REQUIREMENT_GTK;
+ }
+ }
+ #endif
+ return 0;
+}
+int EGong_cnc_sendmessage_broad(const char *msg){
+ return EGong_cnc_sendmessage(msg, NULL);
+}
+int EGong_cnc_sendmessage(const char *msg, const char *dest){
+ if(dest==NULL){
+ dest="255.255.255.255";
+ }
+ struct EGong_packet packet;
+ EGong_generate_packet(&packet, msg, strlen(msg));
+ if(EGong_send_packet(&packet, dest)<0){
+ do_log("Couldn't send packet.", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ }
+ else{
+ do_log("Message sent", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ }
+ return 0;
+}
+
+int EGong_cnc_getmessage(char **msg){
+ struct EGong_packet packet;
+ int ret=EGong_get_packet(NULL, &packet);
+ if(ret!=0){
+ return ret;
+ }
+ if(EGong_packet_verify(&packet, NULL)){
+ *msg=packet.message.data;
+ }
+ else{
+ EGong_packet_free(&packet);
+ do_log("Packet didn't verify.", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);
+ return -2;
+ }
+ return ret;
+}
+void EGong_cnc_freemessage(char *msg){
+ struct EGong_packet virtpack;
+ virtpack.message.data=msg;
+ EGong_packet_free(&virtpack);
+}
+
+void EGong_cnc_deinit(void){
+ if((EGong_cnc_running&EGONG_REQUIREMENT_LISTENER)>0){
+ EGong_listener_close(NULL);
+ EGong_sockets_shutdown();
+ }
+}
diff --git a/src/EGong b/src/EGong
Binary files differ.
diff --git a/src/EGong.c b/src/EGong.c
@@ -0,0 +1,32 @@
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Misc.h>
+#include <EGong/Util/Config.h>
+#include <EGong/Interfaces.h>
+#include <EGong/Util/Waiter.h>
+#include <EGong/CNC.h>
+#include <EGong/Packet.h>
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+int main(int argc, char **argv){
+
+ EGong_config_init(NULL);
+ EGong_global_argc=argc;
+ EGong_global_argv=argv;
+ if(EGong_waiter_init()<0){
+ return -1;
+ }
+
+ if(EGong_interface_init(0)<0){
+ return -1;
+ }
+
+ while(EGong_interface_cycle()==0){
+ EGong_waiter_wait();
+ }
+
+ EGong_cnc_deinit();
+ return 0;
+}
diff --git a/src/Interfaces.c b/src/Interfaces.c
@@ -0,0 +1,263 @@
+#include <EGong/CNC.h>
+#include <EGong/Interfaces/STDIO.h>
+#include <EGong/Interfaces/CMD.h>
+#include <EGong/Util/Config.h>
+#ifdef USE_GTK
+ #include <EGong/Interfaces/GTK.h>
+#endif
+#ifdef USE_AO
+ #include <EGong/Interfaces/Audio.h>
+#endif
+#ifdef USE_WINGUI
+ #include <EGong/Interfaces/Windows.h>
+#endif
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Misc.h>
+#include <stdlib.h>
+
+struct EGong_interface EGong_interfaces[]={
+ {
+ .name="CMD",
+ .identifier='C',
+ .requirements=EGONG_REQUIREMENT_NONE,
+ .state=EGONG_INTERFACE_ACTIVE,
+ .setup=&EGong_if_cmd_setup,
+ .cycle=&EGong_if_cmd_cycle,
+ .display_message=NULL,
+ .shutdown=NULL
+ },
+ {
+ .name="STDIO",
+ .identifier='S',
+ .requirements=EGONG_REQUIREMENT_LISTENER|EGONG_REQUIREMENT_TERMINAL,
+ .state=0,
+ .setup=&EGong_if_stdio_setup,
+ .cycle=&EGong_if_stdio_cycle,
+ .display_message=&EGong_if_stdio_display,
+ .shutdown=NULL
+ },
+ #ifdef USE_GTK
+ {
+ .name="GTK",
+ .identifier='G',
+ .requirements=EGONG_REQUIREMENT_LISTENER|EGONG_REQUIREMENT_GTK,
+ .state=0,
+ .setup=&EGong_if_gtk_setup,
+ .cycle=&EGong_if_gtk_cycle,
+ .display_message=&EGong_if_gtk_display,
+ .shutdown=&EGong_if_gtk_shutdown
+ },
+ #endif
+ #ifdef USE_AO
+ {
+ .name="Audio",
+ .identifier='A',
+ .requirements=EGONG_REQUIREMENT_LISTENER,
+ .state=0,
+ .setup=&EGong_if_audio_setup,
+ .cycle=NULL,
+ .display_message=&EGong_if_audio_display,
+ .shutdown=&EGong_if_audio_shutdown
+ }
+ #endif
+ #ifdef USE_WINGUI
+ {
+ .name="WinGUI",
+ .identifier='W',
+ .requirements=EGONG_REQUIREMENT_LISTENER,
+ .state=0,
+ .setup=&EGong_if_win_setup,
+ .cycle=NULL,
+ .display_message=NULL,
+ .shutdown=NULL
+ }
+ #endif
+};
+unsigned short int EGong_interfaces_global_init_done=0;
+unsigned short int EGong_interfaces_userstreams=0;
+unsigned int EGong_interfaces_requirements=0;
+unsigned int EGong_interfaces_requirement_mask=0;
+
+unsigned short int EGong_interface_if_count_ustream(struct EGong_interface *interface){
+ unsigned short int streams=0;
+ if(interface->display_message!=NULL){
+ streams++;
+ }
+ if(interface->cycle!=NULL){
+ streams++;
+ }
+ return streams;
+}
+int EGong_interface_setup(struct EGong_interface *interface){
+ if((interface->requirements&EGong_interfaces_requirement_mask)>0){
+ do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_ERROR, EGong_global_configuration.log.destinations, "Couldn't setup interface ", interface->name, " due to unmet dependencies", NULL);
+ }
+ else{
+ if(EGong_cnc_init(interface->requirements&(~EGong_interfaces_requirements))<0){
+ do_log("Couldn't get requirements", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+ else{
+ EGong_interfaces_requirements|=interface->requirements;
+ }
+ }
+ if(interface->setup!=NULL&&interface->setup(interface)<0){
+ do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_ERROR, EGong_global_configuration.log.destinations, "Couldn't setup interface ", interface->name, NULL);
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+ interface->state|=EGONG_INTERFACE_SETUP;
+ EGong_interfaces_userstreams+=EGong_interface_if_count_ustream(interface);
+ return 0;
+}
+int EGong_interface_activate(struct EGong_interface *interface){
+ if((interface->state&EGONG_INTERFACE_SETUP)==0&&EGong_interfaces_global_init_done==1){
+ if(EGong_interface_setup(interface)<0){
+ return -1;
+ }
+ }
+ if((interface->state&EGONG_INTERFACE_ACTIVE)>0){
+ return 1;
+ }
+ interface->state|=EGONG_INTERFACE_ACTIVE;
+ EGong_interfaces_userstreams+=EGong_interface_if_count_ustream(interface);
+ return 0;
+}
+int EGong_interface_shutdown(struct EGong_interface *interface){
+ if((interface->state&EGONG_INTERFACE_SETUP)>0){
+ return 1;
+ }
+ int ret=0;
+ if(interface->shutdown(interface)<0){
+ do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_ERROR, EGong_global_configuration.log.destinations, "Couldn't shutdown interface ", interface->name, NULL);
+ ret=-1;
+ }
+ interface->state&=~EGONG_INTERFACE_SETUP;
+ EGong_interface_deactivate(interface);
+ return ret;
+}
+int EGong_interface_deactivate(struct EGong_interface *interface){
+ if((interface->state&EGONG_INTERFACE_ACTIVE)==0){
+ return 1;
+ }
+ interface->state&=~EGONG_INTERFACE_ACTIVE;
+ EGong_interfaces_userstreams-=EGong_interface_if_count_ustream(interface);
+ return 0;
+}
+struct EGong_interface *EGong_interface_get_from_id(char identifier){
+ int i;
+ for(i=0; i<CSIZEOF(EGong_interfaces); i++){
+ if(EGong_interfaces[i].identifier==identifier){
+ return &EGong_interfaces[i];
+ }
+ }
+ return NULL;
+}
+int EGong_interface_interpret_ret(int ret){
+ switch(ret){
+ case EGONG_INTERFACE_RETURN_FATAL:
+ do_log("Couldn't run interface function, exiting", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
+ case EGONG_INTERFACE_RETURN_ERROR:
+ do_log("Couldn't run interface function, skipping", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ break;
+ case EGONG_INTERFACE_RETURN_EXIT:
+ do_log("Interface function requested exit", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);
+ break;
+ case EGONG_INTERFACE_RETURN_BREAK:
+ do_log("Interface function requested queueabortion", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);
+ break;
+ }
+ return ret;
+}
+int EGong_interface_init(unsigned int requirement_mask){
+ EGong_interfaces_requirement_mask=requirement_mask;
+ int i, ret;
+ for(i=0; i<CSIZEOF(EGong_interfaces); i++){
+ if((EGong_interfaces[i].state&(EGONG_INTERFACE_ACTIVE))>0&&EGong_interfaces[i].setup!=NULL){
+ ret=EGong_interface_interpret_ret(EGong_interface_setup(&EGong_interfaces[i]));
+ if(ret>EGONG_INTERFACE_RETURN_OK){
+ EGong_interfaces[i].state&=~(EGONG_INTERFACE_ACTIVE|EGONG_INTERFACE_SETUP);
+ }
+ if(ret==EGONG_INTERFACE_RETURN_FATAL){
+ return -1;
+ }
+ else if(ret==EGONG_INTERFACE_RETURN_EXIT){
+ return 1;
+ }
+ else if(ret==EGONG_INTERFACE_RETURN_BREAK){
+ break;
+ }
+ }
+ }
+ if(EGong_interfaces_userstreams==0){
+ do_log("No userstreams available", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
+ return -1;
+ }
+ EGong_interfaces_global_init_done=1;
+ do_log("Interfaces initialized", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ return 0;
+}
+int EGong_interface_cycle(void){
+ if(EGong_interfaces_userstreams==0){
+ do_log("No userstreams found, exiting...", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);
+ return 1;
+ }
+ int i, ret;
+ char* msg;
+ char *dest;
+ for(i=0; i<CSIZEOF(EGong_interfaces); i++){
+ if((EGong_interfaces[i].state&EGONG_INTERFACE_ACTIVE)>0&&EGong_interfaces[i].cycle!=NULL){
+ msg=dest=NULL;
+ ret=EGong_interface_interpret_ret(EGong_interfaces[i].cycle(&EGong_interfaces[i], &msg, &dest));
+ if(ret==EGONG_INTERFACE_RETURN_FATAL){
+ return -1;
+ }
+ else if(ret==EGONG_INTERFACE_RETURN_EXIT){
+ return 1;
+ }
+ else if(ret==EGONG_INTERFACE_RETURN_BREAK){
+ break;
+ }
+ else if(msg!=NULL){
+ EGong_cnc_sendmessage(msg, NULL);
+ free(msg);
+ }
+ }
+ }
+ msg=NULL;
+ if(((EGong_interfaces_requirements&EGONG_REQUIREMENT_LISTENER)>0)&&EGong_cnc_getmessage(&msg)==0){
+ for(i=0; i<CSIZEOF(EGong_interfaces); i++){
+ if((EGong_interfaces[i].state&EGONG_INTERFACE_ACTIVE)>0&&EGong_interfaces[i].display_message!=NULL){
+ ret=EGong_interface_interpret_ret(EGong_interfaces[i].display_message(&EGong_interfaces[i],msg));
+ if(ret==EGONG_INTERFACE_RETURN_FATAL){
+ return -1;
+ }
+ else if(ret==EGONG_INTERFACE_RETURN_EXIT){
+ return 1;
+ }
+ else if(ret==EGONG_INTERFACE_RETURN_BREAK){
+ break;
+ }
+ }
+ }
+ }
+ if(msg!=NULL){
+ EGong_cnc_freemessage(msg);
+ }
+ return 0;
+}
+
+void EGong_interface_deinit(void){
+ EGong_cnc_deinit();
+ int i, ret;
+ for(i=0; i<sizeof(EGong_interfaces)/sizeof(*EGong_interfaces); i++){
+ if((EGong_interfaces[i].state&EGONG_INTERFACE_SETUP)>0&&EGong_interfaces[i].shutdown!=NULL){
+ ret=EGong_interface_interpret_ret(EGong_interface_shutdown(&EGong_interfaces[i]));
+ if(ret==EGONG_INTERFACE_RETURN_EXIT){
+ return;
+ }
+ else if(ret==EGONG_INTERFACE_RETURN_BREAK){
+ break;
+ }
+ }
+ }
+}
diff --git a/src/Interfaces/Audio.c b/src/Interfaces/Audio.c
@@ -0,0 +1,62 @@
+#include <ao/ao.h>
+#include <EGong/Interfaces.h>
+#include <EGong/Util/Log.h>
+#include <string.h>
+#include <math.h>
+
+
+#define BUFFERSIZE EGong_if_audio_format.bits/8 * EGong_if_audio_format.channels * EGong_if_audio_format.rate
+
+ao_device *EGong_if_audio_device;
+ao_sample_format EGong_if_audio_format;
+int EGong_if_audio_driver;
+char *EGong_if_audio_buffer;
+
+int EGong_if_audio_setup(struct EGong_interface *interface){
+ ao_initialize();
+ do_log("Initialized audio", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ EGong_if_audio_driver = ao_default_driver_id();
+ if(EGong_if_audio_driver==-1){
+ do_log("Couldn't get default driver ID", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ ao_shutdown();
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+ do_log("Got driver ID", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+
+ memset(&EGong_if_audio_format, 0, sizeof(EGong_if_audio_format));
+ EGong_if_audio_format.bits = 16;
+ EGong_if_audio_format.channels = 2;
+ EGong_if_audio_format.rate = 11025;
+ EGong_if_audio_format.byte_format = AO_FMT_LITTLE;
+
+ EGong_if_audio_device=ao_open_live(EGong_if_audio_driver, &EGong_if_audio_format, NULL);
+ if(EGong_if_audio_device==NULL){
+ do_log("couldn't open device", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ ao_shutdown();
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+ do_log("Opened audio device", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+
+ EGong_if_audio_buffer = calloc(BUFFERSIZE,sizeof(char));
+
+ int sample,i;
+ for (i = 0; i < EGong_if_audio_format.rate; i++) {
+ sample = (int)(1 * 32768.0 *
+ sin(2 * M_PI * 440.0 * ((float) i/EGong_if_audio_format.rate)));
+ EGong_if_audio_buffer[4*i] = EGong_if_audio_buffer[4*i+2] = sample & 0xff;
+ EGong_if_audio_buffer[4*i+1] = EGong_if_audio_buffer[4*i+3] = (sample >> 8) & 0xff;
+ }
+ return EGONG_INTERFACE_RETURN_OK;
+}
+int EGong_if_audio_display(struct EGong_interface *interface, const char *msg){
+
+ do_log("Playing Audio", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ ao_play(EGong_if_audio_device, EGong_if_audio_buffer, BUFFERSIZE);
+ return EGONG_INTERFACE_RETURN_OK;
+}
+
+int EGong_if_audio_shutdown(struct EGong_interface *interface){
+ ao_close(EGong_if_audio_device);
+ ao_shutdown();
+ return EGONG_INTERFACE_RETURN_OK;
+}
diff --git a/src/Interfaces/CMD.c b/src/Interfaces/CMD.c
@@ -0,0 +1,181 @@
+#include <EGong/Interfaces.h>
+#include <EGong/Interfaces/CMD.h>
+#include <EGong/Interfaces.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Misc.h>
+#include <EGong/Util/Command.h>
+#include <EGong/Util/Config.h>
+#include <stddef.h>
+#include <stdint.h>
+#ifdef USE_GTK
+ #include <EGong/Interfaces/GTK/NewMessage.h>
+#endif
+#ifdef USE_WINGUI
+ #include <EGong/Interfaces/Windows.h>
+#endif
+#ifdef _WIN32
+ #include <stdio.h>
+#endif
+int EGong_global_argc;
+char **EGong_global_argv;
+
+struct EGong_command_if_cmd EGong_if_cmd_commands[]={
+ {
+ .command={
+ .longname="verbose",
+ .shortname="v",
+ .description="Increase verbosity",
+ .type={.type=EGONG_COMMAND_UINT_DEC, .args=0},
+ .pointer=&EGong_global_configuration.log.level
+ },
+ .execute=EGONG_IF_CMD_SETUP
+ },
+ {
+ .command={
+ .longname="quiet",
+ .shortname="q",
+ .description="Decrease verbosity",
+ .type={.type=EGONG_COMMAND_UINT_INC, .args=0},
+ .pointer=&EGong_global_configuration.log.level
+ },
+ .execute=EGONG_IF_CMD_SETUP
+ },
+ {
+ .command={
+ .longname="help",
+ .shortname="h",
+ .description="Displays the help message",
+ .type={.type=EGONG_COMMAND_FUNC_VOID, .args=0},
+ .pointer=&EGong_if_cmd_help
+ },
+ .execute=EGONG_IF_CMD_SETUP
+ },
+ {
+ .command={
+ .longname="interface",
+ .shortname="I",
+ .description="Select an interface",
+ .type={.type=EGONG_COMMAND_FUNC_CHAR, .args=1},
+ .pointer=&EGong_if_cmd_interfaceselect
+ },
+ .execute=EGONG_IF_CMD_SETUP
+ },
+ {
+ .command={
+ .longname="send-message",
+ .shortname="s",
+ .description="Sends a message",
+ .type={.type=EGONG_COMMAND_FUNC_CHAR, .args=1},
+ .pointer=&EGong_if_cmd_send_message
+ },
+ .execute=EGONG_IF_CMD_CYCLE
+ },
+ #ifdef USE_GTK
+ {
+ .command={
+ .longname="gtk-message",
+ .shortname="g",
+ .description="Opens the GTK-Message dialog",
+ .type={.type=EGONG_COMMAND_FUNC_VOID, .args=0},
+ .pointer=&EGong_if_cmd_gtk_msg
+ },
+ .execute=EGONG_IF_CMD_CYCLE
+ },
+ #endif
+ #ifdef USE_WINGUI
+ {
+ .command={
+ .longname="windows-message",
+ .shortname="w",
+ .description="Opens the Windows-Message dialog",
+ .type={.type=EGONG_COMMAND_FUNC_VOID, .args=0},
+ .pointer=&EGong_if_cmd_windows_msg
+ },
+ .execute=EGONG_IF_CMD_CYCLE
+ },
+ #endif
+};
+struct EGong_command_array EGong_if_cmd_commandarray={.array={
+ .elements=&EGong_if_cmd_commands,
+ .element_size=sizeof(*EGong_if_cmd_commands),
+ .element_count=CSIZEOF(EGong_if_cmd_commands),
+}};
+
+#ifdef USE_GTK
+int EGong_if_cmd_gtk_msg(void){
+ EGong_cnc_init(EGONG_REQUIREMENT_GTK);
+ EGong_if_gtk_newmsg_display_single();
+ gtk_main();
+ return EGONG_INTERFACE_RETURN_OK;
+}
+#endif
+#ifdef USE_WINGUI
+int EGong_if_cmd_windows_msg(void){
+ EGong_cnc_init(EGONG_REQUIREMENT_SOCKETS);
+ EGong_if_win_getmsgdialog();
+ return EGONG_INTERFACE_RETURN_OK;
+}
+#endif
+int EGong_if_cmd_send_message(char *msg){
+ EGong_cnc_init(EGONG_REQUIREMENT_SOCKETS);
+ EGong_cnc_sendmessage_broad(msg);
+ return EGONG_INTERFACE_RETURN_OK;
+}
+int EGong_if_cmd_help(void){
+ STDWRITE("Usage: ");
+ STDWRITED(EGong_global_argv[0]);
+ STDWRITE("\n");
+ EGong_command_print_help(&EGong_if_cmd_commandarray, STDOUT_FILENO, "\t");
+ return EGONG_INTERFACE_RETURN_OK;
+}
+int EGong_if_cmd_interfaceselect(const char *data){
+ struct EGong_interface *interface;
+
+ interface=EGong_interface_get_from_id(data[0]);
+ if(interface==NULL){
+ do_log("Malformed interface specified", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ return -EGONG_INTERFACE_RETURN_ERROR;
+ }
+ EGong_interface_activate(interface);
+ return EGONG_INTERFACE_RETURN_OK;
+}
+
+struct EGong_command_if_cmd *EGong_if_cmd_get_from_char(const char *commandline){
+ const char *valptr=commandline;
+ while(*++valptr=='-');
+ return (struct EGong_command_if_cmd *)EGong_command_match(&EGong_if_cmd_commandarray,valptr,EGONG_COMMAND_MATCH_ANY);
+}
+int EGong_if_cmd_exec(unsigned int execution, struct EGong_interface *interface, char **msg, char **dest){
+ int i;
+ char *arg;
+ struct EGong_command_if_cmd *command=NULL;
+ for(i=1; i<EGong_global_argc; i++){
+ arg=EGong_global_argv[i];
+ command=EGong_if_cmd_get_from_char(arg);
+ if(command==NULL){
+ do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_WARNING, EGong_global_configuration.log.destinations, "Command \"", arg, "\" not found", NULL);
+ continue;
+ }
+ if((command->execute&execution)>0){
+ EGong_command_exec((struct EGong_command *)command, (void **)&EGong_global_argv[i+1]);
+ }
+ i+=command->command.type.args;
+ command=NULL;
+ }
+ return EGONG_INTERFACE_RETURN_OK;
+}
+int EGong_if_cmd_setup(struct EGong_interface *interface){
+ EGong_if_cmd_exec(EGONG_IF_CMD_SETUP, interface, NULL, NULL);
+ return EGONG_INTERFACE_RETURN_OK;
+}
+
+int EGong_if_cmd_cycle(struct EGong_interface *interface, char **msg, char **dest){
+ EGong_if_cmd_exec(EGONG_IF_CMD_CYCLE, interface, NULL, NULL);
+ EGong_interface_deactivate(interface);
+ return EGONG_INTERFACE_RETURN_OK;
+}
+
+int EGong_if_cmd_shutdown(struct EGong_interface *interface){
+ EGong_if_cmd_exec(EGONG_IF_CMD_SHUTDOWN, interface, NULL, NULL);
+ return EGONG_INTERFACE_RETURN_OK;
+}
diff --git a/src/Interfaces/GTK.c b/src/Interfaces/GTK.c
@@ -0,0 +1,57 @@
+#include <EGong/Interfaces/GTK/TrayIcon.h>
+#include <EGong/Interfaces/GTK/Message.h>
+#include <EGong/Interfaces/GTK.h>
+#include <EGong/Interfaces.h>
+#include <EGong/Util/Misc.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Interfaces.h>
+#include <gtk/gtk.h>
+
+GtkWidget *Egong_if_gtk_root;
+
+unsigned int EGong_if_gtk_initialized;
+int EGong_if_gtk_int_setup(unsigned int what){
+ gtk_init(&EGong_global_argc, &EGong_global_argv);
+ if((what&EGONG_IF_GTK_INIT_ROOT&~EGong_if_gtk_initialized)>0){
+ Egong_if_gtk_root=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ if(Egong_if_gtk_root!=NULL){
+ EGong_if_gtk_initialized|=EGONG_IF_GTK_INIT_ROOT;
+ }
+ else{
+ do_log("Couldn't initialize rootwindow", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ }
+ if((what&EGONG_IF_GTK_INIT_TRAY&~EGong_if_gtk_initialized)>0){
+ if(EGong_if_gtk_tray_setup()<0){
+ do_log("Couldn't initialize tray", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -2;
+ }
+ else{
+ EGong_if_gtk_initialized|=EGONG_IF_GTK_INIT_TRAY;
+ }
+ }
+ return 0;
+}
+int EGong_if_gtk_setup(struct EGong_interface *interface){
+ if(EGong_if_gtk_int_setup(EGONG_IF_GTK_INIT_ALL)<0){
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+ return 0;
+}
+int EGong_if_gtk_cycle(struct EGong_interface *interface, char **msg, char **dest){
+ interface->cycle=NULL; //Prevent any further execution
+ EGong_interfaces_userstreams--; //GTK takes over the job of cycling the interfaces.
+ gtk_main();
+ return EGONG_INTERFACE_RETURN_EXIT;
+}
+
+int EGong_if_gtk_display(struct EGong_interface *interface, const char *msg){
+ EGong_if_gtk_msg_display(msg); //Shouldn't acutally be used anyway...
+ return EGONG_INTERFACE_RETURN_OK;
+}
+
+int EGong_if_gtk_shutdown(struct EGong_interface *interface){
+ gtk_main_quit();
+ return EGONG_INTERFACE_RETURN_OK;
+}
diff --git a/src/Interfaces/GTK/Message.c b/src/Interfaces/GTK/Message.c
@@ -0,0 +1,19 @@
+#include <EGong/Interfaces/GTK/Message.h>
+#include <EGong/Interfaces/GTK.h>
+#include <gtk/gtk.h>
+
+void EGong_if_gtk_msg_display(const char *msg){
+ GtkWidget *dialog = gtk_dialog_new_with_buttons("Nachricht",
+ GTK_WINDOW(Egong_if_gtk_root),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
+ GtkWidget *Message;
+ GtkWidget *content_area=gtk_dialog_get_content_area(GTK_DIALOG (dialog));
+ Message=gtk_label_new(msg);
+ gtk_container_add (GTK_CONTAINER (content_area), Message);
+ g_signal_connect_swapped(dialog, "response", G_CALLBACK (gtk_widget_destroy), (gpointer)dialog);
+
+ gtk_widget_show_all(dialog);
+}
diff --git a/src/Interfaces/GTK/NewMessage.c b/src/Interfaces/GTK/NewMessage.c
@@ -0,0 +1,47 @@
+#include <gtk/gtk.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Interfaces/GTK/NewMessage.h>
+#include <EGong/Interfaces/GTK/TrayIcon.h>
+#include <EGong/Interfaces/GTK.h>
+GtkWidget *EGong_if_gtk_newmsg_dialog;
+void EGong_if_gtk_newmsg_send_callback(GtkDialog *caller, guint button, gpointer data){
+ if(button==GTK_RESPONSE_OK){
+ char *message=(char *)gtk_entry_get_text((GtkEntry *)data);
+ if(message[0]!='\0'){
+ EGong_cnc_sendmessage(message,NULL);
+ }
+ }
+ EGong_if_gtk_newmsg_dialog=NULL;
+ gtk_widget_destroy(GTK_WIDGET(caller));
+}
+
+void EGong_if_gtk_newmsg_display_construct(unsigned short int single){
+ if(EGong_if_gtk_newmsg_dialog==NULL){
+ EGong_if_gtk_newmsg_dialog = gtk_dialog_new_with_buttons("Nachricht senden",
+ GTK_WINDOW(Egong_if_gtk_root),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+ GtkWidget *Message;
+ GtkWidget *content_area=gtk_dialog_get_content_area(GTK_DIALOG (EGong_if_gtk_newmsg_dialog));
+ Message=gtk_entry_new();
+ gtk_container_add (GTK_CONTAINER (content_area), Message);
+ if(single==1){
+ g_signal_connect(EGong_if_gtk_newmsg_dialog, "response", G_CALLBACK (gtk_main_quit), NULL);
+ }
+ g_signal_connect(EGong_if_gtk_newmsg_dialog, "response", G_CALLBACK (EGong_if_gtk_newmsg_send_callback), (gpointer)Message);
+
+ }
+ gtk_widget_show_all(EGong_if_gtk_newmsg_dialog);
+
+}
+void EGong_if_gtk_newmsg_display_single(void){
+ EGong_if_gtk_newmsg_display_construct(1);
+}
+void EGong_if_gtk_newmsg_display(void){
+ EGong_if_gtk_newmsg_display_construct(0);
+}
+
diff --git a/src/Interfaces/GTK/TrayIcon.c b/src/Interfaces/GTK/TrayIcon.c
@@ -0,0 +1,51 @@
+#include <gtk/gtk.h>
+#include <EGong/Interfaces/GTK/TrayIcon.h>
+#include <EGong/Interfaces/GTK/NewMessage.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Misc.h>
+#include <EGong/CNC.h>
+
+GtkStatusIcon *EGong_if_gtk_tray_root;
+GtkWidget *EGong_if_gtk_tray_menu;
+
+struct EGong_if_gtk_tray_menu_call EGong_if_gtk_tray_menu_calls[]={
+ {.name="Essen", .tooltip="Zum Essen rufen", .message="Essen!"},
+};
+
+void EGong_if_gtk_tray_popup(GtkStatusIcon *icon, guint button, guint activation_time, gpointer data){
+ gtk_menu_popup(GTK_MENU(EGong_if_gtk_tray_menu),NULL,NULL,gtk_status_icon_position_menu, icon, button, activation_time);
+}
+void EGong_if_gtk_tray_predef_call(GtkMenuItem *icon, const char *message){
+ EGong_cnc_sendmessage_broad(message);
+}
+int EGong_if_gtk_tray_setup(){
+ EGong_if_gtk_tray_root=gtk_status_icon_new_from_stock(GTK_STOCK_NETWORK);
+ g_signal_connect(GTK_STATUS_ICON(EGong_if_gtk_tray_root), "activate", G_CALLBACK(EGong_if_gtk_newmsg_display), NULL);
+ g_signal_connect(GTK_STATUS_ICON(EGong_if_gtk_tray_root), "popup-menu", G_CALLBACK(EGong_if_gtk_tray_popup), NULL);
+
+ EGong_if_gtk_tray_menu=gtk_menu_new();
+
+ GtkWidget *Exit=gtk_image_menu_item_new_with_label("Exit");
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(Exit),gtk_image_new_from_icon_name(GTK_STOCK_QUIT,GTK_ICON_SIZE_MENU));
+ g_signal_connect(G_OBJECT(Exit), "activate", G_CALLBACK(gtk_main_quit), NULL);
+ gtk_menu_shell_append(GTK_MENU_SHELL(EGong_if_gtk_tray_menu), Exit);
+
+ GtkWidget *predef=gtk_menu_item_new_with_label("Rufen");
+ GtkWidget *predefM=gtk_menu_new();
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(predef), predefM);
+ gtk_menu_shell_prepend(GTK_MENU_SHELL(EGong_if_gtk_tray_menu), predef);
+ int i;
+ GtkWidget *callitem;
+ struct EGong_if_gtk_tray_menu_call *call;
+ for(i=0; i<CSIZEOF(EGong_if_gtk_tray_menu_calls); i++){
+ call=&EGong_if_gtk_tray_menu_calls[i];
+ callitem=gtk_menu_item_new_with_label(call->name);
+ gtk_widget_set_tooltip_text(callitem,call->tooltip);
+ g_signal_connect(G_OBJECT(callitem), "activate", G_CALLBACK(EGong_if_gtk_tray_predef_call), call->message);
+ gtk_menu_shell_prepend(GTK_MENU_SHELL(predefM), callitem);
+ }
+
+ gtk_widget_show_all(EGong_if_gtk_tray_menu);
+ do_log("Tray initialized", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ return 0;
+}
diff --git a/src/Interfaces/STDIO.c b/src/Interfaces/STDIO.c
@@ -0,0 +1,76 @@
+#include <EGong/Interfaces.h>
+#include <EGong/Interfaces/CMD.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Waiter.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#ifdef _WIN32
+ #include <stdio.h>
+#else
+ #include <fcntl.h>
+#endif
+
+int EGong_if_stdio_setup(struct EGong_interface *interface){
+ #ifdef _WIN32
+ #else
+ int flags;
+ flags = fcntl(STDIN_FILENO, F_GETFL);
+ flags = fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
+ #endif
+ if(EGong_waiter_add(STDIN_FILENO, EGONG_WAITER_FD)<0){
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+ return EGONG_INTERFACE_RETURN_OK;
+}
+
+int EGong_if_stdio_cmd(char *msg){
+ const char *data[5];
+ unsigned int i=0,arg=0;
+ while(msg[i]!='\0'){
+ if(msg[i]==' '){
+ msg[i]='\0';
+ data[arg]=&msg[i+1];
+ arg++;
+ }
+ i++;
+ }
+ struct EGong_command_if_cmd *cmd=EGong_if_cmd_get_from_char(msg);
+ if(cmd==NULL){
+ write(STDOUT_FILENO, "Command unknown\n", sizeof("Command unknown\n"));
+ }
+ else{
+ EGong_command_exec((struct EGong_command *) cmd, (void **)data);
+ }
+ return EGONG_INTERFACE_RETURN_OK;
+}
+
+int EGong_if_stdio_cycle(struct EGong_interface *interface, char **msg, char **dest){
+ char buffer[50];
+ int ret=read(STDIN_FILENO, buffer, 50);
+ #ifdef _WIN32
+ if(ret<0&&errno!=EAGAIN){
+ #else
+ if(ret<0&&errno!=EAGAIN&&errno!=EWOULDBLOCK){
+ #endif
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+ else if(ret>0){
+ buffer[ret-1]='\0';
+ if(buffer[0]=='/'){
+ EGong_if_stdio_cmd(&buffer[1]);
+ }
+ else{
+ buffer[ret]='\0';
+ *msg=malloc(ret);
+ strncpy(*msg,buffer, ret);
+ }
+ }
+ return EGONG_INTERFACE_RETURN_OK;
+}
+int EGong_if_stdio_display(struct EGong_interface *interface, const char *msg){
+ write(STDOUT_FILENO,msg,strlen(msg));
+ write(STDOUT_FILENO, "\n", sizeof("\n"));
+ return EGONG_INTERFACE_RETURN_OK;
+}
diff --git a/src/Interfaces/Windows.c b/src/Interfaces/Windows.c
@@ -0,0 +1,91 @@
+#include <EGong/Interfaces.h>
+#include <EGong/Interfaces/Windows.h>
+#include <EGong/CNC.h>
+#include <EGong/Util/Log.h>
+#define UNICODE
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+WNDCLASSW EGong_if_win_getmsg = {0};
+HWND EGong_if_win_getmsg_editfield;
+LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
+ HWND hwndButton;
+ (void) hwndButton;
+ switch(msg){
+ case WM_CREATE:
+
+ EGong_if_win_getmsg_editfield = CreateWindowW(L"Edit", NULL,
+ WS_CHILD | WS_VISIBLE | WS_BORDER,
+ 50, 50, 150, 20, hwnd, (HMENU) 0,
+ NULL, NULL);
+
+ hwndButton = CreateWindowW(L"button", L"Senden",
+ WS_VISIBLE | WS_CHILD, 50, 100, 80, 25,
+ hwnd, (HMENU) 1, NULL, NULL);
+
+ break;
+
+ case WM_COMMAND:
+
+ if (HIWORD(wParam) == BN_CLICKED) {
+ int len = GetWindowTextLengthW(EGong_if_win_getmsg_editfield) + 1;
+ char text[len];
+ char msg[len];
+
+ GetWindowTextW(EGong_if_win_getmsg_editfield, text, 5+len);
+ wcstombs(msg,text, len);
+
+ msg[len]='\0';
+ EGong_cnc_sendmessage_broad(msg);
+ PostQuitMessage(0);
+ }
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ }
+ return DefWindowProcW(hwnd, msg, wParam, lParam);
+}
+int EGong_if_win_getmsgdialog(){
+ HINSTANCE hInstance = (HINSTANCE)GetWindowLong( GetForegroundWindow(), GWL_HINSTANCE );
+ MSG msg;
+ EGong_if_win_getmsg.lpszClassName = L"EGong Message";
+ EGong_if_win_getmsg.hInstance = hInstance;
+ EGong_if_win_getmsg.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
+ EGong_if_win_getmsg.lpfnWndProc = WndProc;
+ EGong_if_win_getmsg.hCursor = LoadCursor(0,IDC_ARROW);
+ RegisterClassW(&EGong_if_win_getmsg);
+
+ CreateWindowW(EGong_if_win_getmsg.lpszClassName, L"EGong Message",
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 220, 220, 280, 200, 0, 0, hInstance, 0);
+ while(GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ return 0;
+}
+
+void EGong_if_win_react(){
+ do_log("Windowsinterface is a stub", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+}
+int EGong_if_win_setup(struct EGong_interface *interface){
+ EGong_if_win_react();
+ return EGONG_INTERFACE_RETURN_ERROR;
+}
+
+int EGong_if_win_cmd(char *msg){
+ EGong_if_win_react();
+ return EGONG_INTERFACE_RETURN_ERROR;
+}
+
+int EGong_if_win_cycle(struct EGong_interface *interface, char **msg, char **dest){
+ EGong_if_win_react();
+ return EGONG_INTERFACE_RETURN_ERROR;
+}
+
+int EGong_if_win_display(struct EGong_interface *interface, const char *msg){
+ EGong_if_win_react();
+ return EGONG_INTERFACE_RETURN_ERROR;
+}
diff --git a/src/Packet.c b/src/Packet.c
@@ -0,0 +1,160 @@
+#include <openssl/sha.h>
+#include <EGong/Packet.h>
+#include <EGong/Util/Socket.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Misc.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <string.h>
+#include <stddef.h>
+#ifdef _WIN32
+ #include <winsock2.h>
+#else
+ #include <arpa/inet.h>
+#endif
+
+unsigned char EGong_packet_last_hash[EGONG_PACKET_HASH_LENGTH];
+int EGong_calculate_package_hash(struct EGong_packet *packet, unsigned char *dest, char *cookie){
+ if(cookie==NULL)
+ cookie=EGong_global_configuration.packet.cookie;
+ SHA256_CTX sha256;
+ SHA256_Init(&sha256);
+
+ SHA256_Update(&sha256, packet->message.data, packet->message.length);
+ SHA256_Update(&sha256, packet->rand, EGONG_PACKET_RAND_LENGTH);
+ SHA256_Update(&sha256, cookie, strlen(cookie));
+
+ SHA256_Final(dest, &sha256);
+ return 0;
+}
+
+int EGong_generate_packet(struct EGong_packet *packet, const char *msg, unsigned int msg_length){
+ EGong_misc_get_rand(packet->rand,EGONG_PACKET_RAND_LENGTH);
+
+ packet->message.length=msg_length;
+ packet->message.data=(char *)msg;
+
+ EGong_calculate_package_hash(packet,packet->hash, NULL);
+
+ return 0;
+}
+void EGong_packetbuffer_advance(char **buf, const char *src, size_t length){
+ memcpy(*buf, src, length);
+ *buf+=length;
+}
+int EGong_send_packet(struct EGong_packet *packet, const char *dest){
+ if(packet->message.length==0){
+ do_log("Packetsize 0, not sending...", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ return -1;
+ }
+ SOCKET sock;
+ if(EGong_socket_open(&sock)<0){
+ do_log("Couldn't open socket",LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ #ifdef _WIN32
+ char
+ #else
+ int
+ #endif
+ broadcastEnable=1;
+ if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable))<0){
+ do_log("Couldn't set socket broadcasting",LOG_TYPE_SOCKET, LOG_LEVEL_WARNING);
+ }
+
+ size_t bufsize=EGONG_PACKET_MSGLEN(packet->message.length);
+ char *buf=malloc(bufsize);
+ char *bufptr=buf;
+ if(buf==NULL){
+ do_log("Couldn't allocate buffer",LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ return -2;
+ }
+ memset(bufptr, 0, bufsize);
+ memcpy(EGong_packet_last_hash, packet->hash, EGONG_PACKET_HASH_LENGTH);
+
+ EGong_packetbuffer_advance(&bufptr, (const char *)packet->rand, EGONG_PACKET_RAND_LENGTH);
+ EGong_packetbuffer_advance(&bufptr, (const char *)packet->hash, EGONG_PACKET_HASH_LENGTH);
+ *(uint16_t *) bufptr=htons(packet->message.length);
+ bufptr+=EGONG_PACKET_LENGTH_LENGTH;
+ EGong_packetbuffer_advance(&bufptr, packet->message.data, packet->message.length);
+
+ if(EGong_sendto(&sock, dest, buf, bufsize, NULL)<0){
+ do_log("Couldn't send packet body", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -3;
+ }
+ free(buf);
+ EGong_socket_close(&sock);
+ return 0;
+}
+
+void EGong_packet_free(struct EGong_packet *packet){
+ free(packet->message.data-(EGONG_PACKET_MSGHEADLEN));
+}
+int EGong_packetbuf_alloc(size_t size, char **dest, unsigned int additional){
+ if(size==0){
+ do_log("Tried to allocate message of size 0", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ return -1;
+ }
+ if(size>EGong_global_configuration.packet.packet_maxlen){
+ do_log("Messagesize larger than allowed!", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ return -2;
+ }
+ *dest=malloc(EGONG_PACKET_MSGLEN(size)+additional);
+ if(*dest==NULL){
+ do_log("Couldn't allocate packet!", LOG_TYPE_SIGNAL, LOG_LEVEL_WARNING);
+ return -3;
+ }
+ return 0;
+}
+
+int EGong_packet_verify(struct EGong_packet *packet, char *cookie){
+ unsigned char hash[EGONG_PACKET_HASH_LENGTH];
+ EGong_calculate_package_hash(packet, hash, cookie);
+ return memcmp(packet->hash,hash,EGONG_PACKET_HASH_LENGTH)==0;
+}
+void EGong_packetbuffer_to_packet(const char *buf, struct EGong_packet *packet){
+ memcpy(packet->rand, buf, EGONG_PACKET_RAND_LENGTH);
+ buf+=EGONG_PACKET_RAND_LENGTH;
+ memcpy(packet->hash, buf, EGONG_PACKET_HASH_LENGTH);
+ buf+=EGONG_PACKET_HASH_LENGTH;
+ packet->message.length=ntohs(*(uint16_t *)buf);
+ buf+=EGONG_PACKET_LENGTH_LENGTH;
+ packet->message.data=(char *)buf;
+}
+void EGong_drop_packet(SOCKET *sock){
+ do_log("Dropping packet.", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ EGong_listener_get(sock,NULL,0, NULL, 0);
+}
+int EGong_get_packet(SOCKET *sock, struct EGong_packet *packet){
+ if(sock==NULL){
+ sock=&EGong_listen_sock;
+ } struct sockaddr source;
+ char packetbuf[EGONG_PACKET_MSGHEADLEN];
+ int ret=EGong_listener_get(sock,(char *)packetbuf,EGONG_PACKET_MSGHEADLEN, &source, MSG_PEEK|MSG_DONTWAIT);
+ if(ret<0){
+ do_log("Couldn't receive packet!", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ else if(ret==0){
+ do_log("No packet available", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ return 1;
+ }
+ else if(0&&memcmp(EGong_packet_last_hash, packetbuf+EGONG_PACKET_RAND_LENGTH, EGONG_PACKET_HASH_LENGTH)==0){
+ do_log("Is own packet, dropping", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ EGong_drop_packet(sock);
+ return 2;
+ }
+ uint16_t rawsize=*(uint16_t*)(packetbuf+EGONG_PACKET_RAND_LENGTH+EGONG_PACKET_HASH_LENGTH);
+ size_t size=ntohs(rawsize);
+ char *dest;
+ if(EGong_packetbuf_alloc(size+EGONG_PACKET_MSGHEADLEN,&dest, 1)<0){
+ do_log("Couldn't allocate packetbuffer",LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ EGong_drop_packet(sock);
+ return -2;
+ }
+ ret=EGong_listener_get(sock, dest, EGONG_PACKET_MSGLEN(size), NULL, 0);
+ EGong_packetbuffer_to_packet(dest,packet);
+ return 0;
+}
diff --git a/src/Util/Command.c b/src/Util/Command.c
@@ -0,0 +1,72 @@
+#include <EGong/Util/Command.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Misc.h>
+#include <EGong/Interfaces/CMD.h>
+#include <stdint.h>
+#include <stdio.h>
+
+struct EGong_command *EGong_command_match(struct EGong_command_array *commands, const char *data, unsigned int match_type){
+ unsigned int i;
+ struct EGong_command *command=NULL;
+ for(i=0; i<commands->array.element_count; i++){
+ command=(commands->array.elements+(uintptr_t)(commands->array.element_size*i));
+ if((match_type&EGONG_COMMAND_MATCH_SHORT) && strcmp(command->shortname, data)==0){
+ break;
+ }
+ if((match_type&EGONG_COMMAND_MATCH_LONG) && strcmp(command->longname, data)==0){
+ break;
+ }
+ command=NULL;
+ }
+ return command;
+}
+void EGong_command_print_help(struct EGong_command_array *commands, int destination, char *appendix){
+ unsigned int i;
+ size_t appendixlength=strlen(appendix);
+ struct EGong_command *cmd;
+ for(i=0; i<commands->array.element_count; i++){
+ cmd=(struct EGong_command *)((intptr_t)commands->array.elements+(intptr_t)(commands->array.element_size*i));
+ write(destination, appendix, appendixlength);
+ write(destination, "-", sizeof("-"));
+ write(destination, cmd->shortname, strlen(cmd->shortname));
+ write(destination, "/--", sizeof("/--"));
+ write(destination, cmd->longname, strlen(cmd->longname));
+ write(destination, ": ", sizeof(": "));
+ write(destination, cmd->description, strlen(cmd->description));
+ write(destination,"\n", sizeof("\n"));
+ }
+}
+int EGong_command_exec(struct EGong_command *command, void **data){
+ switch(command->type.type){
+ case EGONG_COMMAND_BOOL_FALSE:
+ *(unsigned int *)command->pointer=0;
+ break;
+ case EGONG_COMMAND_BOOL_TRUE:
+ *(unsigned int *)command->pointer=1;
+ break;
+ case EGONG_COMMAND_BOOL_SET:
+ *(unsigned int *)command->pointer=(**(char **)data=='1') ? 1 : 0;
+ break;
+ case EGONG_COMMAND_UINT_INC:
+ if(*(unsigned int *)command->pointer<=(unsigned int)-1)
+ (*(unsigned int *)command->pointer)++;
+ break;
+ case EGONG_COMMAND_UINT_DEC:
+ if(*(unsigned int *)command->pointer>(unsigned int)0)
+ (*(unsigned int *)command->pointer)--;
+ break;
+ case EGONG_COMMAND_FUNC_VOID:
+ ((int(*)(void))command->pointer)();
+ break;
+ case EGONG_COMMAND_FUNC_CHAR:
+ ((int(*)(char *))command->pointer)(*(char **)data);
+ break;
+ case EGONG_COMMAND_FUNC_2CHAR:
+ ((int(*)(char *, char *))command->pointer)(((char **)data)[0],((char **)data)[1]);
+ break;
+ default:
+ do_log("Unknown command type", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/Util/Config.c b/src/Util/Config.c
@@ -0,0 +1,68 @@
+#include <EGong/Util/Config.h>
+#include <EGong/Util/Log.h>
+#include <stdlib.h>
+
+struct EGong_config EGong_global_configuration;
+
+struct EGong_config_file_entry EGong_configuration_file_interface[EGONG_CONFIG_FILE_ENTRYCOUNT]={
+ [EGONG_CONFIG_FILE_LOG_COLOR]={
+ .type=EGONG_CONFIG_TYPE_BOOL,
+ .name="STDIO-Farben",
+ .data_offset=offsetof(struct EGong_config,log.color)
+ },
+ [EGONG_CONFIG_FILE_LOG_LEVEL]={
+ .type=EGONG_CONFIG_TYPE_UINT,
+ .name="Log-Level",
+ .data_offset=offsetof(struct EGong_config,log.level)
+ },
+ [EGONG_CONFIG_FILE_LOG_DEST]={
+ .type=EGONG_CONFIG_TYPE_BITMASK,
+ .name="Logdestinationsbitmaske",
+ .data_offset=offsetof(struct EGong_config,log.level)
+ },
+ [EGONG_CONFIG_FILE_PACKET_COOKIE]={
+ .type=EGONG_CONFIG_TYPE_STRING,
+ .name="Cookie",
+ .data_offset=offsetof(struct EGong_config,packet.cookie)
+ },
+ [EGONG_CONFIG_FILE_PACKET_LEN]={
+ .type=EGONG_CONFIG_TYPE_STRING,
+ .name="Packet-Maximallänge",
+ .data_offset=offsetof(struct EGong_config,log.level)
+ },
+ [EGONG_CONFIG_FILE_SERVER_BINDIP]={
+ .type=EGONG_CONFIG_TYPE_STRING,
+ .name="Bind-IP",
+ .data_offset=offsetof(struct EGong_config,server.bind_ip)
+ },
+ [EGONG_CONFIG_FILE_SERVER_PORT]={
+ .type=EGONG_CONFIG_TYPE_STRING,
+ .name="Port",
+ .data_offset=offsetof(struct EGong_config,server.port)
+ }
+};
+void EGong_config_set_defaults(struct EGong_config *conf){
+ conf->log.color=0;
+ conf->log.level=LOG_LEVEL_DEBUG;
+ conf->log.destinations=LOG_DEST_STDIO;
+
+ conf->server.port=4242;
+ conf->server.bind_ip="0.0.0.0";
+
+ conf->packet.packet_maxlen=1000;
+ conf->packet.cookie="Derpaherp";
+}
+
+int EGong_config_write(struct EGong_config *conf, int file){
+ unsigned int i;
+ for(i=0;i<EGONG_CONFIG_FILE_ENTRYCOUNT; i++){
+
+ }
+ return 0;
+}
+
+void EGong_config_init(struct EGong_config *conf){
+ if(conf==NULL)
+ conf=&EGong_global_configuration;
+ EGong_config_set_defaults(conf);
+}
diff --git a/src/Util/File.c b/src/Util/File.c
@@ -0,0 +1,25 @@
+
+int EGong_file_open(char *path, ...vargs){
+ int sock=open(path,vargs);
+ if(sock<0){
+ do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR, "Couldn't open file \"", path, "\"", NULL);
+ }
+ return sock;
+}
+
+int FileExists(const TCHAR *fileName){
+ #ifdef _WIN32
+ DWORD fileAttr;
+ fileAttr = GetFileAttributes(fileName);
+ if(fileAttr==0xFFFFFFFF)
+ return 0;
+ #else
+ if(access("file", F_OK)!=0)
+ return 0;
+ #endif
+ return 1;
+}
+
+void EGong_file_close(int file){
+ close(file);
+}
diff --git a/src/Util/Log.c b/src/Util/Log.c
@@ -0,0 +1,128 @@
+/*
+ * SIGI - Swisscom Internet GTK Interface
+ *
+ * @author: Dominik Schmidt <domischmidt@swissonline.ch>
+ * @license: CC-BY-SA-3.0
+ * @version: 2.0.0
+*/
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Misc.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#ifdef _WIN32
+ #include <stdio.h>
+ #include <windows.h>
+ #include <winnt.h>
+#endif
+
+struct log_level log_levels[LOG_LEVEL_COUNT]={
+ [LOG_LEVEL_DEBUG]={.name="DEBUG", .color="\e[2;37;40m"},
+ [LOG_LEVEL_INFO]={.name="INFO", .color="\e[0;37;40m"},
+ [LOG_LEVEL_WARNING]={.name="WARNING", .color="\e[1;33;40m"},
+ [LOG_LEVEL_ERROR]={.name="ERROR", .color="\e[1;31;40m"},
+ [LOG_LEVEL_FATAL]={.name="FATAL", .color="\e[1;33;41m"}
+};
+
+void log_write_stdio(const char *msg, unsigned int length, unsigned int type, unsigned int level){
+ int fd=STDOUT_FILENO;
+ if(level>=LOG_LEVEL_WARNING){
+ fd=STDERR_FILENO;
+ }
+ if(EGong_global_configuration.log.color){
+ STDNWRITE(log_levels[level].color,sizeof(((struct log_level *)NULL)->color));
+ }
+ write(fd,msg,length);
+ if(EGong_global_configuration.log.color){
+ STDWRITE("\e[0m");
+ }
+}
+void do_log_call_composite(const struct log_source src, unsigned int type, unsigned int level, unsigned int destmask, ...){
+ va_list ap;
+ va_start(ap, destmask);
+ char *arg=NULL;
+ char *buf=NULL;
+ char *bufptr=buf;
+ unsigned int length=0, totallength=0, alloc=0;
+ while(1){
+ arg=va_arg(ap, char *);
+ if(arg==NULL){
+ break;
+ }
+ length=strlen(arg);
+ if(length+totallength>100*alloc){
+ buf=realloc(buf,((unsigned int)((length+totallength)/100)+1)*100);
+ bufptr=buf+totallength;
+ }
+ STRNCAT(bufptr,arg,length);
+ totallength+=length;
+ }
+ va_end (ap);
+ do_log_call(src, buf, totallength, type, level, destmask);
+}
+void do_log_call(const struct log_source src, const char *msg, unsigned int msglength, unsigned int type, unsigned int level, unsigned int destmask){
+ if(EGong_global_configuration.log.level>level){
+ return;
+ }
+ int error=errno;
+ char msgdest[msglength+src.file.l+src.line.l+src.func.l+50];
+ const char *msgptr=msgdest;
+ char *msgbuf=msgdest;
+ unsigned int length=0;
+ if(type!=LOG_TYPE_RAW){
+ STRCAT(msgbuf,"[")
+ STRNCAT(msgbuf, log_levels[level].name, strlen(log_levels[level].name));
+ STRCAT(msgbuf,"] ");
+
+ STRNCAT(msgbuf,src.file.v, src.file.l-1);
+ STRCAT(msgbuf,":");
+ STRNCAT(msgbuf, src.line.v, src.line.l-1);
+ STRCAT(msgbuf,", ");
+ STRNCAT(msgbuf, src.func.v, src.func.l-1);
+ STRCAT(msgbuf,": ");
+
+ STRNCAT(msgbuf, msg, msglength);
+ if(type==LOG_TYPE_SIGNAL){
+ char *err=strerror(error);
+ STRCAT(msgbuf,"(");
+ STRNCAT(msgbuf, err,strlen(err));
+ STRCAT(msgbuf,")");
+ }
+ #ifdef _WIN32
+ else if(type==LOG_TYPE_SOCKET){
+ STRCAT(msgbuf,"(");
+ LPVOID lpMsgBuf;
+ int e;
+
+ lpMsgBuf = (LPVOID)"Unknown error";
+ e = WSAGetLastError();
+ if (FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, e,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf, 0, NULL)) {
+ STRNCAT(msgbuf, lpMsgBuf,strlen(lpMsgBuf));
+ LocalFree(lpMsgBuf);
+ }
+ else{
+ STRCAT(msgbuf,"Unknown");
+ }
+ STRCAT(msgbuf,")");
+ }
+ #endif
+ STRCAT(msgbuf,"\n\0");
+ length=(unsigned int)(msgbuf-msgptr);
+ }
+ else{
+ msgptr=msg;
+ length=msglength;
+ }
+ if((destmask&LOG_DEST_STDIO)>0){
+ log_write_stdio(msgptr,length, type, level);
+ }
+}
diff --git a/src/Util/Misc.c b/src/Util/Misc.c
@@ -0,0 +1,12 @@
+#include <EGong/Util/Misc.h>
+#include <EGong/Util/Log.h>
+#include <openssl/rand.h>
+
+int EGong_misc_get_rand(char *dest, size_t length){
+ RAND_pseudo_bytes((unsigned char *)dest, length);
+ return 0;
+}
+
+int EGong_array_init(){
+ return 0;
+}
diff --git a/src/Util/Socket.c b/src/Util/Socket.c
@@ -0,0 +1,156 @@
+#include <EGong/Util/Socket.h>
+#include <EGong/Util/Config.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Packet.h>
+
+#ifdef _WIN32
+ #include <windows.h>
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+ #include <iphlpapi.h>
+#else
+ #include <sys/socket.h>
+ #include <sys/types.h>
+ #include <arpa/inet.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <netinet/in.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+
+SOCKET EGong_listen_sock;
+
+#ifdef _WIN32
+WSADATA wsaData;
+int inet_aton(const char *cp, struct in_addr *inp){
+ inp->s_addr=inet_addr(cp);
+ if(inp->s_addr==-1){
+ return 0;
+ }
+ else{
+ return 1;
+ }
+}
+#endif
+
+int EGong_sockets_setup(void){
+ #ifdef _WIN32
+ int res=WSAStartup(MAKEWORD(2,2), &wsaData);
+ if(res!=0) {
+ do_log("WSAStartup failed", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
+ return -1;
+ }
+ #endif
+ return 0;
+}
+int EGong_sockets_shutdown(void){
+ #ifdef _WIN32
+ WSACleanup();
+ #endif
+ return 0;
+}
+
+void EGong_socket_close(SOCKET *sock){
+ #ifdef _WIN32
+ closesocket(*sock);
+ #else
+ close(*sock);
+ #endif
+}
+int EGong_socket_open(SOCKET *sock){
+ *sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if(*sock<0){
+ do_log("Couldn't initialize socket",LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ EGong_socket_close(sock);
+ return -1;
+ }
+ return 0;
+}
+int EGong_sockaddr_init(struct sockaddr_in *addr, const char *ip, unsigned int port, sa_family_t family){
+ memset(addr, 0, sizeof(*addr));
+ if(inet_aton((char *)ip,&addr->sin_addr)<0){
+ do_log("Couldn't convert bind address", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ addr->sin_family = family;
+ addr->sin_port = htons(port);
+ return 0;
+}
+int EGong_listener_init(SOCKET *sock, struct EGong_config_server *config){
+ struct sockaddr_in listen_server;
+
+ if(config==NULL)
+ config=&EGong_global_configuration.server;
+ if(sock==NULL)
+ sock=&EGong_listen_sock;
+
+ if(EGong_socket_open(sock)<0){
+ do_log("Couldn't open socket",LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ #ifdef _WIN32
+ unsigned long nonblocking_long=1;
+ if (ioctlsocket(*sock, FIONBIO, &nonblocking_long)==SOCKET_ERROR){
+ do_log("Couldn't set listensocket nonblocking",LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ }
+ #endif
+ if(EGong_sockaddr_init(&listen_server, config->bind_ip, config->port, AF_INET)<0){
+ do_log("Couldn't initialize address",LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ EGong_socket_close(sock);
+ return -2;
+ }
+
+ if(bind(*sock, (struct sockaddr *) &listen_server, sizeof(listen_server))<0){
+ do_log("Couldn't bind to sock", LOG_TYPE_SOCKET, LOG_LEVEL_ERROR);
+ EGong_socket_close(sock);
+ return -3;
+ }
+ do_log("Listening on socket...",LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ return 0;
+}
+int EGong_listener_get(SOCKET *sock, char *dest, int length, struct sockaddr *source, int flags){
+ if(sock==NULL)
+ sock=&EGong_listen_sock;
+ int ret;
+ socklen_t size=sizeof(*source);
+ if(source==NULL){
+ struct sockaddr test;
+ source=&test;
+ }
+ do_log("Receiving on socket...",LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ ret=recvfrom(*sock,dest,length, flags, source, &size);
+ #ifdef _WIN32
+ if((flags&MSG_PEEK)>0&&ret==-1&&WSAGetLastError()==WSAEMSGSIZE){
+ return length;
+ }
+ else if((flags&MSG_DONTWAIT)>0&&ret==-1&&(WSAGetLastError()==WSAEWOULDBLOCK)) {
+ #else
+ if((flags&MSG_DONTWAIT)>0&&ret==-1&&(errno==EAGAIN||errno==EWOULDBLOCK)) {
+ #endif
+ return 0;
+ }
+ else if(ret<0){
+ do_log("Couldn't receive from socket", LOG_TYPE_SOCKET, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ return ret;
+}
+void EGong_listener_close(SOCKET *sock){
+ if(sock==NULL){
+ sock=&EGong_listen_sock;
+ }
+ EGong_socket_close(sock);
+}
+int EGong_sendto(SOCKET *sock, const char *dest, const char *msg, size_t msg_len, struct EGong_config_server *config){
+ struct sockaddr_in server;
+ if(config==NULL)
+ config=&EGong_global_configuration.server;
+ EGong_sockaddr_init(&server, dest, config->port, AF_INET);
+ int ret=sendto(*sock, msg, msg_len, 0, (struct sockaddr *)&server, sizeof(server));
+ if(ret!=msg_len){
+ do_log("Error while sending message", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ }
+ return ret;
+}
diff --git a/src/Util/Waiter.c b/src/Util/Waiter.c
@@ -0,0 +1,70 @@
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <EGong/Util/Waiter.h>
+#include <EGong/Interfaces.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Config.h>
+#ifdef _WIN32
+ #include <winsock2.h>
+#endif
+#ifdef USE_GTK
+ #include <gtk/gtk.h>
+
+ gboolean Egong_waiter_gtk_callback(GIOChannel *source, GIOCondition condition, gpointer data){
+ EGong_interface_cycle();
+ return G_SOURCE_CONTINUE;
+ }
+#endif
+
+
+fd_set EGong_waiter_fds;
+unsigned int EGong_waiter_highest_fd;
+unsigned int EGong_waiter_cnt=0;
+int EGong_waiter_init(void){
+ FD_ZERO(&EGong_waiter_fds);
+ return 0;
+}
+int EGong_waiter_add(int sock, unsigned short int type){
+ EGong_waiter_cnt++;
+ #ifdef _WIN32
+ if(type==EGONG_WAITER_FD){
+ do_log("Adding filedescriptors not supported, sorry", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ return 1;
+ }
+ #endif
+ do_log("Adding to waiter...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ FD_SET(sock, &EGong_waiter_fds);
+ if(EGong_waiter_highest_fd<sock){
+ EGong_waiter_highest_fd=sock;
+ }
+ #ifdef USE_GTK
+ GIOChannel *new=g_io_channel_unix_new(sock);
+ g_io_add_watch(new,G_IO_IN|G_IO_ERR|G_IO_HUP, Egong_waiter_gtk_callback, NULL);
+ #endif
+ return 0;
+}
+int EGong_waiter_del(int sock){
+ FD_SET(sock, &EGong_waiter_fds);
+ EGong_waiter_cnt--;
+ return 0;
+}
+int EGong_waiter_wait(void){
+ if(EGong_waiter_cnt==0){
+ do_log("Nothing to wait for...", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);
+ return 1;
+ }
+ do_log("Waiting...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ struct timeval *tv=NULL;
+ #ifdef _WIN32
+ struct timeval tv2;
+ tv2.tv_sec=2;
+ tv2.tv_usec=0;
+ tv=&tv2;
+ #endif
+ if(select(EGong_waiter_highest_fd+1, &EGong_waiter_fds, NULL, NULL, tv)<0){
+ do_log("Couldnt select", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ return 0;
+}