added config parser & incoming connection handler
authorpk910 <philipp@zoelle1.de>
Tue, 15 Jul 2014 21:58:05 +0000 (23:58 +0200)
committerpk910 <philipp@zoelle1.de>
Tue, 15 Jul 2014 21:58:05 +0000 (23:58 +0200)
15 files changed:
configure.ac
src/.gitignore
src/Makefile.am
src/config.c [new file with mode: 0644]
src/ircd_client.c [new file with mode: 0644]
src/ircd_client.h [new file with mode: 0644]
src/ircd_sock.c [new file with mode: 0644]
src/ircd_sock.h [new file with mode: 0644]
src/main.c [new file with mode: 0644]
src/struct_auth.h [new file with mode: 0644]
src/struct_connection.h [new file with mode: 0644]
src/tools.c [new file with mode: 0644]
src/tools.h [new file with mode: 0644]
src/version.h [new file with mode: 0644]
src/version.sh [new file with mode: 0644]

index 4275959d2caf16b73054236bb343d5bfcd31e588..44f4e88c1f7f52e9981d1bd612deda67d5edb5e7 100644 (file)
@@ -5,7 +5,7 @@ AC_INIT([IOMultiplexer], [2.0], [iohandler@pk910.de], [pk910], [http://pk910.de]
 AC_PREFIX_DEFAULT([~/iotest])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign])
-AM_SILENT_RULES([yes])
+AM_SILENT_RULES([no])
 AC_CONFIG_HEADERS([config.h])
 
 LT_INIT([disable-static])
index 3dda72986fc5af262451a760393b3a7065938c80..7b61ddf2ec8eaccd514816e26996c3de52ebcda0 100644 (file)
@@ -1,2 +1,9 @@
+.deps
+.libs
 Makefile.in
 Makefile
+*.o
+version.c
+ircd.conf
+nextircd
+nextircd.exe
\ No newline at end of file
index 2f259ff6d4fa258773404b38f6c001fcb5733c40..976d0393e41984e89a6de33d697fe05687c67ff8 100644 (file)
@@ -1,3 +1,20 @@
 ##Process this file with automake to create Makefile.in
 ACLOCAL_AMFLAGS = -I m4
 SUBDIRS = IOHandler IOHandler++ IOHandler_test
+
+noinst_PROGRAMS = nextircd
+nextircd_LDADD = IOHandler/libiohandler.la
+
+BUILT_SOURCES = version.c
+version.c: checkversion
+checkversion:
+       ./version.sh
+
+nextircd_SOURCES = \
+       version.c \
+       tools.c \
+       config.c \
+       ircd_sock.c \
+       ircd_client.c \
+       main.c
+
diff --git a/src/config.c b/src/config.c
new file mode 100644 (file)
index 0000000..f7a82af
--- /dev/null
@@ -0,0 +1,348 @@
+/* config.c - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "config.h"
+#include "tools.h"
+
+static char *config_file = "ircd.conf";
+
+struct GlobalConfig global_config;
+static struct ConfigReloadCallback *config_reload_callbacks = NULL;
+
+struct ConfigReloadCallback {
+       confreload_callback_t *callback;
+       struct ConfigReloadCallback *next;
+};
+
+#define CONFIG_READ_BUF 512
+
+struct ConfigFile {
+       FILE *file;
+       int pending_bytes;
+       char *content_buffer;
+       int return_value;
+};
+
+#define ENTRYTYPE_BLOCK   1
+#define ENTRYTYPE_STRING  2
+#define ENTRYTYPE_INTEGER 3
+
+struct ConfigEntry {
+       char *name;
+       int type;
+       union {
+               struct ConfigEntry *elements;
+               char *str_value;
+               int int_value;
+       } data;
+       struct ConfigEntry *next;
+};
+
+static char *parse_config_recursive(struct ConfigEntry *centry, char *buffer, struct ConfigFile *configfile);
+static void free_entry_rekursiv(struct ConfigEntry *centry);
+static int parse_config_block(struct ConfigEntry *centry);
+
+#define PARSER_FLAG_ESCAPED    0x01
+#define PARSER_FLAG_BLOCK      0x02
+#define PARSER_FLAG_STRING     0x04
+#define PARSER_FLAG_EXPECT_END 0x08
+#define PARSER_FLAG_NEXTCHAR   0x10
+#define PARSER_FLAG_INTEGER    0x20
+#define PARSER_FLAG_EOBN       0x40 /* End of Block name */
+#define PARSER_FLAG_COMMAND    0x80
+static char *parse_config_recursive(struct ConfigEntry *centry, char *buffer, struct ConfigFile *configfile) {
+       int flags = 0;
+       int type = (centry ? 0 : ENTRYTYPE_BLOCK);
+       char cbuf[1024];
+       int cbufpos = 0;
+       struct ConfigEntry *sub_entrys = NULL;
+       parse_config_recursive_process:
+       while(*buffer) {
+               if(flags & PARSER_FLAG_NEXTCHAR) {
+                       buffer++;
+                       if(*buffer == '\0')
+                               break;
+               }
+               flags |= PARSER_FLAG_NEXTCHAR;
+               if(flags & PARSER_FLAG_EOBN) {
+                       flags &= ~(PARSER_FLAG_EOBN | PARSER_FLAG_NEXTCHAR);
+                       struct ConfigEntry *new_entry = malloc(sizeof(*new_entry));
+                       if (!new_entry) return buffer;
+                       new_entry->name = strdup(cbuf);
+                       buffer = parse_config_recursive(new_entry, buffer, 0);
+                       if(centry) {
+                               if(sub_entrys)
+                                       new_entry->next = sub_entrys;
+                               else
+                                       new_entry->next = NULL;
+                               sub_entrys = new_entry;
+                               centry->data.elements = sub_entrys;
+                       } else {
+                               configfile->return_value |= parse_config_block(new_entry);
+                               free_entry_rekursiv(new_entry);
+                       }
+               }
+               if(flags & PARSER_FLAG_ESCAPED) {
+                       cbuf[cbufpos++] = *buffer;
+                       flags &= ~PARSER_FLAG_ESCAPED;
+                       continue;
+               }
+               if(flags & PARSER_FLAG_EXPECT_END) {
+                       if(*buffer == ';') {
+                               if(centry)
+                                       centry->type = type;
+                               return (buffer+1);
+                       }
+                       continue;
+               }
+               if(flags & PARSER_FLAG_STRING) {
+                       if(*buffer == '"') {
+                               cbuf[cbufpos] = '\0';
+                               flags &= ~PARSER_FLAG_STRING;
+                               if(type == ENTRYTYPE_STRING) {
+                                       flags |= PARSER_FLAG_EXPECT_END;
+                                       if(centry)
+                                               centry->data.str_value = strdup(cbuf);
+                               } else if(type == ENTRYTYPE_BLOCK) {
+                                       flags |= PARSER_FLAG_EOBN;
+                               }
+                       } else if(*buffer == '\\')
+                               flags |= PARSER_FLAG_ESCAPED;
+                       else
+                               cbuf[cbufpos++] = *buffer;
+                       continue;
+               }
+               if(flags & PARSER_FLAG_INTEGER) {
+                       if(!isdigit(*buffer)) {
+                               cbuf[cbufpos] = '\0';
+                               flags &= ~PARSER_FLAG_INTEGER;
+                               if(type == ENTRYTYPE_INTEGER) {
+                                       flags |= PARSER_FLAG_EXPECT_END;
+                                       /* a pointer should be big enough to store a int value in it ;) */
+                                       if(centry)
+                                               centry->data.int_value = atoi(cbuf);
+                               }
+                               if(*buffer == ';') {
+                                       if(centry)
+                                               centry->type = type;
+                                       return (buffer+1);
+                               }
+                       } else
+                               cbuf[cbufpos++] = *buffer;
+                       continue;
+               }
+               if(flags & PARSER_FLAG_COMMAND) {
+                       int found_command = 0;
+                       char *tmp_buffer;
+                       switch(*buffer) {
+                               case '/':
+                                       tmp_buffer = buffer;
+                                       buffer = strchr(buffer, '\r');
+                                       if(!buffer)
+                                               buffer = strchr(tmp_buffer, '\n');
+                                       if(!buffer)
+                                               buffer = tmp_buffer + strlen(tmp_buffer)-1;
+                                       found_command = 1;
+                                       break;
+                               case '*':
+                                       //simple search for the next */
+                                       buffer = strstr(buffer, "*/")+1;
+                                       found_command = 1;
+                       }
+                       flags &= ~PARSER_FLAG_COMMAND;
+                       if(found_command)
+                               continue;
+               }
+               switch(*buffer) {
+                       case '\\':
+                               flags |= PARSER_FLAG_ESCAPED;
+                               break;
+                       case '/':
+                               if(!(flags & PARSER_FLAG_STRING)) {
+                                       flags |= PARSER_FLAG_COMMAND;
+                               }
+                               break;
+                       case '{':
+                               flags |= PARSER_FLAG_BLOCK;
+                               type = ENTRYTYPE_BLOCK;
+                               break;
+                       case '}':
+                               if(flags & PARSER_FLAG_BLOCK)
+                                       flags &= ~PARSER_FLAG_BLOCK;
+                               flags |= PARSER_FLAG_EXPECT_END;
+                               break;
+                       case '"':
+                               flags |= PARSER_FLAG_STRING;
+                               if(!type)
+                                       type = ENTRYTYPE_STRING;
+                               cbufpos = 0;
+                               break;
+                       case ';':
+                               if(centry)
+                                       centry->type = type;
+                               return (buffer+1);
+                       case '0':
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
+                       case '8':
+                       case '9':
+                               if(!type)
+                                       type = ENTRYTYPE_INTEGER;
+                               flags |= PARSER_FLAG_INTEGER;
+                               cbufpos = 0;
+                               cbuf[cbufpos++] = *buffer;
+                               break;
+                       default:
+                               break;
+               }
+       }
+       /* try to get more data */
+       if(configfile->pending_bytes) {
+               int read_bytes = configfile->pending_bytes;
+               if(read_bytes > CONFIG_READ_BUF)
+                       read_bytes = CONFIG_READ_BUF;
+               read_bytes = fread(configfile->content_buffer, 1, read_bytes, configfile->file);
+               configfile->content_buffer[read_bytes] = '\0';
+               configfile->pending_bytes -= read_bytes;
+               buffer = configfile->content_buffer;
+               goto parse_config_recursive_process;
+       }
+       if(centry)
+               centry->type = type;
+       return buffer; //end of the buffer
+}
+
+static void free_entry_rekursiv(struct ConfigEntry *centry) {
+       if(centry->type == ENTRYTYPE_BLOCK) {
+               struct ConfigEntry *subentry, *nextentry;
+               for(subentry = centry->data.elements; subentry; subentry = nextentry) {
+                       nextentry = subentry->next;
+                       free_entry_rekursiv(subentry);
+               }
+       } else if(centry->type == ENTRYTYPE_STRING && centry->data.str_value) {
+               free(centry->data.str_value);
+       }
+       free(centry->name);
+       free(centry);
+}
+
+static int parse_config_port_block(struct ConfigEntry *centry);
+
+static int parse_config_block(struct ConfigEntry *centry) {
+       int ret = 0;
+       if(!stricmp(centry->name, "Port"))
+               ret |= parse_config_port_block(centry);
+       else {
+               // ERROR - unknown block name
+       }
+       return ret;
+}
+
+static int parse_config_port_block(struct ConfigEntry *centry) {
+       struct ConfigPortObject *port;
+       struct ConfigEntry *sentry;
+       int ret = 0;
+       if(centry->type != ENTRYTYPE_BLOCK)
+               return 1;
+       port = calloc(1, sizeof(*port));
+       for(sentry = centry->data.elements; sentry; sentry = sentry->next) {
+               if(!stricmp(sentry->name, "port") && sentry->type == ENTRYTYPE_INTEGER)
+                       port->port = sentry->data.int_value;
+               else if(!stricmp(sentry->name, "secure") && sentry->type == ENTRYTYPE_INTEGER)
+                       port->secure = (sentry->data.int_value != 0);
+               else if(!stricmp(sentry->name, "server") && sentry->type == ENTRYTYPE_INTEGER)
+                       port->server = (sentry->data.int_value != 0);
+               else if(!stricmp(sentry->name, "ip4only") && sentry->type == ENTRYTYPE_INTEGER)
+                       port->ip4only = (sentry->data.int_value != 0);
+               else if(!stricmp(sentry->name, "ip6only") && sentry->type == ENTRYTYPE_INTEGER)
+                       port->ip6only = (sentry->data.int_value != 0);
+               else if(!stricmp(sentry->name, "bind") && sentry->type == ENTRYTYPE_STRING) {
+                       port->bind_addr = sentry->data.str_value;
+                       sentry->data.str_value = NULL; //prevents freeing later
+               } else {
+                       // ERROR - unknown field in port block
+                       ret = 1;
+               }
+       }
+       if(port->port && !(port->ip4only && port->ip6only)) {
+               port->next = global_config.ports;
+               global_config.ports = port;
+       } else
+               ret = 1;
+       return ret;
+}
+
+
+
+
+void init_config(char *configfile) {
+       if(configfile)
+               config_file = configfile;
+       memset(&global_config, 0, sizeof(global_config));
+       reload_config();
+}
+
+void reload_config() {
+       struct ConfigFile config;
+       config.file = fopen(config_file, "rb");
+       if(!config.file) {
+               //ERROR
+        printf("Error loading config file.\n");
+               return;
+       }
+       fseek(config.file, 0, SEEK_END);
+       config.pending_bytes = ftell(config.file);
+       rewind(config.file);
+       
+       char content_buffer[CONFIG_READ_BUF+1];
+       config.content_buffer = content_buffer;
+       
+       int read_bytes = config.pending_bytes;
+       if(read_bytes > CONFIG_READ_BUF)
+               read_bytes = CONFIG_READ_BUF;
+       read_bytes = fread(config.content_buffer, 1, read_bytes, config.file);
+       config.content_buffer[read_bytes] = '\0';
+       config.pending_bytes -= read_bytes;
+       
+       config.return_value = 0;
+       parse_config_recursive(NULL, config.content_buffer, &config);
+       
+       fclose(config.file);
+       
+       if(!config.return_value) {
+               //call all the callbacks
+       } else {
+               printf("Error loading config file (%d).\n", config.return_value);
+       }
+}
+
+void reload_config_callback(confreload_callback_t *callback) {
+       struct ConfigReloadCallback *reload_callback = malloc(sizeof(*reload_callback));
+       reload_callback->callback = callback;
+       reload_callback->next = config_reload_callbacks;
+       config_reload_callbacks = reload_callback;
+}
+
diff --git a/src/ircd_client.c b/src/ircd_client.c
new file mode 100644 (file)
index 0000000..3ae6e50
--- /dev/null
@@ -0,0 +1,60 @@
+/* ircd_client.c - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include "ircd_client.h"
+#include "ircd_sock.h"
+#include "struct_connection.h"
+#include "struct_auth.h"
+#include "config.h"
+#include "version.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#define CLIENT_MAXLEN 512
+
+static void client_printf(struct Connection *conn, const char *text, ...) {
+    va_list arg_list;
+       char sendBuf[CLIENT_MAXLEN];
+       int pos;
+       sendBuf[0] = '\0';
+       va_start(arg_list, text);
+       pos = vsnprintf(sendBuf, CLIENT_MAXLEN - 2, text, arg_list);
+       va_end(arg_list);
+       if (pos < 0 || pos > (CLIENT_MAXLEN - 2)) pos = CLIENT_MAXLEN - 2;
+       sendBuf[pos] = '\n';
+    sendBuf[pos+1] = '\0';
+       socket_send(conn, sendBuf, pos);
+}
+
+void client_connected(struct Connection *conn) {
+    client_printf(conn, "NOTICE AUTH :*** NextIRCd v%d.%d (%s)", VERSION_NUMBER, patchlevel, revision);
+    
+    struct Auth *auth = calloc(1, sizeof(*auth));
+    auth->conn = conn;
+    conn->data.auth = auth;
+    
+    /* maybe do some stuff here? */
+}
+
+void client_disconnected(struct Connection *conn) {
+    
+}
+
+void client_recv(struct Connection *conn, char *line) {
+    
+}
diff --git a/src/ircd_client.h b/src/ircd_client.h
new file mode 100644 (file)
index 0000000..e0e0735
--- /dev/null
@@ -0,0 +1,30 @@
+/* ircd_client.h - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#ifndef _ircd_client_h
+#define _ircd_client_h
+
+struct Connection;
+
+/* -- called from ircd_sock.c */
+void client_connected(struct Connection *conn);
+void client_disconnected(struct Connection *conn);
+void client_recv(struct Connection *conn, char *line);
+/* -- */
+
+
+#endif
diff --git a/src/ircd_sock.c b/src/ircd_sock.c
new file mode 100644 (file)
index 0000000..91674b4
--- /dev/null
@@ -0,0 +1,214 @@
+/* ircd_sock.c - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include "config.h"
+#include "ircd_sock.h"
+#include "ircd_client.h"
+#include "struct_connection.h"
+
+#include "IOHandler/IOSockets.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h> // @debug
+
+static struct Connection *sockets_listening = NULL;
+static struct Connection *sockets_first = NULL;
+static struct Connection *sockets_last = NULL;
+
+static CONFRELOAD_CALLBACK(sockets_config_reload);
+static IOSOCKET_CALLBACK(sockets_iohandler_callback);
+static void sockets_free_connection(struct Connection *sock);
+
+void init_sockets() {
+       reload_config_callback(sockets_config_reload);
+       sockets_config_reload(); /* open all listening sockets */
+}
+
+
+static void sockets_append_list(struct Connection *conn) {
+       if(conn->listening) {
+               conn->next = sockets_listening;
+               sockets_listening = conn;
+       } else {
+               conn->next = NULL;
+               conn->prev = sockets_last;
+               if(sockets_last)
+                       sockets_last->next = conn;
+               sockets_last = conn;
+               if(!sockets_first)
+                       sockets_first = conn;
+       }
+}
+
+static void sockets_remove_list(struct Connection *conn) {
+       if(conn->listening) {
+               struct Connection *prev;
+               if(sockets_listening == conn)
+                       sockets_listening = conn->next;
+               else {
+                       for(prev = sockets_listening; prev; prev = prev->next) {
+                               if(prev->next == conn)
+                                       break;
+                       }
+                       if(prev)
+                               prev->next = conn->next;
+               }
+       } else {
+               if(conn->next)
+                       conn->next->prev = conn->prev;
+               else
+                       sockets_last = conn->prev;
+               if(conn->prev)
+                       conn->prev->next = conn->next;
+               else
+                       sockets_first = conn->next;
+       }
+}
+
+static void sockets_free_connection(struct Connection *conn) {
+    free(conn);
+}
+
+static void sockets_close_listening() {
+       struct Connection *conn;
+       while((conn = sockets_listening)) {
+               sockets_remove_list(conn);
+               iosocket_close(conn->socket);
+               sockets_free_connection(conn);
+       }
+}
+
+static int sockets_add_listening(struct ConfigPortObject *conf_port, char *bind_addr, char *certfile, char *keyfile, int socket_flags) {
+    if(!conf_port)
+        return -1;
+    
+    struct IOSocket *iosock;
+    if(!conf_port->secure)
+        iosock = iosocket_listen_flags(bind_addr, conf_port->port, sockets_iohandler_callback, socket_flags);
+    else if(certfile && keyfile)
+        iosock = iosocket_listen_ssl_flags(bind_addr, conf_port->port, certfile, keyfile, sockets_iohandler_callback, socket_flags);
+    else 
+        return -1;
+    
+    if(!iosock)
+        return -1;
+    
+    printf("Added Listener Socket to Port %d.\n", conf_port->port); // @debug
+    
+    struct Connection *connection;
+    connection = calloc(1, sizeof(*connection));
+    connection->listening = 1;
+    connection->socket = iosock;
+    connection->server = conf_port->server;
+    iosock->data = connection;
+    sockets_append_list(connection);
+    return 0;
+}
+
+static void sockets_accept_client(struct IOSocket *new_client, struct Connection *listener) {
+    struct Connection *connection;
+    connection = calloc(1, sizeof(*connection));
+    connection->socket = new_client;
+    connection->ssl = new_client->ssl;
+    
+    new_client->parse_delimiter = 1;
+    new_client->parse_empty = 0;
+    strcpy((char*) new_client->delimiters, "\r\n");
+    
+    connection->parent = listener;
+    new_client->data = connection;
+    sockets_append_list(connection);
+    
+    client_connected(connection);
+}
+
+static CONFRELOAD_CALLBACK(sockets_config_reload) {
+       struct ConfigPortObject *conf_port;
+       char *certfile, *keyfile;
+       
+       sockets_close_listening();
+       
+       certfile = NULL; /* to be continued */
+       keyfile = NULL;
+       
+       for(conf_port = global_config.ports; conf_port; conf_port = conf_port->next) {
+        printf("port: %d\n", conf_port->port); // @debug
+        
+        //add 2 listeners (IPv4 & IPv6) here
+               if(!conf_port->ip4only) {
+            char *bind_addr = conf_port->bind_addr;
+            if(!bind_addr)
+                bind_addr = "::1";
+            sockets_add_listening(conf_port, bind_addr, certfile, keyfile, IOSOCKET_ADDR_IPV6);
+        }
+        
+               if(!conf_port->ip6only) {
+            char *bind_addr = conf_port->bind_addr;
+            if(!bind_addr)
+                bind_addr = "0.0.0.0";
+            sockets_add_listening(conf_port, bind_addr, certfile, keyfile, IOSOCKET_ADDR_IPV4);
+        }
+       }
+}
+
+static IOSOCKET_CALLBACK(sockets_iohandler_callback) {
+       struct Connection *connection = event->socket->data;
+    
+    switch(event->type) {
+    case IOSOCKETEVENT_ACCEPT:
+        sockets_accept_client(event->data.accept_socket, connection);
+        break;
+    
+    case IOSOCKETEVENT_NOTCONNECTED:
+    case IOSOCKETEVENT_CLOSED:
+        sockets_remove_list(connection);
+        if(connection->server) {
+        
+        } else {
+            client_disconnected(connection);
+        }
+        sockets_free_connection(connection);
+        break;
+    
+    case IOSOCKETEVENT_DNSFAILED:
+        if(connection->listening) {
+            // listening socket could not be opened
+        } else {
+            sockets_remove_list(connection);
+            client_disconnected(connection);
+            sockets_free_connection(connection);
+        }
+        break;
+    
+    case IOSOCKETEVENT_RECV:
+        if(connection->server) {
+            
+        } else {
+            client_recv(connection, event->data.recv_str);
+        }
+        break;
+    
+    default:
+        break;
+    }
+}
+
+void socket_send(struct Connection *conn, char *data, int len) {
+    iosocket_send(conn->socket, data, len);
+}
+
diff --git a/src/ircd_sock.h b/src/ircd_sock.h
new file mode 100644 (file)
index 0000000..d0f52f4
--- /dev/null
@@ -0,0 +1,28 @@
+/* ircd_sock.h - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#ifndef _ircd_sock_h
+#define _ircd_sock_h
+
+void init_sockets();
+
+
+struct Connection;
+
+void socket_send(struct Connection *conn, char *data, int len);
+
+#endif
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..fefe88b
--- /dev/null
@@ -0,0 +1,42 @@
+/* main.c - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include "config.h"
+#include "ircd_sock.h"
+#include "IOHandler/IOHandler.h"
+#include "IOHandler/IOLog.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+static IOLOG_CALLBACK(io_log);
+
+int main(int argc, char *argv[]) {
+    iohandler_init();
+    iolog_register_callback(io_log);
+    
+    
+       init_config(NULL);
+       init_sockets();
+       
+    iohandler_run();
+       return 0;
+}
+
+static IOLOG_CALLBACK(io_log) {
+       printf("%s", message);
+}
diff --git a/src/struct_auth.h b/src/struct_auth.h
new file mode 100644 (file)
index 0000000..3a0147c
--- /dev/null
@@ -0,0 +1,34 @@
+/* struct_auth.h - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#ifndef _struct_auth_h
+#define _struct_auth_h
+
+struct Auth {
+    struct Connection *conn;
+    
+    char *nick;
+    char *ident;
+    char *realname;
+    char *passwd;
+    
+    unsigned int ping_number;
+    unsigned int server : 1;
+    
+};
+
+#endif
diff --git a/src/struct_connection.h b/src/struct_connection.h
new file mode 100644 (file)
index 0000000..56f1d40
--- /dev/null
@@ -0,0 +1,43 @@
+/* struct_connection.h - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#ifndef _struct_connection_h
+#define _struct_connection_h
+
+struct IOSocket;
+struct Auth;
+struct Client;
+struct Server;
+
+struct Connection {
+       struct IOSocket *socket;
+    struct Connection *parent;
+       unsigned int listening : 1;
+       unsigned int server : 1;
+       unsigned int ssl : 1;
+       
+    unsigned int authed : 1;
+    union {
+        struct Auth *auth;
+        struct Client *client;
+        struct Server *server;
+    } data;
+    
+       struct Connection *next, *prev; /* managed by ircd_sock.c */
+};
+
+#endif
diff --git a/src/tools.c b/src/tools.c
new file mode 100644 (file)
index 0000000..8a72127
--- /dev/null
@@ -0,0 +1,43 @@
+/* tools.c - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include "tools.h"
+
+int stricmp (const char *s1, const char *s2) {
+    return stricmplen(s1, s2, -1);
+}
+
+int stricmplen(const char *s1, const char *s2, int len) {
+    if (s1 == NULL) 
+        return (s2 == NULL ? 0 : -(*s2));
+    if (s2 == NULL) 
+        return *s1;
+    char c1, c2;
+    int i = 0;
+    while ((c1 = tolower(*s1)) == (c2 = tolower(*s2))) {
+        if (*s1 == '\0') 
+            break;
+        i++;
+        s1++; 
+        s2++;
+        if(len != -1 && i == len) break;
+    }
+    return c1 - c2;
+}
+
diff --git a/src/tools.h b/src/tools.h
new file mode 100644 (file)
index 0000000..ce458c6
--- /dev/null
@@ -0,0 +1,23 @@
+/* tools.h - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+#ifndef _tools_h
+#define _tools_h
+
+int stricmp (const char *s1, const char *s2);
+int stricmplen (const char *s1, const char *s2, int len);
+
+#endif
diff --git a/src/version.h b/src/version.h
new file mode 100644 (file)
index 0000000..813b6eb
--- /dev/null
@@ -0,0 +1,31 @@
+/* version.h - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+#ifndef _version_h
+#define _version_h
+
+#define VERSION_NUMBER 0
+#define VERSION_PATCHLEVEL 0
+
+extern const char *compilation;
+extern const char *creation;
+extern const char *revision;
+extern const char *codelines;
+extern const int revision_master;
+extern const char *dev_revision;
+extern const int patchlevel;
+
+#endif
diff --git a/src/version.sh b/src/version.sh
new file mode 100644 (file)
index 0000000..dfda6bd
--- /dev/null
@@ -0,0 +1,75 @@
+#! /bin/sh
+echo "Extracting version.c ..."
+
+if test -r version.c
+then
+   compilation=`sed -n 's/^const char \*compilation = \"\(.*\)\";/\1/p' < version.c`
+   if test ! "$compilation" ; then compilation=0; fi
+else
+   compilation=0
+fi
+
+compilation=`expr $compilation + 1`
+
+creation=`date | \
+awk '{if (NF == 6) \
+        { print $1 " " $2 " " $3 " " $6 " at " $4 " " $5 } \
+else \
+        { print $1 " " $2 " " $3 " " $7 " at " $4 " " $5 " " $6 }}'`
+
+codelines=`find . -type f -regex '\./.*\.h' -or -regex '\./.*\.c' |xargs cat|wc -l`
+
+
+git_revision_id=`git rev-list -n 1 --pretty="format:%h" --header refs/heads/master | grep '^[0-9a-f]*$'`
+if test "x$git_revision_id" = "x" ; then
+  git_revision="0"
+  git_commitcount="0"
+  git_is_stable="1"
+  git_dev_rev=""
+else
+  git_commitcount=`git rev-list --oneline --first-parent refs/heads/master | wc -l | sed "s/[ \t]//g"`
+  git_revision="git-$git_revision_id"
+  
+  git_real_revision_id=`git rev-list -n 1 --pretty="format:%h" --header HEAD | grep '^[0-9a-f]*$'`
+  if test "$git_revision_id" = "$git_real_revision_id" ; then
+    git_is_stable="1"
+    git_dev_rev=""
+  else
+    git_is_stable="0"
+    git_dev_rev="git-$git_real_revision_id"
+  fi
+fi
+
+
+/bin/cat > version.c <<!SUB!THIS!
+/* version.c - NextIRCd
+ * Copyright (C) 2012-2013  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+//Auto generated file!
+
+#include "version.h"
+
+const char *compilation = "$compilation";
+const char *creation = "$creation";
+const char *revision = "$git_revision";
+const char *codelines = "$codelines";
+const int revision_master = $git_is_stable;
+const char *dev_revision = "$git_dev_rev";
+
+const int patchlevel = ($git_commitcount ? ($git_commitcount - VERSION_PATCHLEVEL) : 0);
+
+!SUB!THIS!
+