From 1c8cbecb4836bafd86885d96cf59e204160927cb Mon Sep 17 00:00:00 2001 From: pk910 Date: Tue, 15 Jul 2014 23:58:05 +0200 Subject: [PATCH] added config parser & incoming connection handler --- configure.ac | 2 +- src/.gitignore | 7 + src/Makefile.am | 17 ++ src/config.c | 348 ++++++++++++++++++++++++++++++++++++++++ src/ircd_client.c | 60 +++++++ src/ircd_client.h | 30 ++++ src/ircd_sock.c | 214 ++++++++++++++++++++++++ src/ircd_sock.h | 28 ++++ src/main.c | 42 +++++ src/struct_auth.h | 34 ++++ src/struct_connection.h | 43 +++++ src/tools.c | 43 +++++ src/tools.h | 23 +++ src/version.h | 31 ++++ src/version.sh | 75 +++++++++ 15 files changed, 996 insertions(+), 1 deletion(-) create mode 100644 src/config.c create mode 100644 src/ircd_client.c create mode 100644 src/ircd_client.h create mode 100644 src/ircd_sock.c create mode 100644 src/ircd_sock.h create mode 100644 src/main.c create mode 100644 src/struct_auth.h create mode 100644 src/struct_connection.h create mode 100644 src/tools.c create mode 100644 src/tools.h create mode 100644 src/version.h create mode 100644 src/version.sh diff --git a/configure.ac b/configure.ac index 4275959..44f4e88 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/src/.gitignore b/src/.gitignore index 3dda729..7b61ddf 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,2 +1,9 @@ +.deps +.libs Makefile.in Makefile +*.o +version.c +ircd.conf +nextircd +nextircd.exe \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 2f259ff..976d039 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 0000000..f7a82af --- /dev/null +++ b/src/config.c @@ -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 . + */ + +#include +#include +#include +#include +#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 index 0000000..3ae6e50 --- /dev/null +++ b/src/ircd_client.c @@ -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 . + */ + +#include "ircd_client.h" +#include "ircd_sock.h" +#include "struct_connection.h" +#include "struct_auth.h" +#include "config.h" +#include "version.h" + +#include +#include +#include +#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 index 0000000..e0e0735 --- /dev/null +++ b/src/ircd_client.h @@ -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 . + */ + +#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 index 0000000..91674b4 --- /dev/null +++ b/src/ircd_sock.c @@ -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 . + */ + +#include "config.h" +#include "ircd_sock.h" +#include "ircd_client.h" +#include "struct_connection.h" + +#include "IOHandler/IOSockets.h" + +#include +#include +#include // @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 index 0000000..d0f52f4 --- /dev/null +++ b/src/ircd_sock.h @@ -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 . + */ + +#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 index 0000000..fefe88b --- /dev/null +++ b/src/main.c @@ -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 . + */ + +#include "config.h" +#include "ircd_sock.h" +#include "IOHandler/IOHandler.h" +#include "IOHandler/IOLog.h" + +#include +#include + +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 index 0000000..3a0147c --- /dev/null +++ b/src/struct_auth.h @@ -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 . + */ + +#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 index 0000000..56f1d40 --- /dev/null +++ b/src/struct_connection.h @@ -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 . + */ + +#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 index 0000000..8a72127 --- /dev/null +++ b/src/tools.c @@ -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 . + */ + +#include +#include +#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 index 0000000..ce458c6 --- /dev/null +++ b/src/tools.h @@ -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 . + */ +#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 index 0000000..813b6eb --- /dev/null +++ b/src/version.h @@ -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 . + */ +#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 index 0000000..dfda6bd --- /dev/null +++ b/src/version.sh @@ -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 <. + */ +//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! + -- 2.20.1