From 2d6305c3d6348431203efcb477726f7897d75fdf Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 5 Feb 2012 22:55:16 +0100 Subject: [PATCH] changed class tool. Now multiple interface per class are supported as well as simple inheritence. --- include/cclass.h | 98 ------------------------------ include/class.h | 81 +++++++++++++++++++++++++ include/interface.h | 39 ++++++++++++ include/interface/class.h | 30 ++++++++++ include/interface/logger.h | 22 +++++++ include/logger.h | 49 ++++++++------- include/server.h | 14 ++--- include/socket.h | 20 +++---- src/cclass.c | 119 ------------------------------------- src/class.c | 28 +++++++++ src/daemonize.c | 6 +- src/interface.c | 45 ++++++++++++++ src/interface/class.c | 43 ++++++++++++++ src/interface/logger.c | 37 ++++++++++++ src/logger.c | 35 +++++++---- src/logger/add.c | 11 ---- src/logger/log.c | 30 ---------- src/logger/stderr.c | 16 +++++ src/logger/syslog.c | 31 ++++++---- src/server.c | 29 +++++---- src/server/close_conn.c | 3 +- src/server/run.c | 34 ++++++----- src/socket.c | 63 ++++++++++---------- src/socket/accept.c | 24 +++----- src/socket/connect.c | 15 ++--- src/socket/listen.c | 17 ++---- src/testserver.c | 10 ++-- 27 files changed, 519 insertions(+), 430 deletions(-) delete mode 100644 include/cclass.h create mode 100644 include/class.h create mode 100644 include/interface.h create mode 100644 include/interface/class.h create mode 100644 include/interface/logger.h delete mode 100644 src/cclass.c create mode 100644 src/class.c create mode 100644 src/interface.c create mode 100644 src/interface/class.c create mode 100644 src/interface/logger.c delete mode 100644 src/logger/add.c delete mode 100644 src/logger/log.c create mode 100644 src/logger/stderr.c diff --git a/include/cclass.h b/include/cclass.h deleted file mode 100644 index 355c318..0000000 --- a/include/cclass.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * \file - * cclass.h: basic "class-like" handling of code and data structures - * Copyright (C) 2011 Georg Hopp - * - * 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 __CCLASS_H__ -#define __CCLASS_H__ - -#include -#include -#include - -#define CCLASS_MAGIC 0xFEFE - - -typedef void (* ctor)(void *, va_list *); -typedef void (* clr)(void *); -typedef void (* dtor)(void *); -typedef void (* jCtor)(void *, struct json_object *); -typedef void (* jTo)(void *, struct json_object **); - -typedef struct _CCLASS { - const int magic; - size_t size; - ctor __construct; - clr __clear; - dtor __destruct; - jCtor __jsonConst; - jTo __toJson; -} * CCLASS; - -#define CCLASS_SIZE sizeof(struct _CCLASS) -#define CCLASS_PTR_SIZE sizeof(CCLASS) - -#define __construct(_class) \ - static void __construct(_class this, va_list * params) -#define __clear(_class) \ - static void __clear(_class this) -#define __destruct(_class) \ - static void __destruct(_class this) -#define __jsonConst(_class) \ - static void __jsonConst(_class this, struct json_object * json) -#define __toJson(_class) \ - static void __toJson(_class this, struct json_object ** json) - -#define CLASS(_class) \ - struct _##_class; \ - typedef struct _##_class * _class; \ - extern const CCLASS const __##_class; \ - struct _##_class - -#define INIT_CLASS(_class) \ - __construct(_class); \ - __clear(_class); \ - __destruct(_class); \ - __jsonConst(_class); \ - __toJson(_class); \ - static const struct _CCLASS _cclass = { \ - CCLASS_MAGIC, \ - sizeof(struct _##_class), \ - (ctor)__construct, \ - (clr)__clear, \ - (dtor)__destruct, \ - (jCtor)__jsonConst, \ - (jTo)__toJson \ - }; const CCLASS __##_class = (const CCLASS)&_cclass - -void * _new(const CCLASS _class, ...); -#define new(_class, ...) _new((__##_class), __VA_ARGS__) - -void * _newFromJson(const CCLASS _class, struct json_object * json); -#define newFromJson(_class, json) _newFromJson((__##_class), (json)) - -int _instanceOf(const CCLASS _class, void * _object); -#define instanceOf(_class, object) _instanceOf((__##_class), (object)) - -void clear(void * _object); -void delete(void * _object); -void toJson(void * _object, struct json_object ** json); -int isObject(void * _object); - -#endif//__CCLASS_H__ - -// vim: set et ts=4 sw=4: diff --git a/include/class.h b/include/class.h new file mode 100644 index 0000000..9f903ef --- /dev/null +++ b/include/class.h @@ -0,0 +1,81 @@ +#ifndef __CLASS_H__ +#define __CLASS_H__ + +#include +#include +#include +#include + +#include "interface.h" + +#define _ISOC99_SOURCE + +#define CLASS_MAGIC 0xFEFE + +#define CLASS(name) \ + struct c_##name; \ + typedef struct c_##name * name; \ + extern struct class * const _##name; \ + struct c_##name + +#define EXTENDS(parent) \ + const char _[sizeof(struct c_##parent)] + +#define _NULL NULL +#define CREATE_CLASS(name,_parent,...) \ + static struct class c_##name; \ + static void _classInit_(void) { \ + c_##name.parent = _##_parent; \ + c_##name.init = NULL; \ + } \ + static struct class c_##name = { \ + CLASS_MAGIC, \ + NULL, \ + sizeof(struct c_##name), \ + _classInit_, \ + INIT_IMPL(__VA_ARGS__) \ + }; struct class * const _##name = &c_##name + +/** + * @TODO: actually i use gcc feature ## for variadoc... think about + * a way to make this standard. + */ +#define CALL(object,_iface,method,...) \ + do { \ + class_ptr class = class_getClass((object)); \ + struct i_##_iface * iface; \ + if (class->init) class->init(); \ + iface = (struct i_##_iface *)class_getInterface(&class, &i_##_iface); \ + while ((NULL == iface || NULL == iface->method) && HAS_PARENT(class)) { \ + class = class->parent; \ + if (class->init) class->init(); \ + iface = (struct i_##_iface *)class_getInterface(&class, &i_##_iface); \ + }; \ + assert(NULL != iface->method); \ + iface->method(object, ##__VA_ARGS__); \ + } while(0) + + +#define IFACE_GET(class,iface) (interfaceGet(&((class)->impl),(iface))) +#define IFACE_EXISTS(class,iface) (NULL != IFACE_GET((class),(iface))) + +#define HAS_PARENT(class) (NULL != ((class)->parent)) + +typedef void (* fptr_classInit)(void); + +struct class; +typedef struct class * class_ptr; +struct class { + const int magic; + class_ptr parent; + size_t object_size; + fptr_classInit init; + struct iface_impl impl; +}; + +extern inline void * class_getInterface(class_ptr *, iface_ptr); +extern inline class_ptr class_getClass(void *); + +#endif // __CLASS_H__ + +// vim: set ts=4 sw=4: diff --git a/include/interface.h b/include/interface.h new file mode 100644 index 0000000..27873e7 --- /dev/null +++ b/include/interface.h @@ -0,0 +1,39 @@ +#ifndef __INTERFACE_H__ +#define __INTERFACE_H__ + +#include + +#define MAX_IFACE 32 // ATTENTION: every iface_impl will use MAX_IFACE * sizeof(void*) + +#define IFACE(name) ((const struct i_##name const*)&i_##name##_impl) + +#define INIT_IFACE(name,...) \ + static const struct i_##name i_##name##_impl = {&i_##name,__VA_ARGS__} + +#define NUMARGS(...) (sizeof((const void*[]){__VA_ARGS__})/sizeof(void*)) + +#define INIT_IMPL(...) {NUMARGS(__VA_ARGS__), 0, {__VA_ARGS__}} +#define CREATE_IMPL(...) \ + static struct iface_impl iface_impl = INIT_IMPL(__VA_ARGS__) + +#define METHOD_GET(iface,method) (iface->method) + + +struct interface { + const char * name; + const size_t nmethods; +}; +typedef const struct interface * iface_ptr; + +struct iface_impl { + const size_t nimpl; // number of interface implementations + char simpl; // implementations sorted?? + const void * impl[MAX_IFACE]; // implementations +}; +typedef struct iface_impl * iface_impl_ptr; + +extern struct interface * interfaceGet(iface_impl_ptr, const iface_ptr); + +#endif // __INTERFACE_H__ + +// vim: set ts=4 sw=4: diff --git a/include/interface/class.h b/include/interface/class.h new file mode 100644 index 0000000..aafa637 --- /dev/null +++ b/include/interface/class.h @@ -0,0 +1,30 @@ +#ifndef __INTERFACE_CLASS_H__ +#define __INTERFACE_CLASS_H__ + +#include + +#include "class.h" +#include "interface.h" + +typedef void (* fptr_ctor)(void *, va_list *); +typedef void (* fptr_dtor)(void *); +typedef void (* fptr_clone)(void *, const void * const); + +extern const struct interface i_Class; + +struct i_Class { + const struct interface * const _; + fptr_ctor ctor; + fptr_dtor dtor; + fptr_clone clone; +}; + +extern inline void * classNew(class_ptr, ...); +extern inline void classDelete(void **); + +#define new(class,...) classNew(_##class, __VA_ARGS__) +#define delete(object) classDelete((void **)(object)) + +#endif // __INTERFACE_CLASS_H__ + +// vim: set ts=4 sw=4: diff --git a/include/interface/logger.h b/include/interface/logger.h new file mode 100644 index 0000000..803ae9b --- /dev/null +++ b/include/interface/logger.h @@ -0,0 +1,22 @@ +#ifndef __INTERFACE_LOGGER_H__ +#define __INTERFACE_LOGGER_H__ + +#include + +#include "interface.h" +#include "logger.h" + +typedef void (* fptr_log)(void *, logger_level, const char * const); + +extern const struct interface i_Logger; + +struct i_Logger { + const struct interface * const _; + fptr_log log; +}; + +extern inline void loggerLog(void *, logger_level, const char * const, ...); + +#endif // __INTERFACE_LOGGER_H__ + +// vim: set ts=4 sw=4: diff --git a/include/logger.h b/include/logger.h index 67fb033..bc7b87d 100644 --- a/include/logger.h +++ b/include/logger.h @@ -1,34 +1,33 @@ #ifndef __LOGGER_H__ #define __LOGGER_H__ -#include "cclass.h" - - -#define LOGGER_EMERG 0 -#define LOGGER_ALERT 1 -#define LOGGER_CRIT 2 -#define LOGGER_ERR 3 -#define LOGGER_WARNING 4 -#define LOGGER_NOTICE 5 -#define LOGGER_INFO 6 -#define LOGGER_DEBUG 7 - -#define MAX_LOG_FNCTS 10 - - -typedef void (*logger_logfnct)(int level, const char * msg); - - -CLASS(LOGGER) { - logger_logfnct logfncts[MAX_LOG_FNCTS]; - unsigned int logfncts_count; +#include "class.h" + +typedef enum logger_level { + LOGGER_DEBUG=0, + LOGGER_INFO, + LOGGER_NOTICE, + LOGGER_WARNING, + LOGGER_ERR, + LOGGER_CRIT, + LOGGER_ALERT, + LOGGER_EMERG +} logger_level; + +extern const char * const logger_level_str[]; + +CLASS(Logger) { + logger_level min_level; }; -void logger_log(LOGGER this, int level, const char * msg, ...) - __attribute__((format (printf, 3, 4))); +CLASS(LoggerStderr) { + EXTENDS(Logger); +}; -void logger_add(LOGGER this, logger_logfnct logfunc); +CLASS(LoggerSyslog) { + EXTENDS(Logger); +}; -#endif /* __LOGGER_H__ */ +#endif // __LOGGER_H__ // vim: set ts=4 sw=4: diff --git a/include/server.h b/include/server.h index 2352b8f..a684a33 100644 --- a/include/server.h +++ b/include/server.h @@ -4,9 +4,9 @@ #include /* for printf() and fprintf() */ #include /* for select system call and related */ +#include "class.h" #include "socket.h" #include "logger.h" -#include "cclass.h" #define POLL_FD_NSIZE 1024 #define POLL_FD_SIZE (sizeof(struct pollfd) * POLL_FD_NSIZE) @@ -23,14 +23,14 @@ typedef void (*server_read_hook)(const char *, size_t); -CLASS(SERVER) { - LOGGER logger; - SOCK sock; +CLASS(Server) { + Logger logger; + Sock sock; nfds_t nfds; struct pollfd fds[POLL_FD_NSIZE]; struct { - SOCK sock; + Sock sock; char * wbuf; char * rbuf; unsigned int rpos; @@ -40,8 +40,8 @@ CLASS(SERVER) { server_read_hook read_hook; }; -void server_run(SERVER this); -void server_close_conn(SERVER this, unsigned int handle); +void serverRun(Server this); +void serverCloseConn(Server this, unsigned int handle); #endif // __SERVER_H__ diff --git a/include/socket.h b/include/socket.h index 5c353aa..e5b116d 100644 --- a/include/socket.h +++ b/include/socket.h @@ -1,23 +1,23 @@ #ifndef __SOCKET_H__ #define __SOCKET_H__ -#include /* for in_port_t */ +#include /* for in_port_t */ +#include "class.h" #include "logger.h" -#include "cclass.h" - -CLASS(SOCK) { - LOGGER logger; +CLASS(Sock) { + Logger log; in_port_t port; struct sockaddr_in addr; - int handle; /* socket handle for server */ + int handle; }; -void sock_connect(SOCK this, const char * addr); -void sock_listen(SOCK this, int backlog); -SOCK sock_accept(SOCK this, char remoteAddr[16]); +void socketConnect(Sock this, const char * addr); +void socketListen(Sock this, int backlog); +Sock socketAccept(Sock this, char remoteAddr[16]); -#endif /* __SOCKET_H__ */ +#endif // __SOCKET_H__ // vim: set ts=4 sw=4: + diff --git a/src/cclass.c b/src/cclass.c deleted file mode 100644 index 3f02a69..0000000 --- a/src/cclass.c +++ /dev/null @@ -1,119 +0,0 @@ -/** - * \file - * cclass.c: basic "class-like" handling of code and data structures - * Copyright (C) 2011 Georg Hopp - * - * 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 "cclass.h" - -#undef __construct -#undef __clear -#undef __destruct -#undef __jsonConst -#undef __toJson - -void * -_new(const CCLASS _class, ...) -{ - const CCLASS class = _class; - void * object = calloc(1, class->size + sizeof(void *)); - - * (const struct _CCLASS **)object = class; - object += sizeof(CCLASS); - - if (class->__construct) { - va_list params; - - va_start(params, _class); - class->__construct(object, ¶ms); - va_end(params); - } - - return object; -} - -void * -_newFromJson(const CCLASS _class, struct json_object * json) -{ - const CCLASS class = _class; - void * object = calloc(1, class->size + sizeof(CCLASS)); - - * (const struct _CCLASS **) object = class; - object += sizeof(CCLASS); - - if (class->__jsonConst && json) { - class->__jsonConst(object, json); - } - - return object; -} - -int -_instanceOf(const CCLASS _class, void * _object) -{ - const CCLASS * class = _object - sizeof(CCLASS); - - return (class && _class == *class); -} - - -void -clear(void * _object) -{ - const CCLASS * class = _object - sizeof(CCLASS); - - if (_object && *class && (*class)->__clear) { - (*class)->__clear(_object); - } -} - -void -delete(void ** _object) -{ - const CCLASS * class = (*_object) - sizeof(CCLASS); - - if (*_object && *class && (*class)->__destruct) { - (*class)->__destruct(*_object); - } - - free((void *)class); - *_object = NULL; -} - -void -toJson(void * _object, struct json_object ** json) -{ - const CCLASS * class = _object - sizeof(CCLASS); - - if (_object && *class && (*class)->__toJson) { - (*class)->__toJson(_object, json); - } -} - -int -isObject(void * _object) -{ - const CCLASS * class = _object - sizeof(CCLASS); - - return (_object && (*class) && CCLASS_MAGIC == (*class)->magic); -} - -// vim: set et ts=4 sw=4: diff --git a/src/class.c b/src/class.c new file mode 100644 index 0000000..98d5604 --- /dev/null +++ b/src/class.c @@ -0,0 +1,28 @@ +#include +#include + +#include "class.h" +#include "interface.h" + +inline +void * +class_getInterface(class_ptr * class, iface_ptr _iface) +{ + void * iface = (void *)IFACE_GET(*class, _iface); + + while(NULL == iface && HAS_PARENT(*class)) { + *class = (*class)->parent; + iface = (void *)IFACE_GET(*class, _iface); + } + + return iface; +} + +inline +class_ptr +class_getClass(void * object) +{ + return *(class_ptr *)(object - sizeof(void*)); +} + +// vim: set ts=4 sw=4: diff --git a/src/daemonize.c b/src/daemonize.c index 6776da1..e07a1af 100644 --- a/src/daemonize.c +++ b/src/daemonize.c @@ -17,7 +17,7 @@ void daemonize(void) { setsid(); /* connect all standard streams to /dev/null */ - freopen("/dev/null", "w", stderr); - freopen("/dev/null", "r", stdin); - freopen("/dev/null", "w", stdout); + stderr = freopen("/dev/null", "w", stderr); + stdin = freopen("/dev/null", "r", stdin); + stdout = freopen("/dev/null", "w", stdout); } diff --git a/src/interface.c b/src/interface.c new file mode 100644 index 0000000..2d8fa02 --- /dev/null +++ b/src/interface.c @@ -0,0 +1,45 @@ +#include +#include + +#include "interface.h" + +#ifndef TRUE +#define TRUE 1 +#endif // TRUE + +static +inline +int +comp(const void * _a, const void * _b) +{ + const struct interface * a = **(const struct interface ***)_a; + const struct interface * b = **(const struct interface ***)_b; + return ((a)<(b))? -1 : ((a)>(b))? 1 : 0; +} + +/** + * this one is important in selector functions to get the correct interface + * implementation of a class. + */ +struct interface * +interfaceGet(iface_impl_ptr iface_impl, const iface_ptr _iface) +{ + const iface_ptr * iface = &_iface; + void * dummy; + + if (! iface_impl->simpl) { + qsort((void**)(iface_impl->impl), iface_impl->nimpl, sizeof(iface_ptr), comp); + iface_impl->simpl=TRUE; + } + + dummy = bsearch( + &iface, + iface_impl->impl, + iface_impl->nimpl, + sizeof(iface_ptr), + comp); + + return dummy? *(struct interface **)dummy : dummy; +} + +// vim: set ts=4 sw=4: diff --git a/src/interface/class.c b/src/interface/class.c new file mode 100644 index 0000000..9772224 --- /dev/null +++ b/src/interface/class.c @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "class.h" +#include "interface/class.h" + +const +struct interface i_Class = { + "class", + 3 +}; + +inline +void * +classNew(class_ptr class, ...) +{ + void * object = calloc(1, class->object_size + sizeof(void*)); + va_list params; + + if (class->init) class->init(); + + * (class_ptr *)object = class; + object += sizeof(void*); + + va_start(params, class); + CALL(object, Class, ctor, ¶ms); + va_end(params); + + return object; +} + +inline +void +classDelete(void ** object) +{ + CALL(*object, Class, dtor); + + free(*object - sizeof(void*)); + *object = NULL; +} + +// vim: set ts=4 sw=4: diff --git a/src/interface/logger.c b/src/interface/logger.c new file mode 100644 index 0000000..6829128 --- /dev/null +++ b/src/interface/logger.c @@ -0,0 +1,37 @@ +#include + +#include "logger.h" +#include "interface/logger.h" + +const struct interface i_Logger = { + "logger", + 1 +}; + +inline +void +loggerLog(void * _object, logger_level level, const char * const fmt, ...) { + Logger object = _object; + + if (level >= object->min_level) { + char * msg = NULL; + size_t msg_size = 0; + va_list params; + + va_start(params, fmt); + msg_size = vsnprintf(msg, msg_size, fmt, params); + va_end(params); + + msg = malloc(msg_size + 1); + + va_start(params, fmt); + vsnprintf(msg, msg_size + 1, fmt, params); + va_end(params); + + CALL(_object, Logger, log, level, msg); + + free(msg); + } +} + +// vim: set ts=4 sw=4: diff --git a/src/logger.c b/src/logger.c index 96ad785..6a44531 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,18 +1,33 @@ -#include "logger.h" +#include -extern void logger_syslog(int level, const char * msg); +#include "logger.h" +#include "interface/class.h" +#include "interface/logger.h" -INIT_CLASS(LOGGER); +const +char * const +logger_level_str[] = { + "DEBUG", + "INFO", + "NOTICE", + "WARNING", + "ERR", + "CRIT", + "ALERT", + "EMERG" +}; -__construct(LOGGER) +static +void +ctor(void * _this, va_list * params) { - this->logfncts[0] = logger_syslog; - this->logfncts_count = 1; + Logger this = _this; + this->min_level = va_arg(*params, int); } -__destruct(LOGGER) {} -__jsonConst(LOGGER) {} -__toJson(LOGGER) {} -__clear(LOGGER) {} +static void dtor(void * _this) {} + +INIT_IFACE(Class, ctor, dtor, NULL); +CREATE_CLASS(Logger, NULL, IFACE(Class)); // vim: set ts=4 sw=4: diff --git a/src/logger/add.c b/src/logger/add.c deleted file mode 100644 index 474fecc..0000000 --- a/src/logger/add.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "logger.h" - -void -logger_add(LOGGER this, logger_logfnct logfunc) { - if (this->logfncts_count < MAX_LOG_FNCTS) { - this->logfncts[this->logfncts_count] = logfunc; - this->logfncts_count++; - } -} - -// vim: set ts=4 sw=4: diff --git a/src/logger/log.c b/src/logger/log.c deleted file mode 100644 index f4c5dfa..0000000 --- a/src/logger/log.c +++ /dev/null @@ -1,30 +0,0 @@ -#define _ISOC99_SOURCE - -#include -#include - -#include "logger.h" - -void -logger_log(LOGGER this, int level, const char * message, ...) { - va_list args; - char buffer[1025]; - logger_logfnct * logfnct; - - int maxBuf = sizeof(buffer)/sizeof(buffer[0]); - - memset(buffer, 0, maxBuf); - - va_start(args, message); - vsnprintf(buffer, 1024, message, args); - va_end(args); - - logfnct = this->logfncts; - - while (NULL != *logfnct) { - (*logfnct)(level, buffer); - logfnct++; - } -} - -// vim: set ts=4 sw=4: diff --git a/src/logger/stderr.c b/src/logger/stderr.c new file mode 100644 index 0000000..b6f5c56 --- /dev/null +++ b/src/logger/stderr.c @@ -0,0 +1,16 @@ +#include + +#include "logger.h" +#include "interface/logger.h" + +static +void +logStderr(void * this, logger_level level, const char * const msg) +{ + fprintf(stderr, "[%s] %s\n", logger_level_str[level], msg); +} + +INIT_IFACE(Logger, logStderr); +CREATE_CLASS(LoggerStderr, Logger, IFACE(Logger)); + +// vim: set ts=4 sw=4: diff --git a/src/logger/syslog.c b/src/logger/syslog.c index 0299fa8..a42f901 100644 --- a/src/logger/syslog.c +++ b/src/logger/syslog.c @@ -1,20 +1,29 @@ #include -const int priority[] = { - LOG_USER | LOG_EMERG, - LOG_USER | LOG_ALERT, - LOG_USER | LOG_CRIT, - LOG_USER | LOG_ERR, - LOG_USER | LOG_WARNING, - LOG_USER | LOG_NOTICE, - LOG_USER | LOG_INFO, - LOG_USER | LOG_DEBUG +#include "logger.h" +#include "interface/logger.h" + +static +const +int syslog_priority[] = { + LOG_USER | LOG_DEBUG, + LOG_USER | LOG_INFO, + LOG_USER | LOG_NOTICE, + LOG_USER | LOG_WARNING, + LOG_USER | LOG_ERR, + LOG_USER | LOG_CRIT, + LOG_USER | LOG_ALERT, + LOG_USER | LOG_EMERG }; +static void -logger_syslog(int level, const char * msg) +logSyslog(void * this, logger_level level, const char * const msg) { - syslog(priority[level], "%s", msg); + syslog(syslog_priority[level], "[%s] %s", logger_level_str[level], msg); } +INIT_IFACE(Logger, logSyslog); +CREATE_CLASS(LoggerSyslog, Logger, IFACE(Logger)); + // vim: set ts=4 sw=4: diff --git a/src/server.c b/src/server.c index 73304c9..c366b5f 100644 --- a/src/server.c +++ b/src/server.c @@ -2,34 +2,38 @@ #include /* for memset and stuff */ #include /* for getopt */ +#include "class.h" #include "server.h" #include "socket.h" -#include "server.h" #include "logger.h" -#include "cclass.h" - -INIT_CLASS(SERVER); +#include "interface/class.h" -__construct(SERVER) +static +void +ctor(void * _this, va_list * params) { + Server this = _this; in_port_t port; unsigned int backlog; - this->logger = va_arg(* params, LOGGER); + this->logger = va_arg(* params, Logger); port = va_arg(* params, int); backlog = va_arg(* params, unsigned int); - this->sock = new(SOCK, this->logger, port); - sock_listen(this->sock, backlog); + this->sock = new(Sock, this->logger, port); + socketListen(this->sock, backlog); (this->fds)[0].fd = this->sock->handle; (this->fds)[0].events = POLLIN; this->nfds = 1; } -__destruct(SERVER) +static +void +dtor(void * _this) { - int i; + Server this = _this; + int i; for (i=1; infds; i++) { /* @@ -41,8 +45,7 @@ __destruct(SERVER) delete(&this->sock); } -__jsonConst(SERVER) {} -__toJson(SERVER) {} -__clear(SERVER) {} +INIT_IFACE(Class, ctor, dtor, NULL); +CREATE_CLASS(Server, NULL, IFACE(Class)); // vim: set ts=4 sw=4: diff --git a/src/server/close_conn.c b/src/server/close_conn.c index b131434..29dbcfd 100644 --- a/src/server/close_conn.c +++ b/src/server/close_conn.c @@ -1,9 +1,10 @@ #include #include "server.h" +#include "interface/class.h" void -server_close_conn(SERVER this, unsigned int i) +serverCloseConn(Server this, unsigned int i) { delete(&((this->conns)[i].sock)); CLEAR_CONN(this, i); diff --git a/src/server/run.c b/src/server/run.c index 90bfd52..ecac6d7 100644 --- a/src/server/run.c +++ b/src/server/run.c @@ -4,17 +4,18 @@ #include /* for errno */ #include -#include "include/logger.h" -#include "include/server.h" -#include "include/socket.h" -#include "include/signalHandling.h" +#include "server.h" +#include "socket.h" +#include "logger.h" +#include "signalHandling.h" +#include "interface/class.h" #undef MAX #define MAX(x,y) ((x) > (y) ? (x) : (y)) static int -server_poll(SERVER this) { +serverPoll(Server this) { int events; /* @@ -30,7 +31,7 @@ server_poll(SERVER this) { /* Fallthrough */ case EINTR: - logger_log(this->logger, LOGGER_CRIT, + loggerLog(this->logger, LOGGER_CRIT, "poll systemcall failed: [%s] - service terminated", strerror(errno)); //exit(EXIT_FAILURE); /* @TODO do real shutdown here */ @@ -42,13 +43,13 @@ server_poll(SERVER this) { static void -server_handle_accept(SERVER this) +serverHandleAccept(Server this) { if (0 != ((this->fds)[0].revents & POLLIN)) { char remoteAddr[16] = ""; - SOCK acc; + Sock acc; - acc = sock_accept(this->sock, remoteAddr); + acc = socketAccept(this->sock, remoteAddr); if (-1 != acc->handle) { (this->conns)[this->nfds].sock = acc; // save the socket handle @@ -65,7 +66,7 @@ server_handle_accept(SERVER this) static int -server_read(SERVER this) +serverRead(Server this) { unsigned int i; size_t _read; @@ -85,7 +86,8 @@ server_read(SERVER this) * read failure / close connection * FALLTHROUGH */ - server_close_conn(this, i); + loggerLog(this->logger, LOGGER_INFO, "connection closed..."); + serverCloseConn(this, i); break; default: @@ -102,12 +104,12 @@ server_read(SERVER this) } void -server_run(SERVER this) +serverRun(Server this) { /* * @TODO again...add verbosity to logger.... */ - logger_log(this->logger, LOGGER_INFO, "service started"); + loggerLog(this->logger, LOGGER_INFO, "service started"); while (!doShutdown) /* until error or signal */ { @@ -116,16 +118,16 @@ server_run(SERVER this) * @TODO take return value of poll into account with * further handling! */ - events = server_poll(this); + events = serverPoll(this); if (doShutdown) break; /* * handle accept */ - server_handle_accept(this); + serverHandleAccept(this); /* handle reads */ - server_read(this); + serverRead(this); } } diff --git a/src/socket.c b/src/socket.c index 15b25ff..a744e5e 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1,49 +1,46 @@ -#include /* for printf() and fprintf() */ -#include /* SO_REUSEADDR */ -#include /* for socket(), bind(), and connect() */ -#include /* for sockaddr_in and inet_ntoa() */ -#include /* for atoi() and exit() */ -#include /* for memset() */ -#include /* for close() */ -#include /* for errno */ -#include +#include +#include -#include "logger.h" -#include "cclass.h" #include "socket.h" +#include "logger.h" +#include "interface/class.h" +#include "interface/logger.h" - -INIT_CLASS(SOCK); - -__construct(SOCK) +static +void +ctor(void * _this, va_list * params) { - int reUse = 1; /* TODO: make this configurable */ - - this->logger = va_arg(* params, LOGGER); - this->port = va_arg(* params, int); - - /* Create socket for incoming connections */ - if (-1 == (this->handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { - logger_log(this->logger, LOGGER_CRIT, - "error opening socket: %s - service terminated", - strerror(errno)); - exit(EXIT_FAILURE); - } + Sock this = _this; + int reUse = 1; /* TODO: make this configurable */ + + this->log = va_arg(* params, Logger); + this->port = va_arg(* params, int); + + /* Create socket for incoming connections */ + if (-1 == (this->handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { + loggerLog(this->log, LOGGER_CRIT, + "error opening socket: %s - service terminated", + strerror(errno)); + exit(EXIT_FAILURE); + } - /* Make the socket REUSE a TIME_WAIT socket */ - setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof (reUse)); + /* Make the socket REUSE a TIME_WAIT socket */ + setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof (reUse)); } -__destruct(SOCK) +static +void +dtor(void * _this) { + Sock this = _this; + if (0 != this->handle) { shutdown(this->handle, SHUT_RDWR); close(this->handle); } } -__jsonConst(SOCK) {} -__toJson(SOCK) {} -__clear(SOCK) {} +INIT_IFACE(Class, ctor, dtor, NULL); +CREATE_CLASS(Sock, NULL, IFACE(Class)); // vim: set ts=4 sw=4: diff --git a/src/socket/accept.c b/src/socket/accept.c index e01bdfe..708a45f 100644 --- a/src/socket/accept.c +++ b/src/socket/accept.c @@ -1,27 +1,19 @@ -#include /* for printf() and fprintf() */ -#include /* SO_REUSEADDR */ -#include /* for socket(), bind(), and connect() */ -#include /* for sockaddr_in and inet_ntoa() */ -#include /* for atoi() and exit() */ -#include /* for memset() */ -#include /* for close() */ #include /* for errno */ -#include -#include "logger.h" -#include "cclass.h" #include "socket.h" +#include "interface/class.h" +#include "interface/logger.h" -SOCK -sock_accept(SOCK this, char remoteAddr[16]) +Sock +socketAccept(Sock this, char remoteAddr[16]) { - SOCK sock; /* Socket for client */ + Sock sock; /* Socket for client */ unsigned int len; /* Length of client address data structure */ /* Set the size of the in-out parameter */ len = sizeof(this->addr); - sock = new(SOCK, this->logger, this->port); + sock = new(Sock, this->log, this->port); /** * @TODO: change port to remote port on success */ @@ -29,10 +21,10 @@ sock_accept(SOCK this, char remoteAddr[16]) /* Wait for a client to connect */ sock->handle = accept(this->handle, (struct sockaddr *) &(sock->addr), &len); if (-1 == sock->handle) { - logger_log(this->logger, LOGGER_WARNING, + loggerLog(this->log, LOGGER_WARNING, "error acception connection: %s", strerror(errno)); } else { - logger_log(this->logger, LOGGER_INFO, + loggerLog(this->log, LOGGER_INFO, "handling client %s\n", inet_ntoa((sock->addr).sin_addr)); } diff --git a/src/socket/connect.c b/src/socket/connect.c index 41ed76b..abb2348 100644 --- a/src/socket/connect.c +++ b/src/socket/connect.c @@ -1,27 +1,20 @@ -#include /* for printf() and fprintf() */ -#include /* SO_REUSEADDR */ -#include /* for socket(), bind(), and connect() */ -#include /* for sockaddr_in and inet_ntoa() */ #include /* for atoi() and exit() */ -#include /* for memset() */ -#include /* for close() */ #include /* for errno */ -#include -#include "logger.h" -#include "cclass.h" #include "socket.h" +#include "interface/class.h" +#include "interface/logger.h" void -sock_connect(SOCK this, const char * addr) +socketConnect(Sock this, const char * addr) { inet_pton(AF_INET, addr, &((this->addr).sin_addr)); (this->addr).sin_family = AF_INET; /* Internet address family */ (this->addr).sin_port = htons(this->port); /* Local port */ if (-1 == connect(this->handle, (struct sockaddr*) &(this->addr), sizeof(this->addr))) { - logger_log(this->logger, LOGGER_CRIT, + loggerLog(this->log, LOGGER_CRIT, "error connection socket: %s - service terminated", strerror(errno)); exit(EXIT_FAILURE); diff --git a/src/socket/listen.c b/src/socket/listen.c index 847816e..13d3b65 100644 --- a/src/socket/listen.c +++ b/src/socket/listen.c @@ -1,20 +1,13 @@ -#include /* for printf() and fprintf() */ -#include /* SO_REUSEADDR */ -#include /* for socket(), bind(), and connect() */ -#include /* for sockaddr_in and inet_ntoa() */ #include /* for atoi() and exit() */ -#include /* for memset() */ -#include /* for close() */ #include /* for errno */ -#include -#include "logger.h" -#include "cclass.h" #include "socket.h" +#include "interface/class.h" +#include "interface/logger.h" void -sock_listen(SOCK this, int backlog) +socketListen(Sock this, int backlog) { (this->addr).sin_family = AF_INET; /* Internet address family */ (this->addr).sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ @@ -22,7 +15,7 @@ sock_listen(SOCK this, int backlog) /* Bind to the local address */ if (-1 == bind(this->handle, (struct sockaddr *) &(this->addr), sizeof(this->addr))) { - logger_log(this->logger, LOGGER_CRIT, + loggerLog(this->log, LOGGER_CRIT, "error binding socket: %s - service terminated", strerror(errno)); exit(EXIT_FAILURE); @@ -30,7 +23,7 @@ sock_listen(SOCK this, int backlog) /* Mark the socket so it will listen for incoming connections */ if (-1 == listen(this->handle, backlog)) { - logger_log(this->logger, LOGGER_CRIT, + loggerLog(this->log, LOGGER_CRIT, "error binding socket: %s - service terminated", strerror(errno)); exit(EXIT_FAILURE); diff --git a/src/testserver.c b/src/testserver.c index 96bcba3..c290907 100644 --- a/src/testserver.c +++ b/src/testserver.c @@ -3,7 +3,9 @@ #include #include "server.h" +#include "logger.h" #include "signalHandling.h" +#include "interface/class.h" static void read_hook(const char * _buffer, size_t size) @@ -11,7 +13,7 @@ read_hook(const char * _buffer, size_t size) char buffer[1025]; memset(buffer, 0, 1025); - snprintf(buffer, size, _buffer); + snprintf(buffer, 1025>size? size : 1024, "%s", _buffer); printf("%s\n", buffer); } @@ -19,13 +21,13 @@ read_hook(const char * _buffer, size_t size) int main() { - LOGGER logger = new(LOGGER, NULL); - SERVER server = new(SERVER, logger, 11212, SOMAXCONN); + Logger logger = new(LoggerStderr, LOGGER_INFO); + Server server = new(Server, logger, 11212, SOMAXCONN); server->read_hook = read_hook; init_signals(); - server_run(server); + serverRun(server); delete(&server); delete(&logger);