Refactored build system and library includes

This commit is contained in:
Ilja Kartašov 2019-03-04 23:05:46 +01:00
parent 2d67fdd5fb
commit 86b69c89b8
47 changed files with 1695 additions and 1087 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "cStuff"]
path = cStuff
url = https://github.com/lowenware/cStuff.git

View File

View File

@ -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}
)

View File

@ -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

1
cStuff

@ -1 +0,0 @@
Subproject commit a423fa7a6dfbd637f3c0b248123f682456fccad7

View File

@ -1,7 +0,0 @@
if(DEFINED CMAKE_DEBUG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror ")
add_definitions(
-DDEBUG
)
endif()

View File

@ -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}"
)
# -----------------------------------------------------------------------------

View File

@ -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}"
)

View File

@ -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}
)

26
config.mk Normal file
View File

@ -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
#

View File

@ -1,107 +1,40 @@
/* ----------------------------------------------------------------------------
* aisl.h - header file for AISL library, part of AISLing Technology
/*
* <aisl/aisl.h>
*
* Copyright (c) 2017 by Löwenware Ltd. (https://lowenware.com/)
* Copyright (c) 2017-2019 by Löwenware Ltd.
*
* Authors and maintainers:
* Ilja Kartaschoff <ik@lowenware.com>
* 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 <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <arpa/inet.h>
/* aisl includes ------------------------------------------------------------ */
/* AISL configuration structure */
#include <aisl/config.h>
/* AISL status codes and utilities */
#include <aisl/status.h>
/* AISL callbacks definitions */
#include <aisl/callback.h>
/* AISL events enumeration and utilities*/
#include <aisl/event.h>
/* AISL instancing, initialization and processing */
#include <aisl/instance.h>
/* Embedded HTTP(s) servers */
#include <aisl/server.h>
/* HTTP(s) clients */
#include <aisl/client.h>
/* HTTP(s) streaming */
#include <aisl/stream.h>
#include <aisl/handle.h>
/* HTTP constants and utilities */
#include <aisl/http.h>
/* 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 */

76
include/aisl/callback.h Normal file
View File

@ -0,0 +1,76 @@
/*
* <aisl/callback.h>
*
* 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 <stdbool.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <aisl/server.h>
#include <aisl/client.h>
#include <aisl/stream.h>
#include <aisl/http.h>
#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 */

15
include/aisl/client.h Normal file
View File

@ -0,0 +1,15 @@
/*
* <aisl/server.h>
*
* 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 */

28
include/aisl/config.h Normal file
View File

@ -0,0 +1,28 @@
/*
* <aisl/config.h>
*
* 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 <stdint.h>
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 */

View File

@ -1,128 +1,42 @@
#ifndef _AISL_EVENT_H_
#define _AISL_EVENT_H_
/*
* <aisl/event.h>
*
* Copyright (c) 2017 by Löwenware Ltd.
*
* Project homepage: https://lowenware.com/aisl/
*
*/
#include <stdbool.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <aisl/stream.h>
#include <aisl/status.h>
#include <aisl/http.h>
#ifndef AISL_EVENT_H_E99458C9_CCAA_4CAC_97F8_41E8869EE26F
#define AISL_EVENT_H_E99458C9_CCAA_4CAC_97F8_41E8869EE26F
/* -------------------------------------------------------------------------- */
#include <stdint.h>
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 */

View File

@ -1,76 +0,0 @@
#ifndef _AISL_HANDLE_H_
#define _AISL_HANDLE_H_
#include <aisl/status.h>
#include <aisl/event.h>
/* -------------------------------------------------------------------------- */
#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

View File

@ -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 */

75
include/aisl/instance.h Normal file
View File

@ -0,0 +1,75 @@
/*
* <aisl/instance.h>
*
* 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 <stdint.h>
#include <stdarg.h>
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 */

24
include/aisl/server.h Normal file
View File

@ -0,0 +1,24 @@
/*
* <aisl/server.h>
*
* 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 */

View File

@ -1,24 +1,29 @@
#ifndef _AISL_STATUS_H_
#define _AISL_STATUS_H_
/*
* <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 */

View File

@ -1,172 +1,104 @@
#ifndef _AISL_STREAM_H_
#define _AISL_STREAM_H_
/*
* <aisl/stream.h>
*
* Copyright (c) 2017-2019 by Löwenware Ltd.
*
* Project homepage: https://lowenware.com/aisl/
*
*/
#include <arpa/inet.h>
/* Library statuses */
/* HTTP requests */
#include <aisl/http.h>
#include <aisl/status.h>
#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 */

View File

@ -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
# -----------------------------------------------------------------------------

View File

@ -7,9 +7,10 @@
#include <sys/time.h>
#include <aisl/aisl.h>
#include <cStuff/list.h>
#include <cStuff/str-utils.h>
#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));
}
/* -------------------------------------------------------------------------- */

19
src/aisl.h Normal file
View File

@ -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 */

View File

@ -13,7 +13,7 @@ struct buffer
typedef struct buffer * buffer_t;
#define BUFFER_EOB ( ~0 )
#define BUFFER_EOB ( ~0L )
/* -------------------------------------------------------------------------- */

View File

@ -6,7 +6,7 @@
#include <aisl/aisl.h>
#include <aisl/http.h>
#include <cStuff/list.h>
#include "list.h"
#include <openssl/err.h>
#include <openssl/ssl.h>

View File

@ -1,11 +1,13 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/select.h>
#include <openssl/err.h>
#include <aisl/handle.h>
#include <cStuff/str-utils.h>
#include <cStuff/list.h>
#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);

View File

@ -6,7 +6,7 @@
#include <aisl/handle.h>
#include <cStuff/list.h>
#include "list.h"
#include <openssl/ssl.h>
#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;
};
/* -------------------------------------------------------------------------- */

13
src/instance.c Normal file
View File

@ -0,0 +1,13 @@
/*
* src/instance.c
*
* Copyright (C) 2019 Ilja Kartašov <ik@lowenware.com>
*
* Project homepage: https://lowenware.com/aisl/
*
*/
#include "instance.h"

16
src/instance.h Normal file
View File

@ -0,0 +1,16 @@
/*
* src/instance.h
*
* Copyright (C) 2019 Ilja Kartašov <ik@lowenware.com>
*
* Project homepage: https://lowenware.com/aisl/
*
*/
#ifndef INSTANCE_H_814CF474_A646_45B7_B6B2_3F4C7BEFA484
#define INSTANCE_H_814CF474_A646_45B7_B6B2_3F4C7BEFA484
#include <aisl/instance.h>
#endif /* !INSTANCE_H */

201
src/list.c Normal file
View File

@ -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 <ik@lowenware.com>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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; i<self->count; 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; i<self->count; 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; i<self->count; 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
/* -------------------------------------------------------------------------- */

120
src/list.h Normal file
View File

@ -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 <ik@lowenware.com>
*
* 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 <stdint.h>
/* 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

View File

@ -3,7 +3,7 @@
#include <string.h>
#include <ctype.h>
#include <cStuff/str-utils.h>
#include "str-utils.h"
#include <aisl/http.h>
#include "parser.h"

View File

@ -2,15 +2,16 @@
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netdb.h>
#include <cStuff/str-utils.h>
#include "server.h"
#include "handle.h"
#include "client.h"
#include "globals.h"
#include "str-utils.h"
/* -------------------------------------------------------------------------- */

627
src/str-utils.c Normal file
View File

@ -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 <ik@lowenware.com>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 <ctype.h>
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 <time.h>
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
/* -------------------------------------------------------------------------- */

104
src/str-utils.h Normal file
View File

@ -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 <ik@lowenware.com>
*
* 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 <stdint.h>
#include <stdarg.h>
#include <time.h>
/* 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

View File

@ -3,7 +3,7 @@
#include <stdbool.h>
#include <aisl/stream.h>
#include <cStuff/list.h>
#include "list.h"
#include "buffer.h"
/* -------------------------------------------------------------------------- */

View File

@ -1 +0,0 @@
0.3.4-alpha