diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 6b92f82..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "cStuff"] - path = cStuff - url = https://github.com/lowenware/cStuff.git diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index e69de29..0000000 diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 3d42de2..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,131 +0,0 @@ -cmake_minimum_required (VERSION 2.8) - -project ( AISL C) - -set (PROJECT_TITLE "aisl") -set (LIBRARY_NAME ${PROJECT_TITLE}) -# set (DEMO_NAME "demo") - -# Defaults -------------------------------------------------------------------- - -include (cmake.compiler) -include (cmake.version) -include (cmake.system) -include (cmake.paths) - -# Definitions ----------------------------------------------------------------- - -add_definitions( - -DPROJECT_TITLE="${PROJECT_TITLE}" -) - -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden") - -if(DEFINED CMAKE_DEBUG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror ") - add_definitions( -DDEBUG=${CMAKE_DEBUG} ) -endif() - - -# Options --------------------------------------------------------------------- - -#if( DEFINED WITH_EVERYTHING ) -# set(WITH_TEMPLIGHT 1) -# set(WITH_OPTIONS 1) -# set(WITH_CONFIG 1) -#endif() - -# Sources --------------------------------------------------------------------- - -include_directories( "." ${INCLUDE_DIR} ) - -add_definitions( -DLIST_WITH_APPEND - -DCSTUFF_LIST_WITH_REMOVE_INDEX - -DCSTUFF_LIST_WITH_REMOVE - -DCSTUFF_LIST_WITH_APPEND - -DCSTUFF_LIST_WITH_INSERT - -DCSTUFF_LIST_WITH_COPY - -DCSTUFF_STR_UTILS_WITH_COPY - -DCSTUFF_STR_UTILS_WITH_NCAT - -DCSTUFF_STR_UTILS_WITH_CMPI - -DCSTUFF_STR_UTILS_WITH_PRINTF - -DCSTUFF_STR_UTILS_WITH_NCOPY - -DSTR_UTILS_WITH_COPY - -DSTR_UTILS_WITH_NCOPY - -DSTR_UTILS_WITH_CAT - -DSTR_UTILS_WITH_PRINTF - -DSTR_UTILS_WITH_CMPI -) - -set ( LIBRARY_SOURCES library/aisl.c - library/buffer.c - library/server.c - library/client.c - library/stream.c - library/parser.c - library/http.c - library/handle.c - library/status.c - library/event.c - cStuff/list.c - cStuff/str-utils.c) - -set ( DEMO_SOURCES demo/main.c demo/events.c demo/urls.c ) - -set ( META_FILES README.md LICENSE.md AUTHORS.md) - -#if( DEFINED WITH_TEMPLIGHT ) -# set(SOURCE_FILES ${SOURCE_FILES} ${SOURCES_DIR}/templight.c) -# add_definitions( -DWITH_TEMPLIGHT ) -#endif() - -#if( DEFINED WITH_OPTIONS ) -# set(SOURCE_FILES ${SOURCE_FILES} ${SOURCES_DIR}/options.c) -# add_definitions( -DWITH_OPTIONS ) -#endif() - -#if( DEFINED WITH_CONFIG ) -# set(SOURCE_FILES ${SOURCE_FILES} ${SOURCES_DIR}/config.c) -# add_definitions( -DWITH_CONFIG ) -#endif() - -find_package(OpenSSL) - -include_directories( - ${OPENSSL_INCLUDE_DIRS} -) - -link_directories( - ${OPENSSL_LIBRARY_DIRS} -) - -# Library ---------------------------------------------------------------------- - -add_library(${LIBRARY_NAME} SHARED ${LIBRARY_SOURCES}) - -# Demos ------------------------------------------------------------------------ - -#add_executable(${DEMO_NAME} ${DEMO_SOURCES}) - -#target_link_libraries(${DEMO_NAME} ${LIBRARY_NAME}) -target_link_libraries(${LIBRARY_NAME} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) - -# Installation ---------------------------------------------------------------- - -install( - TARGETS ${LIBRARY_NAME} - DESTINATION ${CMAKE_INSTALL_LIBDIR} -) -# ${LIB_INSTALL_DIR} - -#install( -# FILES ${META_FILES} -# DESTINATION ${SHARE_INSTALL_PREFIX}/doc/packages/${LIBRARY_NAME}/ -#) - -install( - DIRECTORY ${INCLUDE_DIR}/${LIBRARY_NAME} - DESTINATION ${INCLUDE_INSTALL_DIR} -) - - diff --git a/aisl.proj b/aisl.proj deleted file mode 100644 index 4853133..0000000 --- a/aisl.proj +++ /dev/null @@ -1,36 +0,0 @@ -name = AISL -todo = aisl.todo -handbook = handbook.md -version: - major = 0 - minor = 0 - -include = -definitions = - -profile: - name = debug - flags = -Wall -Werror - definitions = - -profile: - name = release - flags = - definitions = - - - -library: - output = aisl - compiler = gcc - - version: - major = $version.major - minor = $version.minor - tweak = 0 - build = auto - - sources = library/aisl.c, - library/buffer.c - - diff --git a/cStuff b/cStuff deleted file mode 160000 index a423fa7..0000000 --- a/cStuff +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a423fa7a6dfbd637f3c0b248123f682456fccad7 diff --git a/cmake.compiler b/cmake.compiler deleted file mode 100755 index 3680029..0000000 --- a/cmake.compiler +++ /dev/null @@ -1,7 +0,0 @@ - -if(DEFINED CMAKE_DEBUG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror ") - add_definitions( - -DDEBUG - ) -endif() diff --git a/cmake.paths b/cmake.paths deleted file mode 100644 index b0b055d..0000000 --- a/cmake.paths +++ /dev/null @@ -1,90 +0,0 @@ -# Paths ----------------------------------------------------------------------- - -# Constants ------------------------------------------------------------------- - -set(INCLUDE_DIR "include") -set(BUILD_DIR "build") - -# CMAKE installation paths ---------------------------------------------------- - - -# -DCMAKE_INSTALL_PREFIX:PATH=/usr - -if(NOT DEFINED CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX "/usr") -endif() - - -# -DINCLUDE_INSTALL_DIR:PATH=/usr/include - -if(NOT DEFINED INCLUDE_INSTALL_DIR) - set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include") -endif() - - -# -DSHARE_INSTALL_PREFIX:PATH=/usr/share - -if(NOT DEFINED SHARE_INSTALL_PREFIX) - set(SHARE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share") -endif() - - -# -DSYSCONF_INSTALL_DIR:PATH=/etc - -if(NOT DEFINED SYSCONF_INSTALL_DIR) - set(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc") -endif() - - -# -DCMAKE_INSTALL_LIBDIR:PATH=lib64 - -if(NOT DEFINED CMAKE_INSTALL_LIBDIR) - set(CMAKE_INSTALL_LIBDIR "lib${SYSTEM_LIB_SUFFIX}") -endif() - -# -DLIB_INSTALL_DIR:PATH=/usr/lib64 -if(NOT DEFINED LIB_INSTALL_DIR) - set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") -endif() - - -# ----------------------------------------------------------------------------- - -set(PATH_BIN "${CMAKE_INSTALL_PREFIX}/bin") -set(PATH_INC "${INCLUDE_INSTALL_DIR}") -set(PATH_CFG "${SYSCONF_INSTALL_DIR}") -set(PATH_RUN "/var/run") -set(PATH_LIB "${LIB_INSTALL_DIR}") -set(PATH_LOG "/var/log") -set(PATH_RES "${SHARE_INSTALL_PREFIX}") -set(PATH_LNG "${SHARE_INSTALL_PREFIX}/locale") - - - -MESSAGE( STATUS "Paths:") -MESSAGE( STATUS " Prefix: ${CMAKE_INSTALL_PREFIX}" ) -MESSAGE( STATUS " Binaries: ${PATH_BIN}" ) -MESSAGE( STATUS " Configuration: ${PATH_CFG}" ) -MESSAGE( STATUS " Libraries: ${PATH_LIB}" ) -MESSAGE( STATUS " Includes: ${PATH_INC}" ) -MESSAGE( STATUS " Run: ${PATH_RUN}" ) -MESSAGE( STATUS " Log Files: ${PATH_LOG}" ) -MESSAGE( STATUS " Resources: ${PATH_RES}" ) -MESSAGE( STATUS " Locale Files: ${PATH_LNG}" ) -MESSAGE( STATUS "") - -# Compiler's Definitions ------------------------------------------------------ - -add_definitions( - -DPREFIX="${CMAKE_INSTALL_PREFIX}" - -DPATH_BIN="${PATH_BIN}" - -DPATH_CFG="${PATH_CFG}" - -DPATH_INC="${PATH_INC}" - -DPATH_LIB="${PATH_LIB}" - -DPATH_RUN="${PATH_RUN}" - -DPATH_LOG="${PATH_LOG}" - -DPATH_LNG="${PATH_LNG}" - -DPATH_RES="${PATH_RES}" -) - -# ----------------------------------------------------------------------------- diff --git a/cmake.system b/cmake.system deleted file mode 100644 index aeb769f..0000000 --- a/cmake.system +++ /dev/null @@ -1,18 +0,0 @@ -# Architecture ---------------------------------------------------------------- - -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(SYSTEM_BITNESS 64) - set(SYSTEM_ARCH "amd64") - set(SYSTEM_LIB_SUFFIX "64") -else() - set(SYSTEM_BITNESS 32) - set(SYSTEM_ARCH "x86") - set(SYSTEM_LIB_SUFFIX "") -endif() - -add_definitions( - -DSYSTEM_NAME="${CMAKE_SYSTEM_NAME}" - -DSYSTEM_BITNESS=${SYSTEM_BITNESS} - -DSYSTEM_ARCH_${SYSTEM_ARCH} - -DSYSTEM_ARCH="${SYSTEM_ARCH}" -) diff --git a/cmake.version b/cmake.version deleted file mode 100644 index 5a89fc5..0000000 --- a/cmake.version +++ /dev/null @@ -1,61 +0,0 @@ -# ----------------------------------------------------------------------------- -# -# CMake module for paths generation in DEBUG and RELEASE modes -# -# (c) Copyright Löwenware Ltd. (https://lowenware.com/) -# -# ----------------------------------------------------------------------------- - - -## Constants -set (VERSION_FILE "version") -set ( - VERSION_REGEX - "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-(pre|alpha|beta|rc|release))?" -) - -# Read file -file (READ ${VERSION_FILE} VERSION_STRING) - -# Match file content -string(REGEX MATCH ${VERSION_REGEX} VERSION_STRING ${VERSION_STRING} ) - -# Set Version constants -set (VERSION_MAJOR ${CMAKE_MATCH_1}) -set (VERSION_MINOR ${CMAKE_MATCH_2}) -set (VERSION_TWEAK ${CMAKE_MATCH_3}) - -if (CMAKE_MATCH_5 STREQUAL "pre") - set(VERSION_CYCLE 1) -elseif (CMAKE_MATCH_5 STREQUAL "alpha") - set (VERSION_CYCLE 2) -elseif (CMAKE_MATCH_5 STREQUAL "beta") - set (VERSION_CYCLE 3) -elseif (CMAKE_MATCH_5 STREQUAL "rc") - set (VERSION_CYCLE 4) -else() - set (VERSION_CYCLE 0) -endif() - -set (VERSION_LABEL ${CMAKE_MATCH_4}) - -# Add compiler macros - -add_definitions( - -DVERSION_MAJOR=${VERSION_MAJOR} - -DVERSION_MINOR=${VERSION_MINOR} - -DVERSION_TWEAK=${VERSION_TWEAK} - -DVERSION_CYCLE=${VERSION_CYCLE} - -DVERSION_LABEL="${VERSION_LABEL}" -) - -#Print output - -MESSAGE( - STATUS "${PROJECT_TITLE} version: " ${VERSION_MAJOR} "." - ${VERSION_MINOR} "." - ${VERSION_TWEAK} "-" - ${VERSION_CYCLE_TEXT} " " - ${VERSION_LABEL} -) - diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..c765c6d --- /dev/null +++ b/config.mk @@ -0,0 +1,26 @@ +# +# config.mk +# Löwenware Makefile Config, 2019-03-02 17:35 +# + +PREFIX = /usr/ + +PKG_CONFIG = pkg-config + +# includes and libs +# INCS = -I$(X11INC) \ +# `$(PKG_CONFIG) --cflags fontconfig` \ +# `$(PKG_CONFIG) --cflags freetype2` + +# LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ +# `$(PKG_CONFIG) --libs fontconfig` \ +# `$(PKG_CONFIG) --libs freetype2` + +# flags +# STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 +# STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) +# STLDFLAGS = $(LIBS) $(LDFLAGS) + + +# vim:ft=make +# diff --git a/include/aisl/aisl.h b/include/aisl/aisl.h index 6e05852..4267256 100644 --- a/include/aisl/aisl.h +++ b/include/aisl/aisl.h @@ -1,107 +1,40 @@ -/* ---------------------------------------------------------------------------- - * aisl.h - header file for AISL library, part of AISLing Technology +/* + * * - * Copyright (c) 2017 by Löwenware Ltd. (https://lowenware.com/) + * Copyright (c) 2017-2019 by Löwenware Ltd. * - * Authors and maintainers: - * Ilja Kartaschoff + * Project homepage: https://lowenware.com/aisl/ * - * DOCUMENTATION - * This file is not designed to be used as a documentation, but for looking at - * the precise values of constants and definitions. - * Please, for documentation refer to web page https://lowenware.com/aisling/ or - * file READEME.md from library source package. - * - * LICENSE and DISCLAIMER - * - * -------------------------------------------------------------------------- */ + */ -#ifndef _AISL_H_ -#define _AISL_H_ +#ifndef AISL_H_17EF1616_A00F_49C9_92B6_273AB13BF279 +#define AISL_H_17EF1616_A00F_49C9_92B6_273AB13BF279 -/* system includes ---------------------------------------------------------- */ - -#include -#include -#include -#include - -/* aisl includes ------------------------------------------------------------ */ +/* AISL configuration structure */ +#include +/* AISL status codes and utilities */ #include + +/* AISL callbacks definitions */ +#include + +/* AISL events enumeration and utilities*/ #include + +/* AISL instancing, initialization and processing */ +#include + +/* Embedded HTTP(s) servers */ +#include + +/* HTTP(s) clients */ +#include + +/* HTTP(s) streaming */ #include -#include + +/* HTTP constants and utilities */ #include - - -/* Control calls ------------------------------------------------------------ */ - -/* DEPRECATED, use aisl_handle_new instead - * */ -aisl_status_t -aisl_init(); - -/* DEPRECATED, use aisl_handle_free instead - * */ -void -aisl_release(); - -/* Tell library what socket should be opened. Could be called multiple times. - * This function only save passed data. In fact, sockets are being opened only - * inside aisl_run loop. - * @address : host or IP to listen - * @port : port to listen - * */ - -aisl_status_t -aisl_select(const char *address, int port); - -/* Start main loop - * @result : exit code - * */ -aisl_status_t -aisl_run( int * flags ); - -/* Event calls -------------------------------------------------------------- */ - -/* Add callback to be executed after timeout. If callback function will return - * true, callback will be kept in main loop and raised again, otherwise it will - * be removed - * @cb : callback function: bool callback (void * u_data) - * @usec : delay in milliseconds - * @data : user-defined data to be passed to callback - * */ -aisl_status_t -aisl_delay(aisl_callback_t cb, uint32_t msec, void *u_data); - -/* Add event listener - * @source : pointer to event source - * @e_id : event identifier - * @cb : callback to be executed - * */ -aisl_status_t -aisl_listen(void *source, aisl_event_t e_id, aisl_callback_t cb); - -/* Raise event - * @source : pointer to event source data - * @e_id : event identifier - * @... : custom event data - * @result : true if event was handled, false otherwise - * */ -bool -aisl_raise(void *source, aisl_event_t e_id, ... ); - -/* input stream functions --------------------------------------------------- */ - - -const char * -aisl_header_get(aisl_stream_t stream, const char *key); - -const char * -aisl_header_get_by_index(aisl_stream_t stream, const char **key, uint32_t i); - -/* -------------------------------------------------------------------------- */ - -#endif +#endif /* !AISL_H */ diff --git a/include/aisl/callback.h b/include/aisl/callback.h new file mode 100644 index 0000000..97f128b --- /dev/null +++ b/include/aisl/callback.h @@ -0,0 +1,76 @@ +/* + * + * + * Copyright (c) 2017 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#ifndef AISL_CALLBACK_H_E99458C9_CCAA_4CAC_97F8_41E8869EE26F +#define AISL_CALLBACK_H_E99458C9_CCAA_4CAC_97F8_41E8869EE26F + +#include +#include +#include + +#include +#include +#include +#include + +#define AISL_CALLBACK(x) ((aisl_callback_t) x) + + +/* void-type callback */ +typedef void +(* aisl_callback_t) (void); + + +/* real type callbacks */ + +typedef bool +(*aisl_server_open_t)( aisl_server_t server, int flags ); + +typedef bool +(*aisl_server_error_t)( aisl_server_t server, int flags, const char * details ); + +typedef bool +(*aisl_client_connect_t)( aisl_server_t server, aisl_client_t client ); + +typedef bool +(*aisl_client_disconnect_t)( aisl_server_t server, aisl_client_t client ); + +typedef bool +(*aisl_client_timeout_t)( aisl_server_t server, aisl_client_t client ); + +typedef bool +(*aisl_stream_open_t)( aisl_stream_t stream, + aisl_http_method_t method, + const char * path, + const char * query ); + +typedef bool +(*aisl_stream_header_t)( aisl_stream_t stream, + const char * key, + const char * val ); + +typedef bool +(*aisl_stream_input_t)( aisl_stream_t stream, char * data, int len ); + +typedef bool +(*aisl_stream_request_t)( aisl_stream_t stream ); + +typedef bool +(*aisl_stream_output_t)( aisl_stream_t stream, uint32_t buffer_space ); + +typedef bool +(*aisl_stream_close_t)( aisl_stream_t stream ); + +typedef bool +(*aisl_stream_error_t)( aisl_stream_t stream, const char * details ); + +typedef bool +(*aisl_custom_event_t)( void * source, va_list vl ); + +#endif /* !AISL_CALLBACK_H */ diff --git a/include/aisl/client.h b/include/aisl/client.h new file mode 100644 index 0000000..2016132 --- /dev/null +++ b/include/aisl/client.h @@ -0,0 +1,15 @@ +/* + * + * + * Copyright (c) 2017-2019 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#ifndef AISL_CLIENT_H_A6C37DCF_2183_4F22_A5A0_668311757A08 +#define AISL_CLIENT_H_A6C37DCF_2183_4F22_A5A0_668311757A08 + +typedef struct aisl_client * aisl_client_t; + +#endif /* !AISL_CLIENT_H */ diff --git a/include/aisl/config.h b/include/aisl/config.h new file mode 100644 index 0000000..9643c71 --- /dev/null +++ b/include/aisl/config.h @@ -0,0 +1,28 @@ +/* + * + * + * Copyright (c) 2017-2019 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#ifndef AISL_CONFIG_H_DB67A89B_5CAF_4A5F_AEB1_6DB9F84827D6 +#define AISL_CONFIG_H_DB67A89B_5CAF_4A5F_AEB1_6DB9F84827D6 + +#include + + +struct aisl_config +{ + uint32_t servers_spool_size; + uint32_t clients_spool_size; + uint32_t ssl_spool_size; + uint32_t events_spool_size; + uint32_t initial_buffer_size; + uint32_t clients_accept_limit; +}; + +typedef struct aisl_config * aisl_config_t; + +#endif /* !AISL_CONFIG_H */ diff --git a/include/aisl/event.h b/include/aisl/event.h index 476ddf8..2d9852b 100644 --- a/include/aisl/event.h +++ b/include/aisl/event.h @@ -1,128 +1,42 @@ -#ifndef _AISL_EVENT_H_ -#define _AISL_EVENT_H_ +/* + * + * + * Copyright (c) 2017 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ -#include -#include -#include -#include -#include -#include +#ifndef AISL_EVENT_H_E99458C9_CCAA_4CAC_97F8_41E8869EE26F +#define AISL_EVENT_H_E99458C9_CCAA_4CAC_97F8_41E8869EE26F -/* -------------------------------------------------------------------------- */ +#include -typedef unsigned int aisl_event_t; -/* -------------------------------------------------------------------------- */ - -typedef enum +enum { - AISL_SERVER_OPEN = 100, - AISL_SERVER_ERROR = 190, + AISL_SERVER_OPEN = 100 + , AISL_SERVER_ERROR = 190 - AISL_CLIENT_CONNECT = 200, - AISL_CLIENT_DISCONNECT = 210, - AISL_CLIENT_TIMEOUT = 220, + , AISL_CLIENT_CONNECT = 200 + , AISL_CLIENT_DISCONNECT = 210 + , AISL_CLIENT_TIMEOUT = 220 - AISL_STREAM_OPEN = 300, /* 5 - headers recieved */ - AISL_STREAM_HEADER = 310, /* 5 - headers recieved */ - AISL_STREAM_INPUT = 320, /* 6 - chunk of data transmission */ - AISL_STREAM_REQUEST = 330, /* 7 - data received, response required */ - AISL_STREAM_OUTPUT = 340,/* event for long-size responses optimal handling */ - AISL_STREAM_CLOSE = 350, - AISL_STREAM_ERROR = 390, /* 8 - bad request */ + , AISL_STREAM_OPEN = 300 + , AISL_STREAM_HEADER = 310 + , AISL_STREAM_INPUT = 320 + , AISL_STREAM_REQUEST = 330 + , AISL_STREAM_OUTPUT = 340 + , AISL_STREAM_CLOSE = 350 + , AISL_STREAM_ERROR = 390 - AISL_EVENTS_CUSTOM = 999 + , AISL_EVENTS_CUSTOM = 1000 -} aisl_event_id_t; +}; +typedef uint32_t aisl_event_t; -/* -------------------------------------------------------------------------- */ - -/* AISL_SERVER_OPEN event handler */ -typedef bool -(*aisl_server_open_t)( aisl_server_t server, - int flags ); - -/* AISL_SERVER_ERROR event handler */ -typedef bool -(*aisl_server_error_t)( aisl_server_t server, - int flags, - const char * details ); - -/* AISL_CLIENT_CONNECT event handler */ -typedef bool -(*aisl_client_connect_t)( aisl_server_t server, - aisl_client_t client ); - -/* AISL_CLIENT_DISCONNECT event handler */ -typedef bool -(*aisl_client_disconnect_t)( aisl_server_t server, - aisl_client_t client ); - -/* AISL_CLIENT_DISCONNECT event handler */ -typedef bool -(*aisl_client_timeout_t)( aisl_server_t server, - aisl_client_t client ); - -/* AISL_STREAM_OPEN event handler */ -typedef bool -(*aisl_stream_open_t)( aisl_stream_t s, - aisl_http_method_t method, - const char * path, - const char * query ); - -typedef bool -(*aisl_stream_header_t)( aisl_stream_t s, - const char * key, - const char * value ); - - -/* AISL_STREAM_INPUT event handler */ -typedef bool -(*aisl_stream_input_t)( aisl_stream_t s, - char * data, - int len ); - -/* AISL_STREAM_REQUEST event handler */ -typedef bool -(*aisl_stream_request_t)( aisl_stream_t s ); - -/* AISL_STREAM_OUTPUT event handler */ -typedef bool -(*aisl_stream_output_t)( aisl_stream_t s, - uint32_t buffer_space ); - -typedef bool -(*aisl_stream_close_t)( aisl_stream_t s ); - -/* AISL_STREAM_ERROR event handler */ -typedef bool -(*aisl_stream_error_t)( aisl_stream_t s, - const char * details ); - -/* CUSTOM event_handler */ -typedef bool -(*aisl_custom_event_t)( void * source, - va_list vl ); - -/* on delay timeout */ -typedef bool -(*aisl_delay_timeout_t)( void * u_data ); - -/* -------------------------------------------------------------------------- */ - -/* type for event callbacks to use in structures and function prototypes */ -typedef bool -(* aisl_callback_t) (void); - -/* cast callback as aisl_callback_t */ -#define AISL_CALLBACK(x) ((aisl_callback_t) x) - -/* -------------------------------------------------------------------------- */ const char * -aisl_event_get_text( aisl_event_t e_id ); +aisl_event_get_text( aisl_event_t event ); - -/* -------------------------------------------------------------------------- */ - -#endif +#endif /* !AISL_EVENT_H */ diff --git a/include/aisl/handle.h b/include/aisl/handle.h deleted file mode 100644 index 29d9f09..0000000 --- a/include/aisl/handle.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _AISL_HANDLE_H_ -#define _AISL_HANDLE_H_ - -#include -#include - -/* -------------------------------------------------------------------------- */ - -#define AISL_FLAG_SSL (1<<0) - -/* -------------------------------------------------------------------------- */ - -typedef struct aisl_handle * aisl_handle_t; - - -/* -------------------------------------------------------------------------- */ - -aisl_handle_t -aisl_handle_new(size_t min_clients, size_t buffer_size); - -/* -------------------------------------------------------------------------- */ - -aisl_handle_t -aisl_handle_from_stream( aisl_stream_t s ); - -/* -------------------------------------------------------------------------- */ - -void -aisl_handle_free( aisl_handle_t self ); - -/* -------------------------------------------------------------------------- */ - -aisl_status_t -aisl_bind( aisl_handle_t self, const char * address, int port, int flags ); - -/* -------------------------------------------------------------------------- */ - -aisl_status_t -aisl_set_ssl( aisl_handle_t self, const char * server_name, - const char * key_file, - const char * crt_file ); - -/* -------------------------------------------------------------------------- */ - -aisl_status_t -aisl_set_callback( aisl_handle_t self, - void * source, - aisl_event_t e_id, - aisl_callback_t cb ); - -/* -------------------------------------------------------------------------- */ - -bool -aisl_raise_event( aisl_handle_t self, - void * source, - aisl_event_t e_id, - ... ); - -/* -------------------------------------------------------------------------- */ - -aisl_status_t -aisl_run_cycle( aisl_handle_t self ); - -/* -------------------------------------------------------------------------- */ - -const char * -aisl_handle_get_error( aisl_handle_t self ); - -/* -------------------------------------------------------------------------- */ - -int -aisl_sleep( aisl_handle_t self, unsigned long usec ); - -/* -------------------------------------------------------------------------- */ - -#endif diff --git a/include/aisl/http.h b/include/aisl/http.h index 432492f..1260eaf 100644 --- a/include/aisl/http.h +++ b/include/aisl/http.h @@ -1,104 +1,104 @@ -#ifndef _AISL_HTTP_H_ -#define _AISL_HTTP_H_ +/* + * aisl/http.h + * + * Copyright (c) 2017 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#ifndef AISL_HTTP_H_2BB40A17_5EB3_438B_8A98_EB3C68BA3A45 +#define AISL_HTTP_H_2BB40A17_5EB3_438B_8A98_EB3C68BA3A45 -/* -------------------------------------------------------------------------- */ typedef enum { - AISL_HTTP_1_0, - AISL_HTTP_1_1, - AISL_HTTP_2_0 + AISL_HTTP_1_0 + , AISL_HTTP_1_1 + , AISL_HTTP_2_0 } aisl_http_version_t; -/* -------------------------------------------------------------------------- */ +typedef enum +{ + AISL_HTTP_GET + , AISL_HTTP_PUT + , AISL_HTTP_POST + , AISL_HTTP_HEAD + , AISL_HTTP_TRACE + , AISL_HTTP_DELETE + , AISL_HTTP_OPTIONS + , AISL_HTTP_CONNECT -typedef enum { - AISL_HTTP_GET, - AISL_HTTP_PUT, - AISL_HTTP_POST, - AISL_HTTP_HEAD, - AISL_HTTP_TRACE, - AISL_HTTP_DELETE, - AISL_HTTP_OPTIONS, - AISL_HTTP_CONNECT, - - AISL_HTTP_PRI + , AISL_HTTP_PRI } aisl_http_method_t; -/* -------------------------------------------------------------------------- */ - typedef enum { - /* informational ------------------------------ */ - AISL_HTTP_CONTINUE = 100, - AISL_HTTP_SWITCHING_PROTOCOLS, - /* Successful --------------------------------- */ - AISL_HTTP_OK = 200, - AISL_HTTP_CREATED, - AISL_HTTP_ACCEPTED, - AISL_HTTP_NON_AUTHORITATIVE_INFORMATION, - AISL_HTTP_NO_CONTENT, - AISL_HTTP_RESET_CONTENT, - AISL_HTTP_PARTIAL_CONTENT, - /* redirection -------------------------------- */ - AISL_HTTP_MULTIPLE_CHOICES = 300, - AISL_HTTP_MOVED_PERMANENTLY, - AISL_HTTP_FOUND, - AISL_HTTP_SEE_OTHER, - AISL_HTTP_NOT_MODIFIED, - AISL_HTTP_USE_PROXY, - AISL_HTTP_UNUSED, - AISL_HTTP_TEMPORARY_REDIRECT, - /* client error ------------------------------- */ - AISL_HTTP_BAD_REQUEST = 400, - AISL_HTTP_UNAUTHORIZED, - AISL_HTTP_PAYMENT_REQUIRED, - AISL_HTTP_FORBIDDEN, - AISL_HTTP_NOT_FOUND, - AISL_HTTP_METHOD_NOT_ALLOWED, - AISL_HTTP_NOT_ACCEPTABLE, - AISL_HTTP_PROXY_AUTHENTICATION_REQUIRED, - AISL_HTTP_REQUEST_TIMEOUT, - AISL_HTTP_CONFLICT, - AISL_HTTP_GONE, - AISL_HTTP_LENGTH_REQUIRED, - AISL_HTTP_PRECONDITION_FAILED, - AISL_HTTP_REQUEST_ENTITY_TOO_LARGE, - AISL_HTTP_REQUEST_URI_TOO_LONG, - AISL_HTTP_UNSUPPORTED_MEDIA_TYPE, - AISL_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE, - AISL_HTTP_EXPECTATION_FAILED, - /* server error ------------------------------- */ - AISL_HTTP_INTERNAL_SERVER_ERROR = 500, - AISL_HTTP_NOT_IMPLEMENTED, - AISL_HTTP_BAD_GATEWAY, - AISL_HTTP_SERVICE_UNAVAILABLE, - AISL_HTTP_GATEWAY_TIMEOUT, - AISL_HTTP_VERSION_NOT_SUPPORTED + AISL_HTTP_CONTINUE = 100 + , AISL_HTTP_SWITCHING_PROTOCOLS + + , AISL_HTTP_OK = 200 + , AISL_HTTP_CREATED + , AISL_HTTP_ACCEPTED + , AISL_HTTP_NON_AUTHORITATIVE_INFORMATION + , AISL_HTTP_NO_CONTENT + , AISL_HTTP_RESET_CONTENT + , AISL_HTTP_PARTIAL_CONTENT + + , AISL_HTTP_MULTIPLE_CHOICES = 300 + , AISL_HTTP_MOVED_PERMANENTLY + , AISL_HTTP_FOUND + , AISL_HTTP_SEE_OTHER + , AISL_HTTP_NOT_MODIFIED + , AISL_HTTP_USE_PROXY + , AISL_HTTP_UNUSED + , AISL_HTTP_TEMPORARY_REDIRECT + + , AISL_HTTP_BAD_REQUEST = 400 + , AISL_HTTP_UNAUTHORIZED + , AISL_HTTP_PAYMENT_REQUIRED + , AISL_HTTP_FORBIDDEN + , AISL_HTTP_NOT_FOUND + , AISL_HTTP_METHOD_NOT_ALLOWED + , AISL_HTTP_NOT_ACCEPTABLE + , AISL_HTTP_PROXY_AUTHENTICATION_REQUIRED + , AISL_HTTP_REQUEST_TIMEOUT + , AISL_HTTP_CONFLICT + , AISL_HTTP_GONE + , AISL_HTTP_LENGTH_REQUIRED + , AISL_HTTP_PRECONDITION_FAILED + , AISL_HTTP_REQUEST_ENTITY_TOO_LARGE + , AISL_HTTP_REQUEST_URI_TOO_LONG + , AISL_HTTP_UNSUPPORTED_MEDIA_TYPE + , AISL_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE + , AISL_HTTP_EXPECTATION_FAILED + + , AISL_HTTP_INTERNAL_SERVER_ERROR = 500 + , AISL_HTTP_NOT_IMPLEMENTED + , AISL_HTTP_BAD_GATEWAY + , AISL_HTTP_SERVICE_UNAVAILABLE + , AISL_HTTP_GATEWAY_TIMEOUT + , AISL_HTTP_VERSION_NOT_SUPPORTED } aisl_http_response_t; -/* -------------------------------------------------------------------------- */ + const char * -aisl_http_version_to_string(aisl_http_version_t version); +aisl_http_version_to_string( aisl_http_version_t version ); -/* -------------------------------------------------------------------------- */ const char * -aisl_http_response_to_string(aisl_http_response_t code); +aisl_http_response_to_string( aisl_http_response_t code ); -/* -------------------------------------------------------------------------- */ const char * aisl_http_secure_to_string( int is_secure ); -/* -------------------------------------------------------------------------- */ const char * aisl_http_method_to_string( aisl_http_method_t method ); -/* -------------------------------------------------------------------------- */ -#endif +#endif /* !AISL_HTTP_H */ diff --git a/include/aisl/instance.h b/include/aisl/instance.h new file mode 100644 index 0000000..584d273 --- /dev/null +++ b/include/aisl/instance.h @@ -0,0 +1,75 @@ +/* + * + * + * Copyright (c) 2017-2019 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#ifndef INSTANCE_H_60576F41_454C_4189_B91A_F40501132230 +#define INSTANCE_H_60576F41_454C_4189_B91A_F40501132230 + +#include +#include + + +typedef struct aisl_instance * aisl_instance_t; + + +/* Initialization functions */ + +aisl_instance_t +aisl_new( aisl_config_t * config ); + + +void +aisl_free( aisl_instance_t instance ); + + +aisl_server_t +aisl_listen( aisl_instance_t instance, + const char * address, + uint16_t port ); + + +#ifdef AISL_WITH_SSL + +aisl_status_t +aisl_set_ssl( aisl_instance_t instance, + const char * hostname, + const char * key_file, + const char * crt_file ); + +#endif + + +aisl_status_t +aisl_set_callback( aisl_instance_t instance, + void * source, + aisl_event_t e_id, + aisl_callback_t cb ); + + +/* Control functions */ + +aisl_status_t +aisl_run_cycle( aisl_instance_t instance ); + + +const char * +aisl_get_error( aisl_instance_t instance ); + + +aisl_status_t +aisl_sleep( aisl_instance_t instance, uint32_t usec ); + + +aisl_status_t +aisl_raise( aisl_instance_t instance, aisl_event_t event, ...); + + +aisl_status_t +aisl_raisev( aisl_instance_t instance, aisl_event_t event, va_list args); + +#endif /* !INSTANCE_H */ diff --git a/include/aisl/server.h b/include/aisl/server.h new file mode 100644 index 0000000..cc20e47 --- /dev/null +++ b/include/aisl/server.h @@ -0,0 +1,24 @@ +/* + * + * + * Copyright (c) 2017-2019 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#ifndef AISL_SERVER_H_CC564608_7A05_4B31_9E7E_32750BC60768 +#define AISL_SERVER_H_CC564608_7A05_4B31_9E7E_32750BC60768 + +typedef struct aisl_server * aisl_server_t; + + +#ifdef AISL_WITH_SSL + +aisl_status_t +aisl_server_set_ssl( aisl_server_t server, bool value ); + +#endif + + +#endif /* !AISL_SERVER_H */ diff --git a/include/aisl/status.h b/include/aisl/status.h index bcc4428..34e0e33 100644 --- a/include/aisl/status.h +++ b/include/aisl/status.h @@ -1,24 +1,29 @@ -#ifndef _AISL_STATUS_H_ -#define _AISL_STATUS_H_ +/* + * + * + * Copyright (c) 2017 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ -/* -------------------------------------------------------------------------- */ +#ifndef AISL_STATUS_H_BF7E4434_A711_4D7C_B3AE_1BA2E1A020EF +#define AISL_STATUS_H_BF7E4434_A711_4D7C_B3AE_1BA2E1A020EF -typedef enum { - AISL_EXTCALL_ERROR = -3, - AISL_SYSCALL_ERROR = -2, - AISL_MALLOC_ERROR = -1, +typedef enum +{ + AISL_EXTCALL_ERROR = -3 + , AISL_SYSCALL_ERROR = -2 + , AISL_MALLOC_ERROR = -1 - AISL_SUCCESS = 0, - AISL_IDLE = 1 + , AISL_SUCCESS = 0 + , AISL_IDLE = 1 } aisl_status_t; -/* -------------------------------------------------------------------------- */ const char * aisl_status_to_string(aisl_status_t status); -/* -------------------------------------------------------------------------- */ - -#endif +#endif /* !AISL_STATUS_H */ diff --git a/include/aisl/stream.h b/include/aisl/stream.h index 7bcaf3c..bb7822b 100644 --- a/include/aisl/stream.h +++ b/include/aisl/stream.h @@ -1,172 +1,104 @@ -#ifndef _AISL_STREAM_H_ -#define _AISL_STREAM_H_ +/* + * + * + * Copyright (c) 2017-2019 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ -#include -/* Library statuses */ -/* HTTP requests */ -#include -#include +#ifndef STREAM_H_4D8EB622_3CE0_4F1B_AC1F_B27CCB5C2EDC +#define STREAM_H_4D8EB622_3CE0_4F1B_AC1F_B27CCB5C2EDC -/* -------------------------------------------------------------------------- */ - -typedef struct sockaddr_in * aisl_server_t; -typedef struct sockaddr_in * aisl_client_t; - -struct aisl_stream -{ - /* DO NOT USE PROPERTIES DIRECTLY IN NEW CODE */ - - struct sockaddr_in *client; - - const char *host; - const char *path; - const char *query; - const char *scheme; - - void *u_ptr; /* pointer to bind custom data to stream */ - - aisl_http_method_t request_method; -}; - -/* pointer to stream descriptor */ typedef struct aisl_stream * aisl_stream_t; -/* -------------------------------------------------------------------------- */ -/* start response to client - * this function should be called before any header or content function - * necessary protocol headers as well as Content-Type and Content-Length - * will be set automaticaly - * @stream : stream instance - * @status : HTTP response status code (default 200) - * @content_type : string with content type (default text/html), NULL -> no - * @content_length : length of content, 0 = no content - * */ -aisl_status_t -aisl_response(aisl_stream_t stream, aisl_http_response_t status_code, - const char *content_type, - uint32_t content_length); - -/* send all buffered data to client - * ALL responses should always be finished with calling of this method - * @stream : stream instance - * */ -aisl_status_t -aisl_flush(aisl_stream_t stream); - -/* header functions --------------------------------------------------------- */ - -/* add custom header to stream - * this function should be called before content functions - * @stream : stream instance - * @key : header key string - * @value : header value string - * */ -int -aisl_header(aisl_stream_t stream, const char *key, const char *value); - -/* add custom header to stream - * this function should be called before content functions - * @stream : stream instance - * @key : header key string - * @f_value : value format string, same as for printf function - * @... : arguments according to f_value string - * */ -int -aisl_header_printf(aisl_stream_t stream, const char *key, - const char *f_value, ...); - -/* add custom header to stream - * this function should be called before content functions - * @stream : stream instance - * @key : header key string - * @f_value : value format string, same as for printf function - * @args : arguments macro according to f_value string - * */ -int -aisl_header_vprintf(aisl_stream_t stream, const char *key, - const char *format, - va_list args); - - -/* data response functions -------------------------------------------------- */ - -/* response formated data to client - * @stream : stream instance - * @format : format string, same as for printf - * @... : arguments according to format string - * @result : number of responed bytes - * */ -int -aisl_printf(aisl_stream_t stream, const char *format, ...); - - -/* response formated data to client - * @stream : stream instance - * @format : format string, same as for printf - * @args : arguments macro according to format string - * @result : number of responed bytes - * */ -int -aisl_vprintf(aisl_stream_t stream, const char *format, va_list args); - -/* response characters to client - * @stream : stream instance - * @data : characters to be sent - * @d_len : number of characters to send - * @result : number of responed bytes - * */ -int -aisl_write(aisl_stream_t s, const char *data, int d_len); - -/* response string to client - * @string : string to be sent - * @stream : stream instance - * @result : number of responed bytes - * */ -int -aisl_puts(const char *string, aisl_stream_t stream); - -/* -------------------------------------------------------------------------- */ - -void -aisl_cancel(aisl_stream_t s); - -/* -------------------------------------------------------------------------- */ +/* Stream helpers */ bool -aisl_is_secure(aisl_stream_t s); +aisl_is_secure( aisl_stream_t stream ); -/* -------------------------------------------------------------------------- */ - -void * -aisl_get_context(aisl_stream_t s); - -/* -------------------------------------------------------------------------- */ - -void -aisl_set_context(aisl_stream_t s, void * u_ptr); - -/* -------------------------------------------------------------------------- */ aisl_client_t -aisl_get_client(aisl_stream_t s); +aisl_get_client( aisl_stream_t stream ); -/* -------------------------------------------------------------------------- */ aisl_server_t -aisl_get_server(aisl_stream_t s); +aisl_get_server( aisl_stream_t stream ); - /* -------------------------------------------------------------------------- */ aisl_http_version_t -aisl_get_http_version(aisl_stream_t s); +aisl_get_http_version( aisl_stream_t stream ); + + +aisl_instance_t +aisl_stream_get_instance( aisl_stream_t s ); + + +/* Context functions */ + +void * +aisl_get_context( aisl_stream_t stream ); -/* -------------------------------------------------------------------------- */ void -aisl_reject( aisl_stream_t s); +aisl_set_context( aisl_stream_t stream, void * context ); -/* -------------------------------------------------------------------------- */ -#endif +/* Stream control functions */ + +aisl_status_t +aisl_flush( aisl_stream_t stream ); + + +void +aisl_cancel( aisl_stream_t stream ); + + +void +aisl_reject( aisl_stream_t stream ); + + +/* Response functions */ + +aisl_status_t +aisl_response( aisl_stream_t stream, + aisl_http_response_t status_code, + const char * content_type, + uint32_t content_length); + + +int +aisl_header( aisl_stream_t stream, const char *key, const char *value ); + + +int +aisl_header_printf( aisl_stream_t stream, + const char * key, + const char * format, + ... ); + + +int +aisl_header_vprintf( aisl_stream_t stream, + const char * key, + const char * format, + va_list args ); + + +int +aisl_printf( aisl_stream_t stream, const char * format, ... ); + + +int +aisl_vprintf( aisl_stream_t stream, const char * format, va_list args ); + + +int +aisl_write( aisl_stream_t stream, const char * data, int d_len ); + + +int +aisl_puts( const char * str_data, aisl_stream_t stream ); + +#endif /* !AISL_STREAM_H */ diff --git a/project.sh b/project.sh deleted file mode 100755 index 8a1f6b5..0000000 --- a/project.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash - -# ----------------------------------------------------------------------------- -# -# CMake Wrapper v.1.0 for Linux -# (c) Copyright Löwenware Ltd. (https://lowenware.com/) -# -# ----------------------------------------------------------------------------- - -ABSOLUTE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -PROJECT="aisl" -PROJECT_VERSION=$(cat ${ABSOLUTE_PATH}/version | sed 's/\([0-9]\{1,5\}.[0-9]\{1,5\}.[0-9]\{1,5\}\).*/\1/') - -PREFIX="/usr" -SYSCONF="/etc" -DIR_BUILD="build" -DIR_ROOT="root" - -# ----------------------------------------------------------------------------- - -function project_clean { - echo "Cleaning..." - - if [ -d ./$DIR_BUILD ]; then - rm -Rf ./$DIR_BUILD/* - else - mkdir ./$DIR_BUILD - fi - - if [ -d ./$DIR_ROOT ]; then - rm -Rf ./$DIR_ROOT/* - else - mkdir ./$DIR_ROOT - fi - -} - -# ----------------------------------------------------------------------------- - -function project_compile { - - CMAKE="cmake" - - if [[ "$OSTYPE" == "darwin"* ]]; then - ov="1.0.2n" - ov_p="-DOPENSSL_INCLUDE_DIRS=/usr/local/Cellar/openssl/${ov}/include -DOPENSSL_CRYPTO_LIBRARY=/usr/local/Cellar/openssl/${ov}/lib/libcrypto.dylib -DOPENSSL_SSL_LIBRARY=/usr/local/Cellar/openssl/${ov}/lib/libssl.dylib -DOPENSSL_LIBRARY_DIRS=/usr/local/Cellar/openssl/${ov}/lib" - CMAKE="cmake ${ov_p}" - fi - - echo ${CMAKE} - - ${CMAKE} -B./$DIR_BUILD -H./ -DCMAKE_INSTALL_PREFIX=$PREFIX -DCMAKE_DEBUG=1 - cd $DIR_BUILD/ - make - make DESTDIR=../$DIR_ROOT install - cd .. -} - -# ----------------------------------------------------------------------------- - -case $1 in - clean) - project_clean - ;; - compile) - project_compile - ;; - build) - project_clean - project_compile - ;; - install) - cmake -DWITH_EVERYTHING=1 -B./$DIR_BUILD -H./ -DCMAKE_INSTALL_PREFIX=$PREFIX - cd $DIR_BUILD - sudo make install - cd .. - ;; - deploy) - DEPLOY_PATH="${PROJECT}-${PROJECT_VERSION}" - mkdir ${2}${DEPLOY_PATH} - cp -R ${ABSOLUTE_PATH}/{include,library,LICENSE,AUTHORS,version,README.md,cmake*,CMakeLists.txt,cStuff} ${2}${DEPLOY_PATH} - rm ${2}${DEPLOY_PATH}/cStuff/.git - CUR_DIR=$(pwd) - cd $2 - tar cfz ${DEPLOY_PATH}.tar.gz ${DEPLOY_PATH} - cd $CUR_DIR - rm -Rf ${2}${DEPLOY_PATH} - echo "_version ${PROJECT_VERSION}" - ;; - *) - echo "Usage: ./project.sh (compile|build|clean|install)" - ;; -esac - - -# ----------------------------------------------------------------------------- diff --git a/library/aisl.c b/src/aisl.c similarity index 62% rename from library/aisl.c rename to src/aisl.c index bae54a1..86fd636 100644 --- a/library/aisl.c +++ b/src/aisl.c @@ -7,9 +7,10 @@ #include #include -#include -#include +#include "aisl.h" +#include "list.h" +#include "str-utils.h" #include "handle.h" #include "client.h" #include "server.h" @@ -18,116 +19,131 @@ #include "buffer.h" -/* Globals ------------------------------------------------------------------ */ - -#define AISL_TERMINATED 1 - -aisl_handle_t gHandle = NULL; +struct aisl_instance +{ + list_t * servers; + #ifdef AISL_WITH_SSL + list_t * ssl; + #endif + list_t servers; + list_t clients; + list_t callbacks; + buffer_t buffer; + char * last_error; + int iterator; + int stage; + int flags; + uint32_t accept_limit; +}; -/* DEPRECATED --------------------------------------------------------------- */ +#ifdef AISL_WITH_SSL +static uint32_t m_instances = 0; +#endif + +/* Initialization functions */ __attribute__ ((visibility ("default") )) -aisl_status_t -aisl_init( ) +aisl_t +aisl_new( aisl_config_t * config ) { - gHandle = aisl_handle_new( AISL_MIN_CLIENTS, AISL_BUFFER_SIZE ); + aisl_t self; - return (gHandle != NULL) ? AISL_SUCCESS : AISL_MALLOC_ERROR; + #ifdef AISL_WITH_SSL + if ((m_instances++) == 0) + { + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); + } + #endif + + if ( !(self = calloc(1, sizeof(struct aisl_instance))) ) + goto finally; + + if ( !(self->servers = list_new(config->servers_spool_size)) ) + goto release; + + if ( !(self->clients = list_new(config->clients_spool_size)) ) + goto release; + + if ( !(self->callbacks = list_new(config->callbacks_spool_size)) ) + goto release; + + if ( !(self->buffer = buffer_new(config->initial_buffer_size)) ) + goto release; + + #ifdef AISL_WITH_SSL + if ( !(self->ssl = list_new(config->ssl_spool_size)) ) + goto release; + #endif + + self->accept_limit = config->clients_accept_limit; + + goto finally; + +release: + aisl_free(self); + self = NULL; + +finally: + return self; } -/* DEPRECATED --------------------------------------------------------------- */ __attribute__ ((visibility ("default") )) void -aisl_release() +aisl_free( aisl_t self ) { - aisl_handle_free(gHandle); -} + if (self->clients) + list_free(self->clients, (list_destructor_t) client_free ); -/* DEPRECATED --------------------------------------------------------------- */ + if (self->servers) + list_free(self->servers, (list_destructor_t) server_free ); -__attribute__ ((visibility ("default") )) -aisl_status_t -aisl_select(const char * address, int port) -{ - return aisl_bind(gHandle, address, port, 0); -} + if (self->callbacks) + list_free(self->callbacks, free); -/* -------------------------------------------------------------------------- */ + if (self->buffer) + buffer_free(self->buffer); -__attribute__ ((visibility ("default") )) -aisl_status_t -aisl_run( int * flags ) -{ - aisl_status_t exit_code = AISL_SUCCESS; - struct timeval timeout = {0,0}; + if (self->ssl) + list_free(self->ssl, (list_destructor_t) crypter_free ); - while( !(*flags & AISL_TERMINATED) ) + if (self->last_error) + free(self->last_error); + + free(self); + + #ifdef AISL_WITH_SSL + if ((--m_instances) == 0) { - if ( (exit_code = aisl_run_cycle( gHandle )) == AISL_IDLE ) - { - timeout.tv_usec = 300; - timeout.tv_sec = 0; + EVP_cleanup(); + } + #endif +} - select(0, NULL, NULL, NULL, &timeout); + +__attribute__ ((visibility ("default") )) +aisl_server_t +aisl_listen( aisl_instance_t instance, + const char * address, + uint16_t port ) +{ + aisl_server_t result; + + if ( (result = aisl_server_new(address, port)) != NULL ) + { + result->instance = instance; + + if (list_append(instance->servers, result) == LIST_NAN) + { + server_free(result); } } - return exit_code; -} - -/* Event calls -------------------------------------------------------------- */ - -__attribute__ ((visibility ("default") )) -aisl_status_t -aisl_delay( aisl_callback_t cb, uint32_t usec, void * u_data ) -{ - return aisl_set_delay(gHandle, cb, usec, u_data); -} - -/* -------------------------------------------------------------------------- */ - -__attribute__ ((visibility ("default") )) -aisl_status_t -aisl_listen( void * source, aisl_event_t e_id, aisl_callback_t cb ) -{ - return aisl_set_callback( gHandle, source, e_id, cb ); -} - -/* -------------------------------------------------------------------------- */ - - -__attribute__ ((visibility ("default") )) -bool -aisl_raise( void *source, aisl_event_t e_id, ... ) -{ - bool result; - va_list vl; - va_start(vl, e_id); - result = aisl_raise_event_vl( gHandle, source, e_id, vl); - va_end(vl); return result; } -__attribute__ ((visibility ("default") )) -const char * -aisl_header_get(aisl_stream_t stream, const char *key) -{ - int i; - if (STREAM(stream)->headers) - { - for (i=0; i< STREAM(stream)->headers->count; i++) - { - if (str_cmpi(((pair_t)list_index(STREAM(stream)->headers,i))->key,key)==0) - return ((pair_t) list_index(STREAM(stream)->headers,i))->value; - } - } - - return NULL; -} - -/* response functions ------------------------------------------------------- */ static char * get_response_begin(stream_t stream) @@ -195,6 +211,7 @@ aisl_response(aisl_stream_t stream, aisl_http_response_t status_code, return AISL_SUCCESS; } + __attribute__ ((visibility ("default") )) aisl_status_t aisl_flush(aisl_stream_t stream) @@ -219,7 +236,6 @@ aisl_flush(aisl_stream_t stream) return AISL_SUCCESS; } -/* header functions --------------------------------------------------------- */ __attribute__ ((visibility ("default") )) int @@ -251,7 +267,6 @@ aisl_header(aisl_stream_t stream, const char *key, const char *value) return ret; } -/* -------------------------------------------------------------------------- */ __attribute__ ((visibility ("default") )) int @@ -270,7 +285,6 @@ aisl_header_printf(aisl_stream_t stream, const char *key, return ret; } -/* -------------------------------------------------------------------------- */ __attribute__ ((visibility ("default") )) int @@ -292,7 +306,6 @@ aisl_header_vprintf(aisl_stream_t stream, const char *key, return ret; } -/* -------------------------------------------------------------------------- */ __attribute__ ((visibility ("default") )) int @@ -316,7 +329,6 @@ aisl_printf(aisl_stream_t stream, const char *format, ...) } -/* -------------------------------------------------------------------------- */ __attribute__ ((visibility ("default") )) int @@ -339,7 +351,6 @@ aisl_vprintf(aisl_stream_t stream, const char *format, va_list args) return result; } -/* -------------------------------------------------------------------------- */ __attribute__ ((visibility ("default") )) int @@ -354,7 +365,6 @@ aisl_write(aisl_stream_t stream, const char *data, int d_len) return d_len; } -/* -------------------------------------------------------------------------- */ __attribute__ ((visibility ("default") )) int @@ -363,5 +373,4 @@ aisl_puts(const char *str, aisl_stream_t stream) return aisl_write( stream, str, strlen(str)); } -/* -------------------------------------------------------------------------- */ diff --git a/src/aisl.h b/src/aisl.h new file mode 100644 index 0000000..7e25bd9 --- /dev/null +++ b/src/aisl.h @@ -0,0 +1,19 @@ +/* + * src/aisl.h + * + * Copyright (c) 2017 by Löwenware Ltd. + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#ifndef AISL_H_F49DC34C_7EF3_44EF_8E4B_22F4CC1A665C +#define AISL_H_F49DC34C_7EF3_44EF_8E4B_22F4CC1A665C + +bool +aisl_raise_event( aisl_instance_t instance, + void * source, + aisl_event_t e_id, + ... ); + +#endif /* !AISL_H */ diff --git a/library/buffer.c b/src/buffer.c similarity index 100% rename from library/buffer.c rename to src/buffer.c diff --git a/library/buffer.h b/src/buffer.h similarity index 97% rename from library/buffer.h rename to src/buffer.h index 72d81d6..9e1fc94 100644 --- a/library/buffer.h +++ b/src/buffer.h @@ -13,7 +13,7 @@ struct buffer typedef struct buffer * buffer_t; -#define BUFFER_EOB ( ~0 ) +#define BUFFER_EOB ( ~0L ) /* -------------------------------------------------------------------------- */ diff --git a/library/client.c b/src/client.c similarity index 100% rename from library/client.c rename to src/client.c diff --git a/library/client.h b/src/client.h similarity index 98% rename from library/client.h rename to src/client.h index 44912ad..dd6d34d 100644 --- a/library/client.h +++ b/src/client.h @@ -6,7 +6,7 @@ #include #include -#include +#include "list.h" #include #include diff --git a/library/event.c b/src/event.c similarity index 100% rename from library/event.c rename to src/event.c diff --git a/library/globals.h b/src/globals.h similarity index 100% rename from library/globals.h rename to src/globals.h diff --git a/library/handle.c b/src/handle.c similarity index 99% rename from library/handle.c rename to src/handle.c index 4f4927f..4d6707c 100644 --- a/library/handle.c +++ b/src/handle.c @@ -1,11 +1,13 @@ #include #include +#include +#include #include #include -#include -#include +#include "str-utils.h" +#include "list.h" #include "stream.h" #include "server.h" #include "client.h" @@ -769,6 +771,9 @@ aisl_sleep( aisl_handle_t self, unsigned long usec ) size_t i; struct timeval timeout = {0,usec}; + memset(&timeout, 0, sizeof(struct timeval)); + timeout.tv_usec = usec; + fd_set fs; FD_ZERO (&fs); diff --git a/library/handle.h b/src/handle.h similarity index 79% rename from library/handle.h rename to src/handle.h index 9b3048b..db66510 100644 --- a/library/handle.h +++ b/src/handle.h @@ -6,7 +6,7 @@ #include -#include +#include "list.h" #include #include "buffer.h" @@ -14,20 +14,6 @@ /* -------------------------------------------------------------------------- */ -struct aisl_handle -{ - list_t servers; - list_t clients; - list_t delays; /* deprecated */ - list_t listeners; - list_t crypters; - buffer_t buffer; - char * lastError; - int iterator; - int stage; - int flags; -}; - /* -------------------------------------------------------------------------- */ diff --git a/library/http.c b/src/http.c similarity index 100% rename from library/http.c rename to src/http.c diff --git a/src/instance.c b/src/instance.c new file mode 100644 index 0000000..40928e9 --- /dev/null +++ b/src/instance.c @@ -0,0 +1,13 @@ +/* + * src/instance.c + * + * Copyright (C) 2019 Ilja Kartašov + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#include "instance.h" + + + diff --git a/src/instance.h b/src/instance.h new file mode 100644 index 0000000..129830a --- /dev/null +++ b/src/instance.h @@ -0,0 +1,16 @@ +/* + * src/instance.h + * + * Copyright (C) 2019 Ilja Kartašov + * + * Project homepage: https://lowenware.com/aisl/ + * + */ + +#ifndef INSTANCE_H_814CF474_A646_45B7_B6B2_3F4C7BEFA484 +#define INSTANCE_H_814CF474_A646_45B7_B6B2_3F4C7BEFA484 + +#include + + +#endif /* !INSTANCE_H */ diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..10b15e7 --- /dev/null +++ b/src/list.c @@ -0,0 +1,201 @@ +/* list.c - code file of the List module + * Copyright (c) 2017 Löwenware Ltd (https://lowenware.com) + * + * REPOSITORY: + * git://lowenware.com:standard.git + * MAINTAINER: + * Ilja Kartaschoff + * + * LICENSE and DISCLAIMER: + * All code stored in standard.git repository is designed to solve + * very common and widely meet development tasks. We are not about to patent + * wheels here, so all code you can find in this repository is FREE: + * you can use, redistribute and/or modify it without any limits or + * restrictions. + * + * All code described above is distributed in hope to be useful for somebody + * else WITHOUT ANY WARRANTY, without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In case of questions or suggestions, feel free to contact maintainer. + * + * */ + +#include +#include +#include +#include "list.h" + +/* -------------------------------------------------------------------------- */ + +list_t +list_new(int size) +{ + list_t self = calloc(1, sizeof(struct list)); + if (self) + { + if (size) + { + self->size = size; + + if ( (self->list = calloc(size, sizeof(void *))) == NULL ) + { + free(self); + self = NULL; + } + } + } + return self; +} + +/* -------------------------------------------------------------------------- */ + +void +list_free(list_t self, list_destructor_t destructor) +{ + int i; + if (self) + { + if (self->list) + { + if (destructor) + { + for(i=0; icount; i++) + { + if (self->list[i]) + destructor(self->list[i]); + } + } + free(self->list); + } + free(self); + } +} + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_LIST_WITH_INSERT + +int +list_insert( list_t self, void * item, int position ) +{ + int r; + + if ( (r = list_append(self, item)) == -1) + return -1; + + if (position >= r || position < 0) + return r; + + memmove( + &self->list[position+1], + &self->list[position], + (self->count-position-1)*sizeof(void*) + ); + + self->list[position] = item; + + return position; +} + + +#endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_LIST_WITH_APPEND + +int +list_append(list_t self, void * item) +{ + void ** new_list; + int new_size = self->count+1; + + + if (new_size > self->size) + { + if ( (new_list = realloc( self->list, new_size*sizeof(void*) )) == NULL ) + return -1; + + + self->list = new_list; + self->size = new_size; + } + + self->list[self->count]=item; + + return self->count++; +} + +#endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_LIST_WITH_REMOVE + +void +list_remove( list_t self, void * item ) +{ + int i; + + for (i=0; icount; i++) + { + if (self->list[i]==item) + { + list_remove_index(self, i); + break; + } + } +} + + +#endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_LIST_WITH_REMOVE_INDEX + +void * +list_remove_index( list_t self, int index ) +{ + void * result; + int i; + + if (index < self->count) + { + result = self->list[index]; + self->count--; + for (i=index; icount; i++) + { + self->list[i]=self->list[i+1]; + } + } + else + result = NULL; + + return result; +} + + + +#endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_LIST_WITH_SET_ITEM + +void +list_set_item(list_t self, int index, void * value) +{ + if (self->size > index) + { + self->list[index] = value; + if (index >= self->count) + self->count = index+1; + + } +} + +#endif + +/* -------------------------------------------------------------------------- */ diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..3ac90e4 --- /dev/null +++ b/src/list.h @@ -0,0 +1,120 @@ +/* list.h - header file of the list_t module + * Copyright (c) 2017 Löwenware Ltd (https://lowenware.com) + * + * REPOSITORY: + * https://github.com/lowenware.com:cStuff.git + * MAINTAINER: + * Ilja Kartaschoff + * + * LICENSE and DISCLAIMER: + * All code stored in this repository is designed to solve + * very common and widely meet development tasks. We are not about to patent + * wheels here, so all code you can find in this repository is FREE: + * you can use, redistribute and/or modify it without any limits or + * restrictions. + * + * All code described above is distributed in hope to be useful for somebody + * else WITHOUT ANY WARRANTY, without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In case of questions or suggestions, feel free to contact maintainer. + * + * */ + +#ifndef _CSTUFF_LIST_H_ +#define _CSTUFF_LIST_H_ + +#include + +/* MODULE: list_t + * Dynamic storage for pointers */ + +/* structure ---------------------------------------------------------------- */ + +struct list +{ + void **list; /* list itself */ + int size; /* number of bytes allocated for list */ + int count; /* number of defined items in list */ +}; + +typedef struct list * list_t; + +/* callback to free memory used by stored item ------------------------------ */ + +typedef void (* list_destructor_t)(void * list_item); + +/* functions ---------------------------------------------------------------- */ + +/* get list item by index macro + * @self : list_t instance + * @index : item index + * @result : stored pointer + * */ +#define list_index(self, index) (self->list[index]) + +/* -------------------------------------------------------------------------- */ + +/* create new list_t object + * @size : initial list size + * @result new list_t instance + * */ +list_t +list_new(int size); + +/* -------------------------------------------------------------------------- */ + +/* free resources allocated for list_t instance + * @self : list_t instance + * @destructor : if set, destructor method will be called for each not-null + * list entry + * */ +void +list_free(list_t self, list_destructor_t destructor); + +/* -------------------------------------------------------------------------- */ + +/* insert new item into list at some position, + * memory will be allocated if necessary + * @self : list_t instance + * @item : pointer to be inserted + * @position : number from 0(prepend) to list size (append) + * */ +int +list_insert( list_t self, void * item, int position ); + +/* append item to queue list + * @self : list_t object + * @item : pointer to be appended + * @result : position at which pointer was stored + * */ +int +list_append(list_t self, void * item); + + +/* remove pointer from list + * @self : list_t object + * @item : to be removed + * */ +void +list_remove( list_t self, void * item ); + + +/* remove pointer from list by index + * @self : list_t object + * @index : index of pointer to be removed + * */ +void * +list_remove_index( list_t self, int index ); + + +/* set pointer by index. if element does not exist, list won't be extended + * @self : list_t object + * @index : index of pointer to be removed + * @value : value to be set + * */ +void +list_set_item(list_t self, int index, void * value); + + +#endif diff --git a/library/parser.c b/src/parser.c similarity index 99% rename from library/parser.c rename to src/parser.c index 78b4372..348e4ad 100644 --- a/library/parser.c +++ b/src/parser.c @@ -3,7 +3,7 @@ #include #include -#include +#include "str-utils.h" #include #include "parser.h" diff --git a/library/parser.h b/src/parser.h similarity index 100% rename from library/parser.h rename to src/parser.h diff --git a/library/server.c b/src/server.c similarity index 98% rename from library/server.c rename to src/server.c index 3d16a8f..20e67d4 100644 --- a/library/server.c +++ b/src/server.c @@ -2,15 +2,16 @@ #include #include #include +#include #include #include -#include #include "server.h" #include "handle.h" #include "client.h" #include "globals.h" +#include "str-utils.h" /* -------------------------------------------------------------------------- */ diff --git a/library/server.h b/src/server.h similarity index 100% rename from library/server.h rename to src/server.h diff --git a/library/status.c b/src/status.c similarity index 100% rename from library/status.c rename to src/status.c diff --git a/src/str-utils.c b/src/str-utils.c new file mode 100644 index 0000000..900b598 --- /dev/null +++ b/src/str-utils.c @@ -0,0 +1,627 @@ +/* str_utils.c - code file of the C string module + * Copyright (c) 2017 Löwenware Ltd (https://lowenware.com) + * + * REPOSITORY: + * git://lowenware.com:standard.git + * MAINTAINER: + * Ilja Kartaschoff + * + * LICENSE and DISCLAIMER: + * All code stored in standard.git repository is designed to solve + * very common and widely meet development tasks. We are not about to patent + * wheels here, so all code you can find in this repository is FREE: + * you can use, redistribute and/or modify it without any limits or + * restrictions. + * + * All code described above is distributed in hope to be useful for somebody + * else WITHOUT ANY WARRANTY, without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In case of questions or suggestions, feel free to contact maintainer. + * + * */ +#include +#include +#include + +#include "str-utils.h" + +#ifndef CSTUFF_TIMESTAMP_FORMAT +#define CSTUFF_TIMESTAMP_FORMAT "%Y-%m-%d %H:%M:%S" +#endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_SET + +char * +str_set(char * dst, const char * src) +{ + int len = (src) ? strlen(src) : 0; + + if (!dst || len > strlen(dst)) + { + char * r; + + if ( (r = realloc( dst, len + 1 )) != NULL ) + { + dst = r; + } + else + return r; + } + + if (len) + strncpy(dst, src, len); + + dst[len]=0; + + return dst; +} + +# endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_COPY + +char * +str_copy(const char * src) +{ + if (!src) return NULL; + + uint32_t s = strlen(src); + char * result = malloc((s+1)*sizeof(char)); + + strcpy(result, src); + + return result; +} + +# endif + + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_NCOPY + +char * +str_ncopy(const char * src, uint32_t s) +{ + if (!src) return NULL; + + char * result = malloc((s+1)*sizeof(char)); + + if (s) + strncpy(result, src, s); + + result[s]=0; + + return result; +} + +# endif +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_PRINTF + +#ifndef CSTUFF_STR_UTILS_WITH_VPRINTF +#define CSTUFF_STR_UTILS_WITH_VPRINTF +#endif + +char * +str_printf(const char * format, ...) +{ + va_list vl; + va_start (vl, format); + char * result = str_vprintf(format, vl); + va_end(vl); + + return result; +} + +# endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_VPRINTF + +char * +str_vprintf(const char * format, va_list vl) +{ + if (!format) return NULL; + + va_list _vl; + va_copy(_vl, vl); + + uint32_t total = 0, + fmt_len = 0; + + char tmp_buffer[64], + tmp_format[64], + * chr_arg; + const char * pch = format; + + + + enum { + wsFormatSearch, + wsFormatFlags, + wsFormatWidth, + wsFormatPrecisionDot, + wsFormatPrecision, + wsFormatLength, + wsFormatSpecifier + }; + + uint32_t stage = wsFormatSearch; + + while(*pch) + { + switch (stage) + { + case wsFormatSearch: + if (*pch=='%') + { + stage = wsFormatFlags; + strcpy(tmp_format, "%"); + fmt_len=1; + } + else + { + total++; + } + pch++; + break; + case wsFormatFlags: + switch (*pch) + { + case '-': + case '+': + case ' ': + case '#': + case '0': + tmp_format[fmt_len]=*pch; + fmt_len++; + pch++; + default: + stage=wsFormatWidth; + } + break; + case wsFormatWidth: + switch (*pch) + { + case '*': + stage=wsFormatPrecisionDot; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tmp_format[fmt_len]=*pch; + fmt_len++; + pch++; + break; + default: + stage=wsFormatPrecisionDot; + } + break; + case wsFormatPrecisionDot: + if (*pch=='.') + { + tmp_format[fmt_len]=*pch; + fmt_len++; + pch++; + stage=wsFormatPrecision; + } + else + stage=wsFormatLength; + break; + case wsFormatPrecision: + switch(*pch) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tmp_format[fmt_len]=*pch; + fmt_len++; + pch++; + break; + default: + stage=wsFormatLength; + } + break; + case wsFormatLength: + switch(*pch) + { + case 'h': + case 'l': + case 'j': + case 'z': + case 't': + case 'L': + tmp_format[fmt_len]=*pch; + fmt_len++; + pch++; + break; + default: + stage=wsFormatSpecifier; + + } + break; + case wsFormatSpecifier: + tmp_format[fmt_len]=*pch; + fmt_len++; + tmp_format[fmt_len]=0; + stage = wsFormatSearch; + + switch (*pch) + { + case '%': + total+=1; + break; + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + case 'f': + case 'F': + case 'e': + case 'E': + case 'g': + case 'G': + case 'a': + case 'A': + case 'c': + case 'p': + case 'n': + vsprintf(tmp_buffer, tmp_format, vl); + total+=strlen(tmp_buffer); + break; + case 's': + chr_arg = va_arg(vl, char*); + total+=chr_arg ? strlen( chr_arg ) : 6; /* (null) */ + break; + default: + fprintf( + stderr, "Warning: " + "bad format specifier (%s)\n", tmp_format + ); + return NULL; + } + pch++; + + break; + } + + } + + char * result = malloc(total+1); + + vsprintf(result, format, _vl); + + va_end(_vl); + + return result; +} + +# endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_CAT + +#ifndef CSTUFF_STR_UTILS_WITH_NCAT +#define CSTUFF_STR_UTILS_WITH_NCAT +#endif + +char * +str_cat(char * source, const char * target) +{ + return str_ncat(source, target, strlen(target)); +} + +# endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_NCAT + +char * +str_ncat(char * source, const char * target, uint32_t length) +{ + char * result = realloc( source, + length + ((source) ? strlen(source) : 0) + 1 + ); + if (result) + { + if (!source) + result[0]=0; + + if (target && length) + strncat(result, target, length); + + } + + return result; +} + +# endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_CMPI + +#include + +int +str_cmpi(const char * source, const char * target) +{ + char r; + while ( *source != 0 && *target != 0 ) + { + r = tolower(*source) - tolower(*target); + if ( r != 0 ) return r; + source++; + target++; + } + + return ( *source == 0 && *target == 0 ) ? 0: -1; +} + +# endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_TO_INT + +int +str_to_int(const char * ptr, int l, int32_t * result) +{ + int64_t b; + int rc = str_to_int64(ptr, l, &b); + + *result = b & 0xFFFFFFFF; + + return rc; +} + +/* -------------------------------------------------------------------------- */ + +int +str_to_int64(const char * ptr, int l, int64_t * result) +{ + int rc; + char * src; + int dest; + + if ( (src = str_ncopy(ptr, l)) != NULL ) + { + char * p; + dest = strtoll(src, &p, 10); + + rc = (p && *p == 0) ? CSTUFF_SUCCESS : CSTUFF_PARSE_ERROR; + + free(src); + } + else + { + dest = 0; + rc = CSTUFF_MALLOC_ERROR; + } + + *result = dest; + + return rc; +} + +#endif + + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_TO_TIMESTAMP + +#include + +int +str_to_timestamp(const char * source, size_t l, time_t * p_ts, const char * tz) +{ + int result; + + if (!tz) + tz = "UTC"; + + if ( ! (l < 19) ) + { + struct tm * tms = calloc(1, sizeof(struct tm)); + if (tms) + { + char * curtz; + + tms->tm_year = strtol(source, NULL, 10) - 1900; + tms->tm_mon = strtol(&source[5], NULL, 10) - 1; + tms->tm_mday = strtol(&source[8], NULL, 10); + tms->tm_hour = strtol(&source[11], NULL, 10); + tms->tm_min = strtol(&source[14], NULL, 10); + tms->tm_sec = strtol(&source[17], NULL, 10); + tms->tm_isdst = -1; + + curtz = getenv("TZ"); + setenv("TZ", tz, 1); + + *p_ts = mktime(tms); + + if (curtz) + setenv("TZ", curtz, 1); + else + putenv("TZ"); + + free(tms); + + result = 0; + } + else + result = -1; + } + else + result = 1; + + return result; +} + +#endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_FROM_TIMESTAMP + +char * +str_from_timestamp_iso_utc(time_t ts) +{ + return str_from_timestamp(ts, CSTUFF_TIMESTAMP_FORMAT, "UTC"); +} + +#endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_FROM_TIMESTAMP_FORMAT + +char * +str_from_timestamp(time_t ts, const char * format, const char * timezone) +{ + char * result; + char * cur_tz; + + if (!format) + format = "%c"; + + if (!timezone) + timezone = "UTC"; + + cur_tz = getenv("TZ"); + setenv("TZ", timezone, 1); + + struct tm * p_tm = localtime(&ts); + + if (cur_tz) + setenv("TZ", cur_tz, 1); + else + putenv("TZ"); + + if ((result = calloc(64, sizeof(char))) != NULL) + { + strftime(result, 64, format, p_tm); + } + + return result; +} + +#endif + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_CHOP + +/* chop spaces from string, return number of prepending spaces */ +uint32_t +str_chop(char * source) +{ + char * p = source; + uint32_t s = 0; + + /* remove ending spaces */ + s = strlen(source); + while (--s) + { + if (source[s] != ' ') break; + source[s] = 0; + } + + s=0; + /* remove prepending spaces */ + while (*p == ' ') s++; + if (s) + strcpy(source, &source[s]); + + return s; + +} + +# endif + +/* -------------------------------------------------------------------------- */ + +#ifdef CSTUFF_STR_UTILS_WITH_REPLACE + +char * +str_replace(const char * haystack, const char * needle, const char * value) +{ + size_t h_len, + n_len = strlen(needle), + v_len, + match = 0; + + char * cur = (char *) haystack, + * ptr, + * result, + * out; + + while ( (ptr = strstr(cur, needle)) != NULL ) + { + cur = (char *)(ptr + n_len); + match++; + } + + if (!match) + return (char*) haystack; + + v_len = strlen(value); + h_len = strlen(haystack) - match * n_len + match * v_len + 1; + + if ((result = calloc(h_len, sizeof(char))) != NULL) + { + cur = (char *) haystack; + out = result; + + while ( (ptr = strstr(cur, needle)) != NULL ) + { + if (cur == haystack && ptr != haystack) + { + strncpy(result, haystack, (int)(ptr-haystack)); + out += (int)(ptr-haystack); + } + + strncpy(out, value, v_len); + + out += v_len; + + cur = (char *)(ptr + n_len); + } + + if (*cur) + strcpy(out, cur); + } + + return result; +} + +# endif + +/* -------------------------------------------------------------------------- */ diff --git a/src/str-utils.h b/src/str-utils.h new file mode 100644 index 0000000..37a1791 --- /dev/null +++ b/src/str-utils.h @@ -0,0 +1,104 @@ +/* str_utils.h - header file of the C string module + * Copyright (c) 2017 Löwenware Ltd (https://lowenware.com) + * + * REPOSITORY: + * git://lowenware.com:standard.git + * MAINTAINER: + * Ilja Kartaschoff + * + * LICENSE and DISCLAIMER: + * All code stored in standard.git repository is designed to solve + * very common and widely meet development tasks. We are not about to patent + * wheels here, so all code you can find in this repository is FREE: + * you can use, redistribute and/or modify it without any limits or + * restrictions. + * + * All code described above is distributed in hope to be useful for somebody + * else WITHOUT ANY WARRANTY, without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In case of questions or suggestions, feel free to contact maintainer. + * + * */ + +#ifndef _CSTUFF_STR_UTILS_H_ +#define _CSTUFF_STR_UTILS_H_ + +#include +#include +#include + + +/* if init is not set or smaller than src, it will be reallocated + * */ +char * +str_set(char * init, const char * src); + + +/* copy src string to newly allocated one + * */ +char * +str_copy(const char * src); + + +/* copy num bytes from src string to newly allocated one + * */ +char * +str_ncopy(const char * src, uint32_t num); + + +char * +str_printf(const char * format, ...); + +char * +str_vprintf(const char * format, va_list vl); + + +/* for source will be called u_free automatically */ +char * +str_cat(char * source, const char * target); + + +/* for source will be called u_free automatically */ +char * +str_ncat(char * source, const char * target, uint32_t length); + + +/* compare strings ignoring case */ +int +str_cmpi(const char * source, const char * target); + + +int +str_to_int(const char * ptr, int l, int32_t * result); + + +/* -------------------------------------------------------------------------- */ + +int +str_to_int64(const char * ptr, int l, int64_t * result); + + + +int +str_to_timestamp(const char * source, size_t l, time_t * p_ts, const char * tz); + + +char * +str_from_timestamp_iso_utc(time_t ts); + + +char * +str_from_timestamp(time_t ts, const char * format, const char * timezone); + + +/* chop spaces from string, return number of prepending spaces */ +uint32_t +str_chop(char * source); + + +char * +str_replace(const char * haystack, const char * needle, const char * value); + + +#endif diff --git a/library/stream.c b/src/stream.c similarity index 100% rename from library/stream.c rename to src/stream.c diff --git a/library/stream.h b/src/stream.h similarity index 98% rename from library/stream.h rename to src/stream.h index d308a52..ef59fa2 100644 --- a/library/stream.h +++ b/src/stream.h @@ -3,7 +3,7 @@ #include #include -#include +#include "list.h" #include "buffer.h" /* -------------------------------------------------------------------------- */ diff --git a/version b/version deleted file mode 100644 index 9edeaea..0000000 --- a/version +++ /dev/null @@ -1 +0,0 @@ -0.3.4-alpha