├── NEWS ├── ChangeLog ├── c_icap.def ├── AUTHORS ├── services ├── echo │ ├── srv_echo.def │ ├── .cvsignore │ ├── makefile.w32 │ └── Makefile.am ├── .cvsignore ├── Makefile.am └── ex-206 │ └── Makefile.am ├── docs ├── Makefile.am └── man │ ├── Makefile.am │ ├── c-icap-libicapapi-config.8.in │ ├── c-icap-config.8.in │ ├── c-icap-mkbdb.8.in │ ├── c-icap-mklmdb.8.in │ ├── c-icap-stretch.8.in │ ├── c-icap-client.8.in │ └── c-icap.8.in ├── os ├── .cvsignore ├── unix │ ├── .cvsignore │ ├── dlib.c │ ├── utilfunc.c │ ├── proc_utils.c │ └── threads.c └── win32 │ ├── dll_entry.c │ ├── makefile.w32 │ ├── proc_mutex.c │ ├── dlib.c │ ├── threads.c │ └── shared_mem.c ├── BUGS ├── modules ├── .cvsignore ├── Makefile.am └── perl_handler.c ├── TODO ├── tests ├── dbs │ └── db1.txt ├── test_base64.c ├── Makefile.am ├── test_md5.c ├── test_atomics_cplusplus.cc ├── test_ops.c ├── test_allocators.c ├── test_filetype.c └── test_body.c ├── c_icap.mak ├── CONTRIBUTORS ├── .cvsignore ├── RECONF ├── run-indent.sh ├── contrib ├── convert_old_magic.pl ├── get_file.pl └── config_to_html.pl ├── c_icap_dll.mak ├── c-icap-libicapapi-config.in ├── README ├── openssl ├── build_openssl_opts.pl └── openssl_options.c ├── include ├── simple_api.h ├── c-icap-conf-w32.h.default ├── c-icap-conf-w32.h.in ├── md5.h ├── log.h ├── dlib.h ├── access.h ├── registry.h ├── debug.h ├── hash.h ├── port.h ├── types_ops.h ├── txtTemplate.h ├── openssl_support.h ├── http_server.h ├── proc_mutex.h ├── shared_mem.h ├── txt_format.h ├── util.h ├── ci_regex.h ├── ci_time.h ├── c-icap-conf.h.in ├── client.h ├── mem.h ├── proc_threads_queues.h ├── c-icap.h ├── commands.h ├── lookup_table.h └── ci_threads.h ├── config-w32.h ├── makefile.w32 ├── common.h ├── utils └── Makefile.am ├── c-icap-config.in ├── dlib.c ├── access.c ├── debug.c ├── port.c ├── hash.c ├── registry.c └── default_acl.c /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /c_icap.def: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Tsantilas Christos 2 | -------------------------------------------------------------------------------- /services/echo/srv_echo.def: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = man 2 | -------------------------------------------------------------------------------- /os/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | Makefile.in 3 | 4 | -------------------------------------------------------------------------------- /os/unix/.cvsignore: -------------------------------------------------------------------------------- 1 | .deps 2 | Makefile 3 | Makefile.in 4 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | 1) if client don't support 204 server must not send it 2 | -------------------------------------------------------------------------------- /modules/.cvsignore: -------------------------------------------------------------------------------- 1 | .deps 2 | Makefile 3 | Makefile.in 4 | 5 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | 2 | 3 | TODOS: 4 | 5 | 1) SNMP support (Maybe agentx client....) 6 | -------------------------------------------------------------------------------- /services/echo/.cvsignore: -------------------------------------------------------------------------------- 1 | .deps 2 | Makefile 3 | Makefile.in 4 | srv_echo.c.old 5 | -------------------------------------------------------------------------------- /services/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | Makefile.in 3 | Makefile.old.am 4 | a_perl 5 | 6 | -------------------------------------------------------------------------------- /tests/dbs/db1.txt: -------------------------------------------------------------------------------- 1 | key1: v11, v12, v13 2 | key2: v21, v22, v23, v34 3 | key3: 4 | key4: v41, v42, v43 5 | key5: v51 6 | -------------------------------------------------------------------------------- /os/win32/dll_entry.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | BOOL WINAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, 5 | LPVOID lpReserved) 6 | { 7 | return (TRUE); 8 | } 9 | -------------------------------------------------------------------------------- /c_icap.mak: -------------------------------------------------------------------------------- 1 | 2 | CONFDIR="c:\\c-icap\\etc" 3 | SERVDIR="c:\\c-icap\\lib" 4 | MODSDIR="c:\\c-icap\\lib" 5 | LOGDIR="c:\\c-icap\\log" 6 | 7 | CI_DEFS=-DCONFDIR=\"$(CONFDIR)\" -DSERVDIR=\"$(SERVDIR)\" -DMODSDIR=\"$(MODSDIR)\" -DLOGDIR=\"$(LOGDIR)\" 8 | -------------------------------------------------------------------------------- /services/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | #SUBDIRS = url_check echo clamav 3 | 4 | #SUBDIRS = @BUILD_SERVICES@ 5 | 6 | SUBDIRS = echo ex-206 7 | 8 | #SUBDIRS += url_check 9 | 10 | #if USECLAMAV 11 | #SUBDIRS += clamav 12 | #endif 13 | 14 | #if USEPERL 15 | #SUBDIRS += a_perl 16 | #endif 17 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Christos Tsantilas 2 | Alexandros Tsantilas : has wrote some of the parsers used by c-icap 3 | Tofig Suleymanov: Implemented the ListenAddress configuration option 4 | Alfred Klomp, Bokxing IT: bug fixes 5 | Trever L. Adams: txtTemplates, bzip,gzip/deflate encoding routings 6 | Jeffrey Merkey: brotli compression/decompression support 7 | -------------------------------------------------------------------------------- /.cvsignore: -------------------------------------------------------------------------------- 1 | aclocal.m4 2 | autom4te.cache 3 | c-icap.conf 4 | c-icap.local.conf 5 | compile 6 | config.* 7 | configure 8 | depcomp 9 | .deps 10 | icap_send_file 11 | install-sh 12 | libtool 13 | ltmain.sh 14 | Makefile 15 | Makefile.in 16 | Makefile.Linux-Static 17 | missing 18 | mkinstalldirs 19 | stamp-h1 20 | TAGS 21 | TEST 22 | tests 23 | var 24 | -------------------------------------------------------------------------------- /RECONF: -------------------------------------------------------------------------------- 1 | if test -d .git; then 2 | git branch --list -v | grep -e '^\*' | awk '{print $2"-"$3}'> VERSION.m4 3 | else 4 | echo "unversioned" > VERSION.m4 5 | fi 6 | autoreconf -f -i -v -W all 7 | #aclocal 8 | #autoconf 9 | ##autoheader 10 | ##cp /usr/share/libtool/ltmain.sh . 11 | #libtoolize --copy --automake -f 12 | #automake --add-missing --copy 13 | -------------------------------------------------------------------------------- /services/echo/makefile.w32: -------------------------------------------------------------------------------- 1 | !include 2 | 3 | all: srv_echo.Dll 4 | 5 | .c.obj: 6 | $(cc) /I..\..\include /I..\..\ $(cdebug) $(cflags) $(cvarsdll) -I. -DCI_BUILD_MODULE -DUNICODE $*.c 7 | 8 | srv_echo.Dll: srv_echo.obj 9 | $(link) $(linkdebug) $(dlllflags) /LIBPATH:..\..\ c_icap.lib -def:srv_echo.def -out:$*.Dll $** $(DLL_ENTRY) $(EXTRA_LIBS) 10 | 11 | clean: 12 | del *.obj *.exe *.lib 13 | 14 | -------------------------------------------------------------------------------- /services/ex-206/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | pkglib_LTLIBRARIES=srv_ex206.la 3 | 4 | AM_CPPFLAGS=-I$(top_srcdir)/ -I$(top_srcdir)/include/ -I$(top_builddir)/include/ 5 | 6 | if ISCYGWIN 7 | MODS_LIB_ADD=$(top_builddir)/libicapapi.la 8 | else 9 | MODS_LIB_ADD= 10 | endif 11 | 12 | srv_ex206_la_LIBADD = $(MODS_LIB_ADD) 13 | srv_ex206_la_CFLAGS= @MODULES_CFLAGS@ 14 | srv_ex206_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 15 | srv_ex206_la_SOURCES = srv_ex206.c 16 | 17 | -------------------------------------------------------------------------------- /services/echo/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | pkglib_LTLIBRARIES=srv_echo.la 3 | 4 | AM_CPPFLAGS=-I$(top_srcdir)/ -I$(top_srcdir)/include/ -I$(top_builddir)/include/ 5 | 6 | if ISCYGWIN 7 | MODS_LIB_ADD=$(top_builddir)/libicapapi.la 8 | else 9 | MODS_LIB_ADD= 10 | endif 11 | 12 | srv_echo_la_LIBADD = $(MODS_LIB_ADD) 13 | srv_echo_la_CFLAGS= @MODULES_CFLAGS@ 14 | srv_echo_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 15 | srv_echo_la_SOURCES = srv_echo.c 16 | 17 | 18 | EXTRA_DIST= makefile.w32 srv_echo.def 19 | -------------------------------------------------------------------------------- /run-indent.sh: -------------------------------------------------------------------------------- 1 | # prefer astyle for formating: 2 | find . -name "*.[ch]" -exec astyle --mode=c -s4 --convert-tabs --keep-one-line-blocks --style=kr --lineend=linux --pad-header \{\} \; 3 | 4 | # mostly k&r style with some exceptions 5 | #find . -name "*.[ch]" -exec indent -nbad -bap -nbc -br -brs -c33 -cd33 -cdb -ce -ci4 -cli0 -cp33 -d0 -di1 -nfc1 -nfca -i4 -ip0 -l180 -ncs -npcs -nprs -npsl -saf -sai -saw -nsc -nsob -nss -nut \{\} \; 6 | 7 | # Old formating command: 8 | # find . -name "*.h" -o -name "*.c" -exec indent -kr -i4 -ts8 -di1 -l80 -nce -nut -nfca \{\} \; 9 | 10 | 11 | -------------------------------------------------------------------------------- /os/win32/makefile.w32: -------------------------------------------------------------------------------- 1 | !include 2 | 3 | UTILS_OBJS=shared_mem.obj proc_mutex.obj net_io.obj threads.obj utilfunc.obj 4 | 5 | all: dll_entry.obj utils.lib 6 | 7 | .c.obj: 8 | 9 | $(cc) -I..\..\include -I..\..\ $(cdebug) $(cflags) $(cvarsdll) -I. -DCI_BUILD_LIB -DUNICODE $*.c 10 | 11 | # Previous line is the correct if we include utils.lib in c_icap.dll 12 | 13 | # $(cc) -I..\..\include -I..\..\ $(cdebug) $(cflags) $(cvarsmt) -I. -DUNICODE $*.c 14 | 15 | 16 | 17 | utils.lib: $(UTILS_OBJS) 18 | 19 | echo "Do not make the lib so nothing to do....." 20 | 21 | # $(link) /LIB $(linkdebug) -out:$*.lib $** $(EXTRA_LIBS) 22 | 23 | 24 | clean: 25 | 26 | del *.obj *.exe *.lib 27 | -------------------------------------------------------------------------------- /docs/man/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | CONFIGDIR=@sysconfdir@ 3 | PKGLIBDIR=@pkglibdir@ 4 | MODULESDIR=$(pkglibdir)/ 5 | SERVICESDIR=$(pkglibdir)/ 6 | LOGDIR=$(localstatedir)/log/ 7 | SOCKDIR=/var/run/c-icap 8 | 9 | do_subst=sed -e 's%[@]SYSCONFDIR[@]%$(CONFIGDIR)%g' \ 10 | -e 's%[@]PACKAGE_STRING[@]%$(PACKAGE_STRING)%g' 11 | 12 | 13 | manpages = c-icap.8 c-icap-client.8 c-icap-config.8 c-icap-libicapapi-config.8 \ 14 | c-icap-stretch.8 c-icap-mkbdb.8 c-icap-mklmdb.8 15 | manpages_src = $(manpages:.8=.8.in) 16 | 17 | CLEANFILES = $(manpages) 18 | 19 | SUFFIXES = .8.in .8 20 | 21 | .8.in.8: 22 | $(do_subst) < $< > $@ 23 | 24 | man_MANS = $(manpages) 25 | 26 | EXTRA_DIST = $(manpages_src) 27 | -------------------------------------------------------------------------------- /tests/test_base64.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "encoding.h" 3 | #include 4 | 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | char encoded[1024]; 9 | char decoded[1024]; 10 | int l; 11 | const char *str; 12 | if (argc > 1) { 13 | str = argv[1]; 14 | } else 15 | str = "Good morning"; 16 | ci_base64_encode((unsigned char *)str, (size_t)strlen(str), encoded, 1024); 17 | l = ci_base64_decode(encoded, decoded, 1024); 18 | decoded[l] = '\0'; 19 | printf("Input string: \'%s\'\n", str); 20 | printf("Base64 encoded string: \'%s\'\n", encoded); 21 | printf("Decoded string: \'%s\'\n", decoded); 22 | return 0; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /contrib/convert_old_magic.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # this utility can be used to convert old c-icap.magic files to new format 4 | # The old line format was: 5 | # POS:LABEL:TYPE NAME:GROUP:COMMENT 6 | # The new is : 7 | # POS:LABEL:TYPE NAME:COMMENT:GROUP1[:GROUP2[:GROUP3[...]]] 8 | 9 | 10 | my $in = shift; 11 | 12 | if(!open(FILE,$in)){ 13 | die "The file $in does not exists!\n\n"; 14 | } 15 | 16 | while(){ 17 | $line=$_; 18 | 19 | 20 | if( $line =~ /^\#.*/ || $line =~ /^[\s*]$/){ 21 | print $line; 22 | } 23 | else{ 24 | chomp $line; 25 | split ':',$line; 26 | 27 | print $_[0].":".$_[1].":".$_[2].":".$_[4].":".$_[3]."\n"; 28 | 29 | } 30 | 31 | } 32 | 33 | close(FILE); 34 | -------------------------------------------------------------------------------- /c_icap_dll.mak: -------------------------------------------------------------------------------- 1 | !include 2 | !include "c_icap.mak" 3 | 4 | all: c_icap.Dll 5 | 6 | LIBICAPOBJS = header.obj body.obj net_io.obj simple_api.obj base64.obj cfg_lib.obj filetype.obj debug.obj 7 | LIBUTIL=os\win32\shared_mem.obj os\win32\proc_mutex.obj os\win32\net_io.obj os\win32\threads.obj os\win32\utilfunc.obj 8 | 9 | .c.obj: 10 | $(cc) -Iinclude $(cdebug) $(cflags) $(cvarsdll) $(CI_DEFS) -I. -DCI_BUILD_LIB -DUNICODE $*.c /Fo$*.obj 11 | # $(cc) -Iinclude $(cdebug) $(cflags) $(cvarsmt) -I. -DCI_BUILD_LIB -DUNICODE $*.c 12 | 13 | c_icap.Dll: $(LIBICAPOBJS) $(LIBUTIL) $(DLL_ENTRY) 14 | $(link) $(ldebug) $(dlllflags) -def:c_icap.def -out:$*.Dll $** Ws2_32.lib kernel32.lib $(DLL_ENTRY) $(EXTRA_LIBS) 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | CONFIGDIR=@sysconfdir@ 3 | PKGLIBDIR=@pkglibdir@ 4 | MODULESDIR=$(pkglibdir)/ 5 | SERVICESDIR=$(pkglibdir)/ 6 | #CONFIGDIR=$(sysconfdir)/ 7 | 8 | RPATH_FLAG= 9 | if USE_RPATH 10 | RPATH_FLAG+=-rpath @libdir@ 11 | endif 12 | 13 | AM_CFLAGS=-I$(top_srcdir)/ -I$(top_srcdir)/include/ -I$(top_builddir)/include/ 14 | AM_LDFLAGS = -rdynamic $(RPATH_FLAG) @THREADS_LDFLAGS@ 15 | LDADD = ../libicapapi.la @THREADS_LDADD@ @DL_ADD_FLAG@ $(EXT_PROGRAMS_MKLIB) 16 | 17 | if USE_CPLUSPLUS 18 | AM_CXXFLAGS = $(AM_CFLAGS) 19 | CXX_PRGS = test_atomics_cplusplus 20 | test_atomics_cplusplus_SOURCES = test_atomics_cplusplus.cc 21 | endif 22 | 23 | noinst_PROGRAMS = test_cache test_tables test_headers test_allocators test_arrays test_lists test_md5 test_base64 test_body test_ops test_filetype test_shared_locking test_atomics $(CXX_PRGS) 24 | -------------------------------------------------------------------------------- /docs/man/c-icap-libicapapi-config.8.in: -------------------------------------------------------------------------------- 1 | .TH c-icap-libicapapi-config 8 "@PACKAGE_STRING@" 2 | .SH NAME 3 | c-icap-libicapapi-config - script to get information about c-icap library 4 | .SH SYNOPSIS 5 | .B c-icap-libicapapi-config 6 | [ 7 | .B --cflags 8 | ] 9 | [ 10 | .B --libs 11 | ] 12 | [ 13 | .B --version 14 | ] 15 | .SH DESCRIPTION 16 | .B c-icap-libicapapi-config 17 | is a script to get compile options must used to use c-icap library. 18 | .SH OPTIONS 19 | .IP --cflags 20 | print preprocessor and compiler flags should used to compile a c-icap service or module 21 | .IP --libs 22 | print linker flags should used to link with c-icap library 23 | .IP --version 24 | print the c-icap server version 25 | .SH SEE ALSO 26 | .BR c-icap "(8)" 27 | .BR c-icap-client "(8)" 28 | .BR c-icap-stretch "(8)" 29 | .BR c-icap-config "(8)" 30 | .BR c-icap-mkbdb "(8)" 31 | .SH AUTHOR 32 | Tsantilas Christos 33 | -------------------------------------------------------------------------------- /c-icap-libicapapi-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prefix=@prefix@ 4 | 5 | PKGLIBDIR=@PKGLIBDIR@/ 6 | LIBDIR=@LIBDIR@/ 7 | CONFIGDIR=@SYSCONFDIR@/ 8 | DATADIR=@PKGDATADIR@/ 9 | #LOGDIR= 10 | SOCKDIR=@SOCKDIR@ 11 | 12 | INCDIR=@INCLUDEDIR@ 13 | INCDIR2=@PKGINCLUDEDIR@ 14 | 15 | VERSION=@PACKAGE_VERSION@ 16 | 17 | CFLAGS="@CFLAGS@" 18 | LIBS="-L$LIBDIR -licapapi @EXT_PROGRAMS_LIBADD@" 19 | LDFLAGS="" 20 | 21 | 22 | usage() 23 | { 24 | cat <) { 9 | $line = $_; 10 | if ( $line =~ /^\s*#\s*define\s*(SSL_OP_\w*)\s*(0x[0-9a-fA-F]+)[U|L|u|l]/ ) { 11 | $def = {}; 12 | $def->{name} = $1; 13 | $def->{value} = $2."U"; 14 | # Check to see if it is already exist in array. 15 | if (!findDefine(\@defines, \$def)) { 16 | push @defines, $def; 17 | } 18 | } 19 | } 20 | 21 | print "struct {\n const char *name;\n unsigned long int value;\n} OPENSSL_OPTS[] = {\n"; 22 | for $def (@defines) { 23 | print "#if defined(".$def->{name}.")\n {\"".$def->{name}."\", ".$def->{name}."},\n#endif\n"; 24 | } 25 | print " {NULL, 0x0}\n};\n"; 26 | exit(0); 27 | 28 | sub findDefine { 29 | ($defines, $find) = @_; 30 | for $def (@$defines) { 31 | if ($def->{name} eq $$find->{name}) { 32 | return 1; 33 | } 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /include/simple_api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_SIMPLE_API_H 22 | #define __C_ICAP_SIMPLE_API_H 23 | 24 | #include "c-icap.h" 25 | #include "request.h" 26 | #include "request_util.h" 27 | #include "encoding.h" 28 | 29 | 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /docs/man/c-icap-config.8.in: -------------------------------------------------------------------------------- 1 | .TH c-icap-config 8 "@PACKAGE_STRING@" 2 | .SH NAME 3 | c-icap-config - script to get information about c-icap server 4 | .SH SYNOPSIS 5 | .B c-icap-config 6 | [ 7 | .B --cflags 8 | ] 9 | [ 10 | .B --libs 11 | ] 12 | [ 13 | .B --datarootdir 14 | ] 15 | [ 16 | .B --configdir 17 | ] 18 | [ 19 | .B --version 20 | ] 21 | [ 22 | .B --config 23 | ] 24 | .SH DESCRIPTION 25 | .B c-icap-config 26 | is a script to get information about c-icap server and compile options must used to build c-icap server modules and services. 27 | 28 | .SH OPTIONS 29 | .IP --cflags 30 | print preprocessor and compiler flags should used to compile a c-icap service or module 31 | .IP --libs 32 | print linker flags should used to build a c-icap service or module 33 | .IP --datarootdir 34 | print the c-icap data directory 35 | .IP --configdir 36 | print the c-icap configuration directory 37 | .IP --version 38 | print the c-icap server version 39 | .IP --config 40 | print the c-icap server compile configuration 41 | 42 | .SH SEE ALSO 43 | .BR c-icap "(8)" 44 | .BR c-icap-client "(8)" 45 | .BR c-icap-stretch "(8)" 46 | .BR c-icap-libicapapi-config "(8)" 47 | .BR c-icap-mkbdb "(8)" 48 | .SH AUTHOR 49 | Tsantilas Christos 50 | -------------------------------------------------------------------------------- /include/c-icap-conf-w32.h.default: -------------------------------------------------------------------------------- 1 | /*This is autogenerated file*/ 2 | 3 | #ifndef __C_ICAP_CONF_H 4 | #define __C_ICAP_CONF_H 5 | 6 | #define C_ICAP_HEX_VERSION 0xF0000000FFFF 7 | 8 | /* Define USE_IPV6 if we are supporting ipv6 */ 9 | #if 0 10 | #define USE_IPV6 11 | #endif 12 | 13 | #if 0 14 | #define USE_SYSV_IPC 15 | #endif 16 | 17 | #if 0 18 | #define USE_POSIX_FILE_LOCK 19 | #endif 20 | 21 | #if 0 22 | #define USE_POSIX_MAPPED_FILES 23 | #endif 24 | 25 | #if 0 26 | #define USE_POSIX_SEMAPHORES 27 | #endif 28 | 29 | #if 0 30 | #define USE_PTHREADS_RWLOCK 31 | #endif 32 | 33 | #if 0 34 | #define __CI_COMPAT 35 | #endif 36 | 37 | #if 1 38 | #define __SYS_TYPES_H_EXISTS 39 | #endif 40 | 41 | #if 1 42 | #define __INTTYPES_H_EXISTS 43 | #endif 44 | 45 | #define CI_SIZEOF_OFF_T 8 46 | 47 | /* Define to `long int' if does not define. */ 48 | #if 0 49 | #define off_t long int 50 | #endif 51 | 52 | /* Define to `unsigned int' if does not define. */ 53 | #if 0 54 | #define size_t unsigned int 55 | #endif 56 | 57 | #if 0 58 | #define uint16_t unsigned short 59 | #endif 60 | 61 | #if 0 62 | #define uint32_t unsigned int 63 | #endif 64 | 65 | #if 0 66 | #define uint8_t unsigned char 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /include/c-icap-conf-w32.h.in: -------------------------------------------------------------------------------- 1 | /*This is autogenerated file*/ 2 | 3 | #ifndef __C_ICAP_CONF_H 4 | #define __C_ICAP_CONF_H 5 | 6 | #define C_ICAP_HEX_VERSION @C_ICAP_HEX_VERSION@ 7 | 8 | /* Define USE_IPV6 if we are supporting ipv6 */ 9 | #if 0 10 | #define USE_IPV6 11 | #endif 12 | 13 | #if 0 14 | #define USE_SYSV_IPC 15 | #endif 16 | 17 | #if 0 18 | #define USE_POSIX_FILE_LOCK 19 | #endif 20 | 21 | #if 0 22 | #define USE_POSIX_MAPPED_FILES 23 | #endif 24 | 25 | #if 0 26 | #define USE_POSIX_SEMAPHORES 27 | #endif 28 | 29 | #if 0 30 | #define USE_PTHREADS_RWLOCK 31 | #endif 32 | 33 | #if 0 34 | #define __CI_COMPAT 35 | #endif 36 | 37 | #if 1 38 | #define __SYS_TYPES_H_EXISTS 39 | #endif 40 | 41 | #if 1 42 | #define __INTTYPES_H_EXISTS 43 | #endif 44 | 45 | #define CI_SIZEOF_OFF_T 8 46 | 47 | /* Define to `long int' if does not define. */ 48 | #if 0 49 | #define off_t long int 50 | #endif 51 | 52 | /* Define to `unsigned int' if does not define. */ 53 | #if 0 54 | #define size_t unsigned int 55 | #endif 56 | 57 | #if 0 58 | #define uint16_t unsigned short 59 | #endif 60 | 61 | #if 0 62 | #define uint32_t unsigned int 63 | #endif 64 | 65 | #if 0 66 | #define uint8_t unsigned char 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /include/md5.h: -------------------------------------------------------------------------------- 1 | #ifndef __C_ICAP_CI_MD5_H 2 | #define __C_ICAP_CI_MD5_H 3 | 4 | #include "c-icap.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" 8 | { 9 | #endif 10 | 11 | struct ci_MD5Context { 12 | uint32_t buf[4]; 13 | uint32_t bits[2]; 14 | unsigned char in[64]; 15 | }; 16 | typedef struct ci_MD5Context ci_MD5_CTX; 17 | CI_DECLARE_FUNC(void) ci_MD5Init(struct ci_MD5Context *ctx); 18 | CI_DECLARE_FUNC(void) ci_MD5Update(struct ci_MD5Context *ctx, const unsigned char *buf, size_t len); 19 | CI_DECLARE_FUNC(void) ci_MD5Final(unsigned char digest[16], struct ci_MD5Context *ctx); 20 | 21 | /** 22 | Convert the 16-bytes md5 digest to a hex/string representation. 23 | To fully dump md5 string needs a buffer of size at least 24 | 32+1 bytes. 25 | It always produces a null terminated string. 26 | \ingroup UTILITY 27 | \return The written bytes. If the output string is truncated then the 28 | return value us the number of characters which would have been 29 | been written to the out string if enough space had been available. 30 | */ 31 | CI_DECLARE_FUNC(int) ci_MD5_to_str(unsigned char digest[16], char *out, size_t size); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif /* __C_ICAP_CI_MD5_H */ 38 | -------------------------------------------------------------------------------- /tests/test_md5.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | #include 4 | #include 5 | #include "md5.h" 6 | 7 | static void MDPrint(unsigned char digest[16]); 8 | static void MDString(char *string); 9 | 10 | static void 11 | MDString(char *string) 12 | { 13 | ci_MD5_CTX context; 14 | unsigned char digest[16]; 15 | unsigned int len = strlen(string); 16 | ci_MD5Init(&context); 17 | ci_MD5Update(&context, (unsigned char *)string, len); 18 | ci_MD5Final(digest, &context); 19 | printf("MD5 (\"%s\") = ", string); 20 | MDPrint(digest); 21 | printf("\n"); 22 | } 23 | 24 | static void 25 | MDPrint(unsigned char digest[16]) 26 | { 27 | unsigned int i; 28 | for (i = 0; i < 16; i++) 29 | printf("%02x", digest[i]); 30 | } 31 | 32 | 33 | int main(int argc, char *argv[]) 34 | { 35 | printf("MD5 test suite:\n"); 36 | MDString(""); 37 | MDString("a"); 38 | MDString("abc"); 39 | MDString("message digest"); 40 | MDString("abcdefghijklmnopqrstuvwxyz"); 41 | MDString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 42 | MDString("1234567890123456789012345678901234567890" 43 | "1234567890123456789012345678901234567890"); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /config-w32.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Config.h file for win32 using MSVC compiler 4 | 5 | */ 6 | #include /*For struct tm declaration ....*/ 7 | #define HAVE_MALLOC_H 1 8 | #define HAVE_MEMORY_H 1 9 | #define HAVE_STDLIB_H 1 10 | #define HAVE_STRING_H 1 11 | #define HAVE_SYS_STAT_H 1 12 | #define HAVE_SYS_TYPES_H 1 13 | 14 | /*Some functions definitions */ 15 | #define snprintf _snprintf 16 | #define strtoll strtol 17 | 18 | /* Name of package */ 19 | #define PACKAGE "c_icap" 20 | 21 | /* Define to the address where bug reports for this package should be sent. */ 22 | #define PACKAGE_BUGREPORT "" 23 | 24 | /* Define to the full name of this package. */ 25 | #define PACKAGE_NAME "" 26 | 27 | /* Define to the full name and version of this package. */ 28 | #define PACKAGE_STRING "" 29 | 30 | /* Define to the one symbol short name of this package. */ 31 | #define PACKAGE_TARNAME "" 32 | 33 | /* Define to the version of this package. */ 34 | #define PACKAGE_VERSION "" 35 | 36 | /* Define to 1 if you have the ANSI C header files. */ 37 | #define STDC_HEADERS 1 38 | 39 | /* Version number of package */ 40 | #define VERSION "1.0" 41 | 42 | /* Define to empty if `const' does not conform to ANSI C. */ 43 | /* #undef const */ 44 | 45 | /* Define to `unsigned' if does not define. */ 46 | /* #undef size_t */ 47 | -------------------------------------------------------------------------------- /include/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_LOG_H 22 | #define __C_ICAP_LOG_H 23 | 24 | #include "request.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | int log_open(); 32 | void log_close(); 33 | void log_reset(); 34 | void log_flush(); 35 | 36 | void log_access(ci_request_t *req,int status); 37 | void log_server(ci_request_t *req, const char *format, ... ); 38 | void vlog_server(ci_request_t *req, const char *format, va_list ap); 39 | 40 | /* The followings can be used by modules */ 41 | CI_DECLARE_FUNC(char *) logformat_fmt(const char *name); 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /makefile.w32: -------------------------------------------------------------------------------- 1 | !include 2 | !include "c_icap.mak" 3 | 4 | LIBOS=os\win32\~ 5 | MODULES=services\echo\ services\url_check\ 6 | 7 | ALL_DIRS=$(LIBOS) 8 | DLL_ENTRY=os/win32/dll_entry.obj 9 | MOD_DLL_ENTRY=../../os/win32/dll_entry.obj 10 | 11 | c_icap_OBJS = request.obj proc_threads_queues.obj aserver.obj winnt_server.obj module.obj service.obj log.obj access.obj cfg_param.obj http_auth.obj 12 | 13 | all: c_icap.Dll c-icap.exe sub_modules 14 | 15 | .c.obj: 16 | $(cc) -Iinclude $(cdebug) $(cflags) $(cvarsmt) $(CI_DEFS) -I. -DUNICODE $*.c 17 | # $(cc) -Iinclude $(cdebug) $(cflags) $(cvarsdll) -I. -DUNICODE $*.c 18 | 19 | c_icap.Dll: 20 | @if EXIST c_icap_dll.mak $(MAKE) -f c_icap_dll.mak DLL_ENTRY=$(DLL_ENTRY) 21 | 22 | c-icap.exe: $(c_icap_OBJS) 23 | $(link) $(ldebug) $(conlflags) $(conlibsdll) user32.lib c_icap.lib $** /OUT:c-icap.exe 24 | 25 | # The following not needed any more. 26 | #$(LIBOS): 27 | # @cd $(@D) 28 | # @echo *** %CD% *** 29 | # @if NOT "%CD%"== "" $(MAKE) -f makefile.w32 $(makeopts) /$(MAKEFLAGS) 30 | # @cd ..\.. 31 | 32 | sub_modules: 33 | @for %%d in ($(MODULES)) do (cd %%d && $(MAKE) -f makefile.w32 DLL_ENTRY=$(MOD_DLL_ENTRY) $(makeopts) /$(MAKEFLAGS) & cd ..\..\ ) 34 | 35 | # @cd $(@D) 36 | # @echo *** %CD% *** 37 | # @if NOT "%CD%"== "" $(MAKE) -f makefile.w32 DLL_ENTRY=$(MOD_DLL_ENTRY) $(makeopts) /$(MAKEFLAGS) 38 | # @cd ..\.. 39 | 40 | clean: 41 | del *.obj *.exe *.lib *.dll os\win32\*.obj os\win32\*.lib 42 | @for %%d in ($(MODULES)) do (cd %%d && @$(MAKE) -f makefile.w32 clean & cd ..\..\ ) 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __COMMON_H 3 | #define __COMMON_H 4 | 5 | #ifdef HAVE_CONFIG_H 6 | #include "autoconf.h" 7 | #elif defined (_MSC_VER) 8 | #include "config-w32.h" 9 | #endif 10 | 11 | #ifdef HAVE_STDIO_H 12 | #include 13 | #endif 14 | 15 | #ifdef HAVE_STDLIB_H 16 | #include 17 | #endif 18 | 19 | #ifdef HAVE_STRINGS_H 20 | #include 21 | #endif 22 | 23 | #ifdef HAVE_STRING_H 24 | #include 25 | #endif 26 | 27 | #ifdef HAVE_SYS_STAT_H 28 | #include 29 | #endif 30 | 31 | #ifdef HAVE_SYS_TYPES_H 32 | #include 33 | #endif 34 | 35 | #ifdef HAVE_UNISTD_H 36 | #include 37 | #endif 38 | 39 | #if HAVE_SYS_PARAM_H 40 | #include 41 | #endif 42 | 43 | #ifdef HAVE_MALLOC_H 44 | #include 45 | #endif 46 | 47 | #ifdef HAVE_DLFCN_H 48 | #include 49 | #endif 50 | 51 | #ifdef HAVE_STDINT_H 52 | #include 53 | #endif 54 | 55 | #ifdef HAVE_LIMITS_H 56 | #include 57 | #endif 58 | 59 | #ifdef HAVE_ASSERT_H 60 | #include 61 | #endif 62 | 63 | #ifndef HAVE_STRNSTR 64 | #define strnstr(s, find, slen) ci_strnstr(s, find, slen) 65 | #endif 66 | 67 | #ifndef HAVE_STRNCASESTR 68 | #define strncasestr(s, find, slen) ci_strncasestr(s, find, slen) 69 | #endif 70 | 71 | #ifndef HAVE_STRCASESTR 72 | #define strcasestr(str, find) ci_strcasestr(str, find) 73 | #endif 74 | 75 | #ifdef HAVE_C11_ATOMICS 76 | #define CI_ATOMICS_INLINE 77 | #if defined(HAVE_INT128) && defined(HAVE_128BIT_ATOMICS) 78 | #define CI_ATOMICS_USE_128BIT 79 | #endif 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /contrib/get_file.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | my(%args); 4 | if($ENV{'REQUEST_METHOD'} eq "GET") { 5 | $query=$ENV{'QUERY_STRING'}; 6 | my(@line_args)=split(/&/,$query); 7 | 8 | for my $arg (@line_args){ 9 | $arg=~ s/\+/ /g; # replace + with spaces..... 10 | ($key,$val)=split(/=/,$arg); 11 | $val =~ s/%(..)/pack("c",hex($1))/ge; 12 | if($key eq "file" || $key eq "usename" || $key eq "content" ||$key eq "remove" ){ 13 | $args{$key}=$val; 14 | } 15 | 16 | } 17 | 18 | 19 | } 20 | else{ 21 | print "Content-type: text/html\n\n"; 22 | print "No Arguments....."; 23 | exit 1; 24 | } 25 | 26 | 27 | $filename="/srv/www/htdocs/downloads/".$args{"file"}; 28 | my(@stat)=stat $filename; 29 | binmode(STDOUT); 30 | if(open (F,"<$filename")){ 31 | print "Connection: close\n"; 32 | if($args{"content"}){ 33 | print "Content-Type: ".$args{"content"}."\n\\"; 34 | } 35 | else{ 36 | print "Content-Type: application/octet-stream\n"; 37 | } 38 | 39 | print "Content-Length: ".$stat[7]."\n"; 40 | if($args{"usename"}){ 41 | print "Content-Disposition: attachment; filename=".$args{"usename"}."\n\n"; 42 | } 43 | else { 44 | print "Content-Disposition: attachment; filename=".$args{"file"}."\n\n"; 45 | } 46 | 47 | while($len=sysread( F, $buf,512)){ 48 | print $buf; 49 | } 50 | close F; 51 | if($args{"remove"}==1){ 52 | unlink $filename; 53 | } 54 | } 55 | else { 56 | print "Connection: close\n"; 57 | print "Content-Type: text/html\n\n"; 58 | print "

Error

\n"; 59 | print "The file ".$args{"file"}." does not exists in the server
\n"; 60 | print "Please contact to the administrator for more info.\n\n"; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /include/dlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_DLIB_H 22 | #define __C_ICAP_DLIB_H 23 | 24 | #include "c-icap.h" 25 | #ifdef _WIN32 26 | #include 27 | #endif 28 | 29 | #ifdef __cplusplus 30 | extern "C" 31 | { 32 | #endif 33 | 34 | #ifndef _WIN32 35 | #define CI_DLIB_HANDLE void * 36 | #else 37 | #define CI_DLIB_HANDLE HMODULE 38 | #endif 39 | 40 | CI_DECLARE_FUNC(CI_DLIB_HANDLE) ci_module_load(const char *module_file, const char *default_path); 41 | CI_DECLARE_FUNC(void *) ci_module_sym(CI_DLIB_HANDLE handle,const char *symbol); 42 | CI_DECLARE_FUNC(int) ci_module_unload(CI_DLIB_HANDLE handle,const char *name); 43 | 44 | /*Utility functions */ 45 | CI_DECLARE_FUNC(int) ci_dlib_entry(const char *name,const char *file, CI_DLIB_HANDLE handle, int forceUnload); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif /*__C_ICAP_DLIB_H*/ 52 | -------------------------------------------------------------------------------- /include/access.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_ACCESS_H 22 | #define __C_ICAP_ACCESS_H 23 | 24 | #include "c-icap.h" 25 | #include "request.h" 26 | #include "net_io.h" 27 | 28 | 29 | #ifdef __cplusplus 30 | extern "C" 31 | { 32 | #endif 33 | 34 | /**************************************************/ 35 | /*Basic authentication method definitions ...... */ 36 | 37 | #define HTTP_MAX_PASS_LEN 256 38 | 39 | struct http_basic_auth_data { 40 | char http_user[MAX_USERNAME_LEN+1]; 41 | char http_pass[HTTP_MAX_PASS_LEN+1]; 42 | }; 43 | 44 | 45 | int access_reset(); 46 | int http_authorize(ci_request_t *req, char *method); 47 | int http_authenticate(ci_request_t *req, char *method); 48 | int access_check_client(ci_request_t *req); 49 | int access_check_request(ci_request_t *req); 50 | int access_authenticate_request(ci_request_t *req); 51 | int access_check_logging(ci_request_t *req); 52 | 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /include/registry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_REGISTRY_H 21 | #define __C_ICAP_REGISTRY_H 22 | 23 | #include "c-icap.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | CI_DECLARE_FUNC(int) ci_registry_create(const char *name); 31 | CI_DECLARE_FUNC(void) ci_registry_clean(); 32 | 33 | CI_DECLARE_FUNC(int) ci_registry_iterate(const char *name, void *data, int (*fn)(void *data, const char *label, const void *)); 34 | CI_DECLARE_FUNC(int) ci_registry_add_item(const char *name, const char *label, const void *obj); 35 | CI_DECLARE_FUNC(const void *) ci_registry_get_item(const char *name, const char *label); 36 | 37 | CI_DECLARE_FUNC(int) ci_registry_get_id(const char *name); 38 | CI_DECLARE_FUNC(int) ci_registry_id_iterate(int reg_id, void *data, int (*fn)(void *data, const char *label, const void *)); 39 | CI_DECLARE_FUNC(const void *) ci_registry_id_get_item(int reg_id, const char *label); 40 | 41 | 42 | #ifdef __cplusplus 43 | } /*extern "C"*/ 44 | #endif 45 | 46 | #endif /*__REGISTRY_H*/ 47 | -------------------------------------------------------------------------------- /os/win32/proc_mutex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #include "c-icap.h" 22 | #include 23 | #include "debug.h" 24 | #include "proc_mutex.h" 25 | #include 26 | 27 | int ci_proc_mutex_init(ci_proc_mutex_t * mutex, const char *name) 28 | { 29 | snprintf(mutex->name, CI_PROC_MUTEX_NAME_SIZE, "Local\%s", name); 30 | /*TODO: use named mutex*/ 31 | if ((mutex->id = CreateMutex(NULL, FALSE, NULL)) == NULL) { 32 | ci_debug_printf(1, "Error creating mutex:%d\n", GetLastError()); 33 | return 0; 34 | } 35 | return 1; 36 | } 37 | 38 | int ci_proc_mutex_destroy(ci_proc_mutex_t * mutex) 39 | { 40 | CloseHandle(mutex->id); 41 | return 1; 42 | } 43 | 44 | int ci_proc_mutex_lock(ci_proc_mutex_t * mutex) 45 | { 46 | WaitForSingleObject(mutex->id, INFINITE); 47 | return 1; 48 | } 49 | 50 | int ci_proc_mutex_unlock(ci_proc_mutex_t * mutex) 51 | { 52 | ReleaseMutex(mutex->id); 53 | return 1; 54 | } 55 | 56 | void ci_proc_mutex_recover_after_crash() 57 | { 58 | /*Nothing to do*/ 59 | } 60 | -------------------------------------------------------------------------------- /utils/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | CONFIGDIR=@sysconfdir@ 3 | PKGLIBDIR=@pkglibdir@ 4 | MODULESDIR=$(pkglibdir)/ 5 | SERVICESDIR=$(pkglibdir)/ 6 | #CONFIGDIR=$(sysconfdir)/ 7 | LOGDIR=$(localstatedir)/log/ 8 | SOCKDIR=/var/run/c-icap 9 | 10 | RPATH_FLAG= 11 | if USE_RPATH 12 | RPATH_FLAG+=-rpath @libdir@ 13 | endif 14 | 15 | #UTILS_LDADD = @THREADS_LDADD@ @DL_ADD_FLAG@ @ZLIB_LNDIR_LDADD@ @BZLIB_LNDIR_LDADD@ @BROTLI_LNDIR_LDADD@ @PCRE_LNDIR_LDADD@ @OPENSSL_LNDIR_LDADD@ 16 | UTILS_LDADD = @THREADS_LDADD@ @DL_ADD_FLAG@ $(EXT_PROGRAMS_MKLIB) 17 | 18 | bin_PROGRAMS = c-icap-client c-icap-stretch 19 | if USEBDB 20 | bin_PROGRAMS += c-icap-mkbdb 21 | endif 22 | 23 | if USELMDB 24 | bin_PROGRAMS += c-icap-mklmdb 25 | endif 26 | 27 | #other ..... 28 | c_icap_client_SOURCES = c-icap-client.c 29 | c_icap_client_CFLAGS= -I$(top_srcdir)/include/ -I$(top_srcdir)/ -I$(top_builddir)/include/ 30 | c_icap_client_LDADD= $(top_builddir)/libicapapi.la $(UTILS_LDADD) 31 | c_icap_client_LDFLAGS = -rdynamic $(RPATH_FLAG) @THREADS_LDFLAGS@ 32 | 33 | c_icap_mkbdb_SOURCES = c-icap-mkbdb.c 34 | c_icap_mkbdb_CFLAGS= -I$(top_srcdir)/include/ -I$(top_srcdir)/ -I$(top_builddir)/include/ @BDB_ADD_FLAG@ 35 | c_icap_mkbdb_LDADD= $(top_builddir)/libicapapi.la $(UTILS_LDADD) @BDB_ADD_LDADD@ 36 | c_icap_mkbdb_LDFLAGS = -rdynamic $(RPATH_FLAG) @THREADS_LDFLAGS@ 37 | 38 | if USELMDB 39 | c_icap_mklmdb_SOURCES = c-icap-mklmdb.c 40 | c_icap_mklmdb_CFLAGS= -I$(top_srcdir)/include/ -I$(top_srcdir)/ -I$(top_builddir)/include/ @LMDB_ADD_FLAG@ 41 | c_icap_mklmdb_LDADD= $(top_builddir)/libicapapi.la $(UTILS_LDADD) @LMDB_ADD_LDADD@ 42 | c_icap_mklmdb_LDFLAGS = -rdynamic $(RPATH_FLAG) @THREADS_LDFLAGS@ 43 | endif 44 | 45 | c_icap_stretch_SOURCES = c-icap-stretch.c 46 | c_icap_stretch_CFLAGS= -I$(top_srcdir)/include/ -I$(top_srcdir)/ -I$(top_builddir)/include/ 47 | c_icap_stretch_LDADD = $(top_builddir)/libicapapi.la $(UTILS_LDADD) 48 | c_icap_stretch_LDFLAGS= -rdynamic $(RPATH_FLAG) @THREADS_LDFLAGS@ 49 | 50 | 51 | -------------------------------------------------------------------------------- /docs/man/c-icap-mkbdb.8.in: -------------------------------------------------------------------------------- 1 | .TH c-icap-mkbdb 8 "@PACKAGE_STRING@" 2 | .SH NAME 3 | c-icap-mkbdb - simple utility to create Berkeley DB lookup tables 4 | .SH SYNOPSIS 5 | .B c-icap-mkbdb 6 | [ 7 | .B \-V 8 | ] 9 | [ 10 | .B \-VV 11 | ] 12 | [ 13 | .B \-d debug_level 14 | ] 15 | [ 16 | .B \-i file.txt 17 | ] 18 | [ 19 | .B \-o file.db 20 | ] 21 | [ 22 | .B \-t string|int|ip 23 | ] 24 | [ 25 | .B \-v string|int|ip 26 | ] 27 | [ 28 | .B \-\-dump 29 | ] 30 | .SH DESCRIPTION 31 | .B c-icap-mkbdb 32 | utility can be used to create Berkeley DB based lookup tables for use with the c-icap server. 33 | .SH OPTIONS 34 | .IP "-V" 35 | Print version 36 | .IP "-VV" 37 | Print build informations 38 | .IP "-d debug_level" 39 | The debug level 40 | .IP "-i file.txt" 41 | The file contains the data (required). The line format of this file must be: 42 | .br 43 | .I "key: value1, value2, ...." 44 | .IP "-o file.db" 45 | The database to be created 46 | .IP "-t string|int|ip" 47 | The type of the key. Select 48 | .B "string" 49 | for string keys, 50 | .B "int" 51 | for integer keys or 52 | .B "ip" 53 | for using IP addresses as keys. The "string" is the default. 54 | .IP "-v string|int|ip" 55 | The type of the values. The "string" is the default. 56 | .IP "-p page_size[k]" 57 | The page size to use. Can not be less than 512 bytes or greater than 64k. 58 | Read berkeleyDB manual for default values. 59 | .IP "--btree" 60 | Use B-Tree as access method for the database. By default uses Hash. 61 | .IP "--dump" 62 | Do not update the database just dump it to the screen. 63 | .SH EXAMPLES 64 | .TP 65 | c-icap-mkbdb \-o keys \-i keys.txt 66 | It builds the 67 | .B keys 68 | Berkeley DB database, using string type for keys and values. 69 | .TP 70 | c-icap-mkbdb \-o keys \-\-dump 71 | Dump the contents of the keys database 72 | .SH SEE ALSO 73 | .BR c-icap "(8)" 74 | .BR c-icap-client "(8)" 75 | .BR c-icap-stretch "(8)" 76 | .BR c-icap-config "(8)" 77 | .BR c-icap-libicapapi-config "(8)" 78 | .SH AUTHOR 79 | Tsantilas Christos 80 | -------------------------------------------------------------------------------- /include/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_DEBUG_H 22 | #define __C_ICAP_DEBUG_H 23 | 24 | #include "c-icap.h" 25 | #include 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" 30 | { 31 | #endif 32 | 33 | CI_DECLARE_DATA extern int CI_DEBUG_LEVEL; 34 | CI_DECLARE_DATA extern int CI_DEBUG_STDOUT; 35 | 36 | 37 | CI_DECLARE_DATA extern void (*__vlog_error)(void *req, const char *format, va_list ap); 38 | CI_DECLARE_FUNC(void) __ldebug_printf(int i,const char *format, ...); 39 | 40 | CI_DECLARE_DATA extern void (*__log_error)(void *req, const char *format,... ); 41 | 42 | #ifdef _MSC_VER 43 | #define ci_debug_printf __ldebug_printf 44 | #else 45 | #define ci_debug_printf(i, args...) if(i<=CI_DEBUG_LEVEL){ if(__log_error) (*__log_error)(NULL,args); if(CI_DEBUG_STDOUT) printf(args);} 46 | #endif 47 | 48 | CI_DECLARE_DATA extern void (*__ci_debug_abort)(const char *file, int line, const char *function, const char *mesg); 49 | #define _CI_ASSERT(expression) {if (!(expression)) (*__ci_debug_abort)(__FILE__, __LINE__, __func__, #expression);} 50 | 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif /*__C_ICAP_DEBUG_H*/ 57 | -------------------------------------------------------------------------------- /c-icap-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prefix=@prefix@ 4 | 5 | PKGLIBDIR=@PKGLIBDIR@/ 6 | LIBDIR=@LIBDIR@/ 7 | CONFIGDIR=@SYSCONFDIR@/ 8 | DATADIR=@PKGDATADIR@/ 9 | #LOGDIR= 10 | SOCKDIR=@SOCKDIR@ 11 | 12 | INCDIR=@INCLUDEDIR@ 13 | INCDIR2=@PKGINCLUDEDIR@ 14 | 15 | VERSION=@PACKAGE_VERSION@ 16 | CICAPCFLAGS="@CFLAGS@" 17 | CICAPLDFLAGS= 18 | CICAPLIBS= 19 | CFLAGS="@MODULES_CFLAGS@ @CFLAGS@" 20 | LIBS="@MODULES_LIBADD@" 21 | LDFLAGS="" 22 | 23 | 24 | usage() 25 | { 26 | cat < 26 | #include "request.h" 27 | #include "txt_format.h" 28 | #include "body.h" 29 | 30 | #ifdef __cplusplus 31 | extern "C" 32 | { 33 | #endif 34 | 35 | CI_DECLARE_FUNC (ci_membuf_t *) 36 | ci_txt_template_build_content(const ci_request_t *req, 37 | const char *SERVICE_NAME, 38 | const char *TEMPLATE_NAME, struct ci_fmt_entry *user_table); 39 | CI_DECLARE_FUNC (void) ci_txt_template_reset(void); 40 | CI_DECLARE_FUNC (int) ci_txt_template_init(void); 41 | CI_DECLARE_FUNC (void) ci_txt_template_close(void); 42 | CI_DECLARE_FUNC (void) ci_txt_template_set_dir(const char *dir); 43 | CI_DECLARE_FUNC (void) ci_txt_template_set_default_lang(const char *lang); 44 | 45 | CI_DECLARE_DATA extern const char *TEMPLATE_DIR; 46 | CI_DECLARE_DATA extern const char *TEMPLATE_DEF_LANG; 47 | CI_DECLARE_DATA extern int TEMPLATE_RELOAD_TIME; // Default time is one hour, this variable is in seconds 48 | CI_DECLARE_DATA extern int TEMPLATE_CACHE_SIZE; // How many templates can be cached 49 | CI_DECLARE_DATA extern int TEMPLATE_MEMBUF_SIZE; // Max memory for txtTemplate to expand template into txt 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif /*__C_ICAP_TXTTEMPLATE_H*/ 55 | -------------------------------------------------------------------------------- /include/openssl_support.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2018 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_OPENSSL_SUPPORT_H 21 | #define __C_ICAP_OPENSSL_SUPPORT_H 22 | 23 | #include "net_io_ssl.h" 24 | #include "port.h" 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" 29 | { 30 | #endif 31 | /** 32 | \ingroup TLS 33 | \brief Returns the openSSL BIO attached to the given connection object 34 | * For the TLS client connections this is the connect BIO built from a 35 | * BIO_s_connect call. 36 | * For the TLS server connections this is the socket BIO built from a 37 | * BIO_do_accept call. 38 | */ 39 | CI_DECLARE_FUNC(BIO *) ci_openssl_connection_BIO(ci_connection_t *conn); 40 | 41 | /** 42 | \ingroup TLS 43 | \brief Return the openSSL SSL object of the given TLS connection 44 | */ 45 | CI_DECLARE_FUNC(SSL *) ci_openssl_connection_SSL(ci_connection_t *conn); 46 | 47 | /** 48 | \ingroup TLS 49 | \brief Return the SSL_CTX object of the given TLS connection 50 | */ 51 | CI_DECLARE_FUNC(SSL_CTX *) ci_openssl_connection_SSL_CTX(ci_connection_t *conn); 52 | 53 | /** 54 | \ingroup TLS 55 | \brief Converts to the equivalent SSL_CTX object the given c-icap tls context 56 | */ 57 | CI_DECLARE_FUNC(SSL_CTX *) ci_openssl_context_SSL_CTX(ci_tls_pcontext_t pcontext); 58 | 59 | /** 60 | \ingroup TLS 61 | \brief Returns the openSSL TLS_CTX object of the given listening port 62 | */ 63 | CI_DECLARE_FUNC(SSL_CTX *) ci_openssl_port_SSL_CTX(ci_port_t *port); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /tests/test_atomics_cplusplus.cc: -------------------------------------------------------------------------------- 1 | #define CI_ATOMICS_INLINE 2 | #include "atomic.h" 3 | #include "cfg_param.h" 4 | #include "ci_threads.h" 5 | #include "debug.h" 6 | 7 | #include 8 | 9 | 10 | ci_thread_cond_t CND; 11 | ci_thread_mutex_t CNDMTX; 12 | 13 | uint64_t at_c = 0; 14 | 15 | int run_thread() 16 | { 17 | ci_thread_mutex_lock(&CNDMTX); 18 | ci_thread_cond_wait(&CND, &CNDMTX); 19 | ci_thread_mutex_unlock(&CNDMTX); 20 | for(int i = 0; i < 10000; i++) 21 | ci_atomic_add_u64(&at_c, 1); 22 | return 1; 23 | } 24 | 25 | int threadsnum = 100; 26 | int USE_DEBUG_LEVEL = -1; 27 | static struct ci_options_entry options[] = { 28 | { 29 | "-d", "debug_level", &USE_DEBUG_LEVEL, ci_cfg_set_int, 30 | "The debug level" 31 | }, 32 | { 33 | "-t", "threads", &threadsnum, ci_cfg_set_int, 34 | "The numbers of threads to use" 35 | }, 36 | {NULL,NULL,NULL,NULL,NULL} 37 | }; 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | int i; 42 | ci_thread_t *threads; 43 | CI_DEBUG_STDOUT = 1; 44 | 45 | ci_cfg_lib_init(); 46 | ci_mem_init(); 47 | ci_atomics_init(); 48 | 49 | if (!ci_args_apply(argc, argv, options)) { 50 | ci_args_usage(argv[0], options); 51 | exit(-1); 52 | } 53 | 54 | if (USE_DEBUG_LEVEL >= 0) 55 | CI_DEBUG_LEVEL = USE_DEBUG_LEVEL; 56 | 57 | ci_thread_mutex_init(&CNDMTX); 58 | ci_thread_cond_init(&CND); 59 | 60 | threads = new ci_thread_t[threadsnum]; 61 | for (i = 0; i < threadsnum; i++) threads[i] = 0; 62 | for (i = 0; i < threadsnum; i++) { 63 | ci_debug_printf(8, "Thread %d started\n", i); 64 | ci_thread_create(&(threads[i]), 65 | (void *(*)(void *)) run_thread, 66 | (void *) NULL /*data*/); 67 | } 68 | 69 | ci_debug_printf(2, "Threads started, wait some time to be ready\n"); 70 | sleep(1); 71 | ci_debug_printf(2, "kick threads\n"); 72 | ci_thread_cond_broadcast(&CND); 73 | 74 | for (i = 0; i < threadsnum; i++) { 75 | ci_thread_join(threads[i]); 76 | ci_debug_printf(6, "Thread %d exited\n", i); 77 | } 78 | 79 | delete threads; 80 | 81 | ci_debug_printf(1, "Atomic add result : %lu\n", at_c) 82 | 83 | ci_thread_mutex_destroy(&CNDMTX); 84 | ci_thread_cond_destroy(&CND); 85 | return 0; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /os/unix/dlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "debug.h" 23 | #include "dlib.h" 24 | 25 | #ifdef HAVE_DLFCN_H 26 | 27 | void *ci_module_load(const char *module_file, const char *default_path) 28 | { 29 | char path[CI_MAX_PATH]; 30 | void *handle; 31 | int requiredLen; 32 | #if defined __CYGWIN__ 33 | if (default_path && module_file[0] != '/' && module_file[0] != '\\' && module_file[1] != ':') 34 | #else 35 | if (default_path && module_file[0] != '/') 36 | #endif 37 | requiredLen = snprintf(path, CI_MAX_PATH, "%s/%s", default_path, module_file); 38 | else 39 | requiredLen = snprintf(path, sizeof(path), "%s", module_file); 40 | 41 | if (requiredLen >= CI_MAX_PATH) { 42 | ci_debug_printf(1, "Error: too long filename, truncated to '%s'\n", path); 43 | return NULL; 44 | } 45 | 46 | handle = dlopen(path, RTLD_NOW | RTLD_GLOBAL); 47 | 48 | if (!handle) { 49 | char *error_str = dlerror (); 50 | ci_debug_printf(1, "Error loading module %s:%s\n", module_file, error_str); 51 | return NULL; 52 | } 53 | return handle; 54 | } 55 | 56 | void *ci_module_sym(void *handle, const char *symbol) 57 | { 58 | return dlsym(handle, symbol); 59 | } 60 | 61 | 62 | int ci_module_unload(void *handle, const char *name) 63 | { 64 | int ret; 65 | ret = dlclose(handle); 66 | if (ret == 1) { 67 | ci_debug_printf(1, "Error unloading module:%s\n", name); 68 | return 0; 69 | } 70 | return 1; 71 | } 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /include/http_server.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2022 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | /** 21 | \defgroup HTTP_SERVER API 22 | \ingroup API 23 | * API for implementing utility functions to register and use c-icap's 24 | * HTTP server services 25 | */ 26 | 27 | #ifndef __C_ICAP_HTTP_SERVER_H 28 | #define __C_ICAP_HTTP_SERVER_H 29 | #include "c-icap.h" 30 | #include "request.h" 31 | #include "request_util.h" 32 | #include "body.h" 33 | 34 | #ifdef __cplusplus 35 | extern "C" 36 | { 37 | #endif 38 | 39 | CI_DECLARE_FUNC(void) ci_http_server_register_service(const char *path, const char *descr, int (*handler)(ci_request_t *req), unsigned); 40 | CI_DECLARE_FUNC(void) ci_http_server_response_set_status(ci_request_t *req, int status); 41 | 42 | static inline ci_membuf_t *ci_http_server_response_body(ci_request_t *req) { 43 | _CI_ASSERT(req); 44 | return (ci_membuf_t *)req->service_data; 45 | } 46 | 47 | static inline ci_headers_list_t *ci_http_server_request_headers(ci_request_t *req) { 48 | _CI_ASSERT(req); 49 | return ci_icap_request_headers(req); 50 | } 51 | 52 | static inline const char *ci_http_server_request_get_header(ci_request_t *req, const char *header) { 53 | ci_headers_list_t *req_header = ci_http_server_request_headers(req); 54 | if (!req_header) 55 | return NULL; 56 | return ci_headers_search(req_header, header); 57 | } 58 | 59 | static inline const char *ci_http_server_response_add_header(ci_request_t *req, const char *header) { 60 | _CI_ASSERT(req); 61 | return ci_icap_add_xheader(req, header); 62 | } 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /modules/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | 3 | # lib_LTLIBRARIES=sys_logger.la perl_handler.la 4 | 5 | pkglib_LTLIBRARIES= sys_logger.la dnsbl_tables.la shared_cache.la 6 | if USEPERL 7 | pkglib_LTLIBRARIES += perl_handler.la 8 | endif 9 | 10 | if USEBDB 11 | pkglib_LTLIBRARIES += bdb_tables.la 12 | endif 13 | 14 | if USELDAP 15 | pkglib_LTLIBRARIES += ldap_module.la 16 | endif 17 | 18 | if USEMEMCACHED 19 | pkglib_LTLIBRARIES += memcached_cache.la 20 | endif 21 | 22 | if USELMDB 23 | pkglib_LTLIBRARIES += lmdb_tables.la 24 | endif 25 | 26 | AM_CPPFLAGS=-I$(top_srcdir)/ -I$(top_srcdir)/include/ -I$(top_builddir)/include/ 27 | 28 | if ISCYGWIN 29 | MODS_LIB_ADD=$(top_builddir)/libicapapi.la $(top_builddir)/libcicap.la 30 | else 31 | MODS_LIB_ADD= 32 | endif 33 | 34 | sys_logger_la_LIBADD = $(MODS_LIB_ADD) 35 | sys_logger_la_CFLAGS= @MODULES_CFLAGS@ 36 | sys_logger_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 37 | sys_logger_la_SOURCES = sys_logger.c 38 | 39 | dnsbl_tables_la_LIBADD = $(MODS_LIB_ADD) 40 | dnsbl_tables_la_CFLAGS= @MODULES_CFLAGS@ 41 | dnsbl_tables_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 42 | dnsbl_tables_la_SOURCES = dnsbl_tables.c 43 | 44 | perl_handler_la_LIBADD = $(MODS_LIB_ADD) @perllib@ -L@perlcore@ -lperl 45 | perl_handler_la_CFLAGS= @MODULES_CFLAGS@ @perlccflags@ -I@perlcore@ 46 | perl_handler_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ @perlldflags@ 47 | perl_handler_la_SOURCES = perl_handler.c 48 | 49 | 50 | bdb_tables_la_LIBADD = $(MODS_LIB_ADD) @BDB_ADD_LDADD@ 51 | bdb_tables_la_CFLAGS= @MODULES_CFLAGS@ @BDB_ADD_FLAG@ 52 | bdb_tables_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 53 | bdb_tables_la_SOURCES = bdb_tables.c 54 | 55 | lmdb_tables_la_LIBADD = $(MODS_LIB_ADD) @LMDB_ADD_LDADD@ 56 | lmdb_tables_la_CFLAGS= @MODULES_CFLAGS@ @LMDB_ADD_FLAG@ 57 | lmdb_tables_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 58 | lmdb_tables_la_SOURCES = lmdb_tables.c 59 | 60 | ldap_module_la_LIBADD = $(MODS_LIB_ADD) @LDAP_ADD_LDADD@ 61 | ldap_module_la_CFLAGS= @MODULES_CFLAGS@ @LDAP_ADD_FLAG@ 62 | ldap_module_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 63 | ldap_module_la_SOURCES = ldap_module.c 64 | 65 | memcached_cache_la_LIBADD= $(MODS_LIB_ADD) @MEMCACHED_ADD_LDADD@ 66 | memcached_cache_la_CFLAGS= @MODULES_CFLAGS@ @MEMCACHED_ADD_FLAG@ 67 | memcached_cache_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 68 | memcached_cache_la_SOURCES= memcached.c 69 | 70 | shared_cache_la_LIBADD= $(MODS_LIB_ADD) 71 | shared_cache_la_CFLAGS= 72 | shared_cache_la_LDFLAGS= -module -avoid-version @LIBS_LDFLAGS@ 73 | shared_cache_la_SOURCES= shared_cache.c 74 | -------------------------------------------------------------------------------- /include/proc_mutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_PROC_MUTEX_H 22 | #define __C_ICAP_PROC_MUTEX_H 23 | 24 | #include "c-icap.h" 25 | #if defined (_WIN32) 26 | #include 27 | #endif 28 | 29 | #ifdef __cplusplus 30 | extern "C" 31 | { 32 | #endif 33 | 34 | typedef struct ci_proc_mutex ci_proc_mutex_t; 35 | 36 | typedef struct ci_proc_mutex_scheme { 37 | int (*proc_mutex_init)(ci_proc_mutex_t *mutex, const char *name); 38 | int (*proc_mutex_destroy)(ci_proc_mutex_t *mutex); 39 | int (*proc_mutex_lock)(ci_proc_mutex_t *mutex); 40 | int (*proc_mutex_unlock)(ci_proc_mutex_t *mutex); 41 | int (*proc_mutex_print_info)(ci_proc_mutex_t *mutex, char *buf, size_t buf_size); 42 | const char *name; 43 | } ci_proc_mutex_scheme_t; 44 | 45 | #define CI_PROC_MUTEX_NAME_SIZE 64 46 | 47 | struct ci_proc_mutex { 48 | char name[CI_PROC_MUTEX_NAME_SIZE]; 49 | 50 | #if defined(_WIN32) 51 | 52 | HANDLE id; 53 | 54 | #else 55 | 56 | const ci_proc_mutex_scheme_t *scheme; 57 | void *data; 58 | #endif 59 | }; 60 | 61 | CI_DECLARE_FUNC(int) ci_proc_mutex_init(ci_proc_mutex_t *mutex, const char *name); 62 | CI_DECLARE_FUNC(int) ci_proc_mutex_init2(ci_proc_mutex_t *mutex, const char *name, const char *scheme); 63 | CI_DECLARE_FUNC(int) ci_proc_mutex_lock(ci_proc_mutex_t *mutex); 64 | CI_DECLARE_FUNC(int) ci_proc_mutex_unlock(ci_proc_mutex_t *mutex); 65 | CI_DECLARE_FUNC(int) ci_proc_mutex_destroy(ci_proc_mutex_t *mutex); 66 | CI_DECLARE_FUNC(int) ci_proc_mutex_print_info(ci_proc_mutex_t *mutex, char *buf, size_t size); 67 | 68 | CI_DECLARE_FUNC(int) ci_proc_mutex_set_scheme(const char *scheme); 69 | CI_DECLARE_FUNC(const ci_proc_mutex_scheme_t *) ci_proc_mutex_default_scheme(); 70 | 71 | CI_DECLARE_FUNC(void) ci_proc_mutex_recover_after_crash(); 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /os/win32/dlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #include "c-icap.h" 22 | #include "debug.h" 23 | #include "dlib.h" 24 | 25 | 26 | HMODULE ci_module_load(const char *module_file, const char *default_path) 27 | { 28 | HMODULE handle; 29 | WCHAR path[CI_MAX_PATH]; 30 | WCHAR c; 31 | int len, i = 0; 32 | DWORD load_flags = LOAD_WITH_ALTERED_SEARCH_PATH; 33 | 34 | if (module_file[0] != '/' && default_path) { 35 | len = snprintf(path, CI_MAX_PATH, "%s/%s", default_path, module_file); 36 | if (len >= CI_MAX_PATH) { 37 | ci_debug_printf(1, 38 | "Path name len of %s+%s is greater than " 39 | "MAXPATH:%d, not loading\n", 40 | default_path, module_file, CI_MAX_PATH); 41 | return NULL; 42 | } 43 | } else { 44 | if (module_file[0] != '/') 45 | load_flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS; 46 | strncpy(path, module_file, CI_MAX_PATH - 1); 47 | path[CI_MAX_PATH - 1] = '\0'; 48 | } 49 | 50 | handle = LoadLibraryEx(filename, NULL, load_flags); 51 | if (!handle) 52 | handle = LoadLibraryEx(filename, NULL, NULL); 53 | 54 | if (!handle) { 55 | ci_debug_printf(1, "Error loading module %s:%d\n", module_file, 56 | GetLastError()); 57 | return NULL; 58 | } 59 | return handle; 60 | } 61 | 62 | void *ci_module_sym(HMODULE handle, const char *symbol) 63 | { 64 | return GetProcAddress(handle, symbol); 65 | } 66 | 67 | 68 | int ci_module_unload(HMODULE handle, const char *name) 69 | { 70 | int ret; 71 | ret = FreeLibrary(handle); 72 | if (ret == 1) { 73 | ci_debug_printf(1, "Error unloading module:%s\n", name); 74 | return 0; 75 | } 76 | return 1; 77 | } 78 | -------------------------------------------------------------------------------- /include/shared_mem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_SHARED_MEM_H 22 | #define __C_ICAP_SHARED_MEM_H 23 | 24 | #include "c-icap.h" 25 | 26 | #if defined (_WIN32) 27 | #include 28 | #endif 29 | 30 | #ifdef __cplusplus 31 | extern "C" 32 | { 33 | #endif 34 | 35 | typedef struct ci_shared_mem_id ci_shared_mem_id_t; 36 | 37 | typedef struct ci_shared_mem_scheme { 38 | void *(*shared_mem_create)(ci_shared_mem_id_t *id, const char *name, int size); 39 | void *(*shared_mem_attach)(ci_shared_mem_id_t *id); 40 | int (*shared_mem_detach)(ci_shared_mem_id_t *id); 41 | int (*shared_mem_destroy)(ci_shared_mem_id_t *id); 42 | int (*shared_mem_print_info)(ci_shared_mem_id_t *id, char *buf, size_t buf_size); 43 | const char *name; 44 | } ci_shared_mem_scheme_t; 45 | 46 | 47 | #define CI_SHARED_MEM_NAME_SIZE 64 48 | struct ci_shared_mem_id { 49 | char name[CI_SHARED_MEM_NAME_SIZE]; 50 | void *mem; 51 | size_t size; 52 | 53 | #if defined (_WIN32) 54 | HANDLE id; 55 | #else 56 | 57 | const ci_shared_mem_scheme_t *scheme; 58 | union { 59 | #if defined (USE_POSIX_SHARED_MEM) 60 | struct { 61 | int fd; 62 | } posix; 63 | #endif 64 | #if defined (USE_SYSV_IPC) 65 | struct { 66 | int id; 67 | } sysv; 68 | #endif 69 | int id_; 70 | }; 71 | #endif 72 | }; 73 | 74 | CI_DECLARE_FUNC(void) *ci_shared_mem_create(ci_shared_mem_id_t *id, const char *name, int size); 75 | CI_DECLARE_FUNC(void) *ci_shared_mem_attach(ci_shared_mem_id_t *id); 76 | CI_DECLARE_FUNC(int) ci_shared_mem_detach(ci_shared_mem_id_t *id); 77 | CI_DECLARE_FUNC(int) ci_shared_mem_destroy(ci_shared_mem_id_t *id); 78 | CI_DECLARE_FUNC(int) ci_shared_mem_print_info(ci_shared_mem_id_t *id, char *buf, size_t buf_size); 79 | 80 | CI_DECLARE_FUNC(int) ci_shared_mem_set_scheme(const char *name); 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/txt_format.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2009 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_TXT_FORMAT_H 22 | #define __C_ICAP_TXT_FORMAT_H 23 | 24 | #include "request.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | /** 32 | * \defgroup FORMATING Text formating api 33 | * \ingroup API 34 | * Functions and structures used for text formating 35 | */ 36 | 37 | /** 38 | * \brief This structure used to implement text formating directives 39 | * \ingroup FORMATING 40 | */ 41 | struct ci_fmt_entry { 42 | /** 43 | * \brief The formating directive (eg "%a") 44 | */ 45 | const char *directive; 46 | 47 | /** 48 | * \brief A short description 49 | */ 50 | const char *description; 51 | 52 | /** 53 | * \brief Pointer to the function which implements the text formating for this directive 54 | * \param req_data Pointer to the current request structure 55 | * \param buf The output buffer 56 | * \param len The length of the buffer 57 | * \param param Parameter of the directive 58 | * \return Non zero on success, zero on error 59 | */ 60 | int (*format)(ci_request_t *req_data, char *buf, int len, const char *param); 61 | }; 62 | 63 | /** 64 | * \brief Produces formated text based on template text. 65 | * \ingroup FORMATING 66 | * \param req_data The current request 67 | * \param fmt The format string 68 | * \param buffer The output buffer 69 | * \param len The length of the output buffer 70 | * \param user_table An array of user defined directives 71 | * \return the number of written bytes 72 | * 73 | * This function uses the internal formating directives table. Also the user can define his own table. 74 | */ 75 | CI_DECLARE_FUNC(int) ci_format_text(ci_request_t *req_data, const char *fmt, char *buffer, int len, 76 | struct ci_fmt_entry *user_table); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /dlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "dlib.h" 23 | 24 | 25 | struct dlib_entry { 26 | char *file; 27 | char *name; 28 | CI_DLIB_HANDLE handle; 29 | int forceUnload; 30 | struct dlib_entry *next; 31 | }; 32 | 33 | struct dlib_entry *dlib_list = NULL; 34 | 35 | 36 | int ci_dlib_entry(const char *name, const char *file, CI_DLIB_HANDLE handle, int forceUnload) 37 | { 38 | struct dlib_entry *dl_e, *dl_cur; 39 | 40 | if (!name || !file || !handle) 41 | return 0; 42 | dl_e = malloc(sizeof(struct dlib_entry)); 43 | if (!dl_e) 44 | return 0; 45 | dl_e->file = strdup(file); 46 | if (!dl_e->file) { 47 | free(dl_e); 48 | return 0; 49 | } 50 | dl_e->name = strdup(name); 51 | if (!dl_e->name) { 52 | free(dl_e->file); 53 | free(dl_e); 54 | return 0; 55 | } 56 | dl_e->handle = handle; 57 | dl_e->forceUnload = forceUnload; 58 | dl_e->next = NULL; 59 | 60 | if (dlib_list == NULL) { 61 | dlib_list = dl_e; 62 | return 1; 63 | } 64 | dl_cur = dlib_list; 65 | while (dl_cur->next != NULL) 66 | dl_cur = dl_cur->next; 67 | 68 | dl_cur->next = dl_e; 69 | return 1; 70 | } 71 | 72 | 73 | 74 | int ci_dlib_closeall() 75 | { 76 | struct dlib_entry *dl_e, *dl_cur; 77 | int ret, error = 0; 78 | dl_cur = dlib_list; 79 | while (dl_cur != NULL) { 80 | dl_e = dl_cur; 81 | dl_cur = dl_cur->next; 82 | if (dl_e->forceUnload) { 83 | ret = ci_module_unload(dl_e->handle, dl_e->name); 84 | if (!ret) 85 | error = 1; 86 | } 87 | if (dl_e->name) 88 | free(dl_e->name); 89 | if (dl_e->file) 90 | free(dl_e->file); 91 | free(dl_e); 92 | } 93 | dlib_list = NULL; 94 | if (error) 95 | return 0; 96 | return 1; 97 | } 98 | -------------------------------------------------------------------------------- /docs/man/c-icap-stretch.8.in: -------------------------------------------------------------------------------- 1 | .TH c-icap-stretch 8 "@PACKAGE_STRING@" 2 | .SH NAME 3 | c-icap-stretch - A simple utility for stretching ICAP servers 4 | .SH SYNOPSIS 5 | .B c-icap-stretch 6 | [ 7 | .B \-V 8 | ] 9 | [ 10 | .B \-VV 11 | ] 12 | [ 13 | .B \-i "icap_servername" 14 | ] 15 | [ 16 | .B \-p "port" 17 | ] 18 | [ 19 | .B \-s "service" 20 | ] 21 | [ 22 | .B \-urls "filename" 23 | ] 24 | [ 25 | .B \-bU "base_url" 26 | ] 27 | [ 28 | .B \-req 29 | ] 30 | [ 31 | .B \-m "max-requests" 32 | ] 33 | [ 34 | .B \-t "threads-number" 35 | ] 36 | [ 37 | .B \-d "debug level" 38 | ] 39 | [ 40 | .B \-x "icap-header" 41 | ] 42 | [ 43 | .B \-hx "http-request-header" 44 | ] 45 | [ 46 | .B \-rhx "http-response-header" 47 | ] 48 | [ 49 | .B \-O "OutputDirectory" 50 | ] 51 | [ 52 | .B \-\-max-requests-to-save, "requests-number" 53 | ] 54 | .B file1 file2 ... 55 | .SH DESCRIPTION 56 | .B c-icap-stretch 57 | is a simple utility for loading ICAP servers. 58 | .SH OPTIONS 59 | .IP "-V" 60 | Print version 61 | .IP "-VV" 62 | Print build informations 63 | .IP "-i icap_servername" 64 | The hostname or the IP address of the ICAP server. The default is localhost 65 | .IP "-p port" 66 | The ICAP server port. The default port value is 1344 67 | .IP "-s service" 68 | The service name. The default service name is "echo" 69 | .IP "-urls filename" 70 | File with HTTP urls, one url per line, to use for stress test. The utility uses 71 | these urs to construct random HTTP requests. 72 | .IP "-bU base_url" 73 | Base HTTP URL to use it as template to build HTTP requests. The final HTTP url 74 | is built using the base_url and the path of the file used as body data. 75 | .IP "-req" 76 | Send ICAP request modification requests (reqmod) 77 | .IP "-m max-requests" 78 | The maximum requests to send 79 | .IP "-t threads-number" 80 | The number of client threads to start 81 | .IP "-d level" 82 | debug level info to stdout 83 | .IP "-x icap-header" 84 | Include the icap-header in ICAP request headers 85 | .IP "-hx http-request-header" 86 | Include the http-request-header in HTTP request headers 87 | .IP "-rhx http-response-header" 88 | Include the http-response-header in HTTP response headers 89 | .IP "-O OutputDirectory" 90 | Output metadata (ICAP and HTTP headers) and HTTP responses body data under this directory. 91 | .IP "--max-requests-to-save files-number" 92 | Sets the maximum requests to save when the -O parameter is used. By default no more than 4096 requests are saved. 93 | .IP "file1 file2 ..." 94 | The files to use as body data to the ICAP requests. 95 | .SH SEE ALSO 96 | .BR c-icap "(8)" 97 | .BR c-icap-client "(8)" 98 | .BR c-icap-config "(8)" 99 | .BR c-icap-libicapapi-config "(8)" 100 | .BR c-icap-mkbdb "(8)" 101 | .SH BUGS 102 | It can used only for ICAP response modification services. 103 | .SH AUTHOR 104 | Tsantilas Christos 105 | -------------------------------------------------------------------------------- /tests/test_ops.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | #include 4 | #include 5 | #include "c-icap.h" 6 | #include "cfg_param.h" 7 | #include "debug.h" 8 | #include "types_ops.h" 9 | #include "mem.h" 10 | #include "net_io.h" 11 | #include "request.h" 12 | 13 | char *str_ip(ci_ip_t *ip) 14 | { 15 | char ip_buf[512]; 16 | char mask_buf[512]; 17 | static char buf[1024]; 18 | snprintf(buf, sizeof(buf), "%s/%s", 19 | ci_inet_ntoa(ip->family, &ip->address, ip_buf, sizeof(ip_buf)), 20 | ci_inet_ntoa(ip->family, &ip->netmask, mask_buf, sizeof(mask_buf))); 21 | return buf; 22 | } 23 | 24 | int check_ip_ops() 25 | { 26 | int i, ret = 1; 27 | char ip_buf[128]; 28 | ci_ip_t *ip1 = ci_ip_ops.dup("192.168.1.1/255.255.255.248", ci_os_allocator); 29 | for (i = 1; i < 8 && ret; ++i) { 30 | snprintf(ip_buf, sizeof(ip_buf), "192.168.1.%d", i); 31 | ci_ip_t *ip2 = ci_ip_ops.dup(ip_buf, ci_os_allocator); 32 | printf("IP network address: %s\n", str_ip(ip1)); 33 | printf("IP check address: %s\n", str_ip(ip2)); 34 | ret = ci_ip_ops.equal(ip1, ip2); 35 | printf("Check result: %d\n\n", ret); 36 | ci_ip_ops.free(ip2, ci_os_allocator); 37 | } 38 | 39 | for (i = 8; i < 16 && ret; ++i) { 40 | snprintf(ip_buf, sizeof(ip_buf), "192.168.1.%d", i); 41 | ci_ip_t *ip2 = ci_ip_ops.dup(ip_buf, ci_os_allocator); 42 | printf("IP network address: %s\n", str_ip(ip1)); 43 | printf("IP check address: %s\n", str_ip(ip2)); 44 | ret = ci_ip_ops.equal(ip1, ip2); 45 | printf("Check result: %d\n\n", ret); 46 | ret = !ret; 47 | ci_ip_ops.free(ip2, ci_os_allocator); 48 | } 49 | 50 | ci_ip_ops.free(ip1, ci_os_allocator); 51 | return ret; 52 | } 53 | 54 | void log_errors(void *unused, const char *format, ...) 55 | { 56 | va_list ap; 57 | va_start(ap, format); 58 | vfprintf(stderr, format, ap); 59 | va_end(ap); 60 | } 61 | 62 | int USE_DEBUG_LEVEL = -1; 63 | static struct ci_options_entry options[] = { 64 | { 65 | "-d", "debug_level", &USE_DEBUG_LEVEL, ci_cfg_set_int, 66 | "The debug level" 67 | }, 68 | {NULL,NULL,NULL,NULL,NULL} 69 | }; 70 | 71 | int main(int argc,char *argv[]) 72 | { 73 | int ret = 0; 74 | ci_cfg_lib_init(); 75 | __log_error = (void (*)(void *, const char *,...)) log_errors; /*set c-icap library log function */ 76 | 77 | if (!ci_args_apply(argc, argv, options)) { 78 | ci_args_usage(argv[0], options); 79 | exit(-1); 80 | } 81 | 82 | if (USE_DEBUG_LEVEL >= 0) 83 | CI_DEBUG_LEVEL = USE_DEBUG_LEVEL; 84 | 85 | ci_cfg_lib_init(); 86 | ci_mem_init(); 87 | 88 | if (!check_ip_ops()) { 89 | ci_debug_printf(1, "ip_ops check failed!\n"); 90 | ret = -1; 91 | } 92 | 93 | return ret; 94 | } 95 | -------------------------------------------------------------------------------- /include/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_UTIL_H 21 | #define __C_ICAP_UTIL_H 22 | 23 | #include "array.h" 24 | #include "types_ops.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | #define STR_TIME_SIZE 64 32 | 33 | CI_DECLARE_FUNC(void) ci_strtime(char *buf); /*Obsoleted*/ 34 | CI_DECLARE_FUNC(void) ci_strtime_rfc822(char *buf); /*Obsoleted*/ 35 | CI_DECLARE_FUNC(void) ci_strntime(char *buf, size_t size); 36 | CI_DECLARE_FUNC(void) ci_to_strntime(char *buf, size_t size, const time_t *tm); 37 | CI_DECLARE_FUNC(void) ci_strntime_rfc822(char *buf, size_t size); 38 | CI_DECLARE_FUNC(void) ci_to_strntime_rfc822(char *buf, size_t size, const time_t *tm); 39 | 40 | CI_DECLARE_FUNC(int) ci_mktemp_file(char*dir,char *name_template,char *filename); 41 | CI_DECLARE_FUNC(int) ci_usleep(unsigned long usec); 42 | 43 | 44 | #ifdef _WIN32 45 | CI_DECLARE_FUNC(int) mkstemp(char *filename); 46 | CI_DECLARE_FUNC(struct tm*) localtime_r(const time_t *t, struct tm *tm); 47 | CI_DECLARE_FUNC(struct tm*) gmtime_r(const time_t *t, struct tm *tm); 48 | #endif 49 | 50 | CI_DECLARE_FUNC(const char *) ci_strnstr(const char *s, const char *find, size_t slen); 51 | 52 | CI_DECLARE_FUNC(const char *) ci_strncasestr(const char *s, const char *find, size_t slen); 53 | 54 | CI_DECLARE_FUNC(const char *) ci_strcasestr(const char *str, const char *find); 55 | 56 | /*Handle M/m/k/K suffixes and try to detect errors*/ 57 | CI_DECLARE_FUNC(long int) ci_atol_ext(const char *str, const char **error); 58 | 59 | CI_DECLARE_FUNC(void) ci_str_trim(char *str); 60 | 61 | CI_DECLARE_FUNC(char *) ci_str_trim2(char *s); 62 | 63 | CI_DECLARE_FUNC(char *) ci_strerror(int error, char *buf, size_t buflen); 64 | 65 | CI_DECLARE_FUNC(ci_dyn_array_t *) ci_parse_key_value_list(const char *str, char sep); 66 | 67 | CI_DECLARE_FUNC(int) ci_parse_key_mvalues(const char *line, char key_sep, char vals_sep, const ci_type_ops_t *key_type, const ci_type_ops_t *val_type, void **key, size_t *keysize, ci_vector_t **values); 68 | 69 | CI_DECLARE_FUNC(int) ci_screen_columns(); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /tests/test_allocators.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "cfg_param.h" 10 | #include "ci_threads.h" 11 | #include "mem.h" 12 | #include "debug.h" 13 | 14 | 15 | int run_allocs() 16 | { 17 | int l, i, k; 18 | void *v; 19 | for (l = 1; l< 50; l++) { 20 | for (k = 1; k < 133; k++) { 21 | for ( i = k; i < 32768; i = i*2) { 22 | ci_debug_printf(5, "Alloc buffer for %d bytes\n", i); 23 | v = ci_buffer_alloc(i); 24 | memset(v, 0x1, i); 25 | ci_buffer_free(v); 26 | } 27 | } 28 | 29 | for (k = 11; k < 73; k++) { 30 | ci_debug_printf(5, "Alloc buffer for realloc for %d bytes\n", k); 31 | v = ci_buffer_alloc(k); 32 | for ( i = 17; i < 32768; i = i*2) { 33 | ci_debug_printf(5, "ReAlloc buffer for %d bytes\n", i); 34 | v = ci_buffer_realloc(v, i); 35 | memset(v, 0x1, i); 36 | } 37 | ci_buffer_free(v); 38 | } 39 | } 40 | return 1; 41 | } 42 | 43 | int threadsnum = 100; 44 | int USE_DEBUG_LEVEL = -1; 45 | static struct ci_options_entry options[] = { 46 | { 47 | "-d", "debug_level", &USE_DEBUG_LEVEL, ci_cfg_set_int, 48 | "The debug level" 49 | }, 50 | { 51 | "-t", "threads", &threadsnum, ci_cfg_set_int, 52 | "The numbers of threads to use" 53 | }, 54 | {NULL,NULL,NULL,NULL,NULL} 55 | }; 56 | 57 | void log_errors(void *unused, const char *format, ...) 58 | { 59 | va_list ap; 60 | va_start(ap, format); 61 | vfprintf(stderr, format, ap); 62 | va_end(ap); 63 | } 64 | 65 | int main(int argc, char *argv[]) 66 | { 67 | int i; 68 | ci_thread_t *threads; 69 | CI_DEBUG_STDOUT = 1; 70 | 71 | __log_error = (void (*)(void *, const char *,...)) log_errors; /*set c-icap library log function */ 72 | 73 | ci_cfg_lib_init(); 74 | ci_mem_init(); 75 | 76 | if (!ci_args_apply(argc, argv, options)) { 77 | ci_args_usage(argv[0], options); 78 | exit(-1); 79 | } 80 | 81 | if (USE_DEBUG_LEVEL >= 0) 82 | CI_DEBUG_LEVEL = USE_DEBUG_LEVEL; 83 | 84 | /* Simple one thread test */ 85 | run_allocs(); 86 | 87 | /* Run multithread test */ 88 | threads = malloc(sizeof(ci_thread_t) * threadsnum); 89 | for (i = 0; i < threadsnum; i++) threads[i] = 0; 90 | for (i = 0; i < threadsnum; i++) { 91 | ci_debug_printf(8, "Thread %d started\n", i); 92 | ci_thread_create(&(threads[i]), 93 | (void *(*)(void *)) run_allocs, 94 | (void *) NULL /*data*/); 95 | } 96 | 97 | for (i = 0; i < threadsnum; i++) { 98 | ci_thread_join(threads[i]); 99 | ci_debug_printf(6, "Thread %d exited\n", i); 100 | } 101 | 102 | free(threads); 103 | 104 | return 0; 105 | } 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /access.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "request.h" 23 | #include "request_util.h" 24 | #include "module.h" 25 | #include "cfg_param.h" 26 | #include "debug.h" 27 | #include "access.h" 28 | #include "acl.h" 29 | #include "net_io.h" 30 | 31 | 32 | 33 | /********************************************************************************************/ 34 | 35 | extern access_control_module_t default_acl; 36 | access_control_module_t *default_access_controllers[] = { 37 | &default_acl, 38 | NULL 39 | }; 40 | 41 | 42 | access_control_module_t **used_access_controllers = default_access_controllers; 43 | 44 | int access_reset() 45 | { 46 | used_access_controllers = default_access_controllers; 47 | return 1; 48 | } 49 | 50 | int access_check_client(ci_request_t *req) 51 | { 52 | int i = 0, res; 53 | if (!used_access_controllers) 54 | return CI_ACCESS_ALLOW; 55 | 56 | i = 0; 57 | while (used_access_controllers[i] != NULL) { 58 | if (used_access_controllers[i]->client_access) { 59 | res = 60 | used_access_controllers[i]->client_access(req); 61 | if (res != CI_ACCESS_UNKNOWN) 62 | return res; 63 | } 64 | i++; 65 | } 66 | return CI_ACCESS_ALLOW; 67 | } 68 | 69 | 70 | int check_request(ci_request_t * req) 71 | { 72 | int res, i = 0; 73 | while (used_access_controllers[i] != NULL) { 74 | if (used_access_controllers[i]->request_access) { 75 | res = used_access_controllers[i]->request_access(req); 76 | if (res != CI_ACCESS_UNKNOWN) 77 | return res; 78 | } 79 | i++; 80 | } 81 | return CI_ACCESS_ALLOW; 82 | } 83 | 84 | int access_check_request(ci_request_t * req) 85 | { 86 | int res; 87 | 88 | if (!used_access_controllers) 89 | return CI_ACCESS_ALLOW; 90 | 91 | ci_debug_printf(9,"Going to check request for access control restrictions\n"); 92 | 93 | res = check_request(req); 94 | 95 | ci_debug_printf(9,"Access control: %s\n", (res == CI_ACCESS_ALLOW? 96 | "ALLOW": 97 | (res == CI_ACCESS_DENY?"DENY":"UNKNOWN"))); 98 | return res; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /include/ci_regex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_CI_REGEX_H 21 | #define __C_ICAP_CI_REGEX_H 22 | 23 | #include "c-icap.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | typedef void * ci_regex_t; 31 | 32 | struct ci_regex_match { 33 | size_t s; 34 | size_t e; 35 | }; 36 | #define CI_REGEX_SUBMATCHES 10 37 | typedef struct ci_regex_match ci_regex_matches_t[CI_REGEX_SUBMATCHES]; 38 | typedef struct ci_regex_replace_part { 39 | const void *user_data; 40 | ci_regex_matches_t matches; 41 | } ci_regex_replace_part_t; 42 | 43 | /** 44 | \brief Builds a regex match list to store regex matches. 45 | * The regex match list is a ci_list_t object which stores ci_regex_replace_part 46 | * objects as items. 47 | \ingroup UTILITY 48 | */ 49 | #define ci_regex_create_match_list() ci_list_create(1024, sizeof(ci_regex_replace_part_t)) 50 | 51 | /** 52 | \brief Parses a regex expresion having the form /regex/flags 53 | \ingroup UTILITY 54 | * 55 | */ 56 | CI_DECLARE_FUNC(char *) ci_regex_parse(const char *str, int *flags, int *recursive); 57 | 58 | /** 59 | \brief Compiles a regex expresion into an internal form. 60 | \param regex_str The regex string normally returned by ci_regex_parse function 61 | \param regex_flags The regex flags built using the ci_regex_parse 62 | \ingroup UTILITY 63 | */ 64 | CI_DECLARE_FUNC(ci_regex_t) ci_regex_build(const char *regex_str, int regex_flags); 65 | 66 | /** 67 | * Releases objects built using the ci_regex_build 68 | \ingroup UTILITY 69 | */ 70 | CI_DECLARE_FUNC(void) ci_regex_free(ci_regex_t regex); 71 | 72 | /** 73 | * Matchs a compiled regex expresion of type ci_regex_t against the given string. 74 | \param regex The compiled regex expresion 75 | \param str The string to match against 76 | \param len The str string length. For '\0' terminated strings set it to -1 77 | \param recurs If it is not NULL matches recursivelly 78 | \param matches The regex match list to store matches. It can be NULL 79 | \param user_data pointer to user data to store with matches in rege match list. 80 | \ingroup UTILITY 81 | */ 82 | CI_DECLARE_FUNC(int) ci_regex_apply(const ci_regex_t regex, const char *str, int len, int recurs, ci_list_t *matches, const void *user_data); 83 | 84 | 85 | CI_DECLARE_FUNC(void) ci_regex_memory_init(); 86 | CI_DECLARE_FUNC(void) ci_regex_memory_destroy(); 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | 92 | #endif /*__C_ICAP_CI_REGEX_H*/ 93 | -------------------------------------------------------------------------------- /debug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include 23 | #include "debug.h" 24 | 25 | 26 | int CI_DEBUG_LEVEL = 1; 27 | int CI_DEBUG_STDOUT = 0; 28 | 29 | void (*__log_error) (void *req, const char *format, ...) = NULL; 30 | void (*__vlog_error) (void *req, const char *format, va_list ap) = NULL; 31 | void __ldebug_printf(int i, const char *format, ...) 32 | { 33 | va_list ap; 34 | if (i <= CI_DEBUG_LEVEL) { 35 | va_start(ap, format); 36 | if (__vlog_error) { 37 | (*__vlog_error) (NULL, format, ap); 38 | } 39 | if (CI_DEBUG_STDOUT) 40 | vprintf(format, ap); 41 | va_end(ap); 42 | } 43 | } 44 | 45 | void ci_debug_abort(const char *file, int line, const char *function, const char *mesg) 46 | { 47 | ci_debug_printf(1, "Abort at %s, %d, %s: \'%s\'\n", file, line, function, mesg); 48 | fflush(stderr); 49 | fflush(stdout); 50 | abort(); 51 | } 52 | 53 | void (*__ci_debug_abort)(const char *file, int line, const char *function, const char *mesg) = ci_debug_abort; 54 | 55 | /* 56 | void debug_print_request(ci_request_t *req){ 57 | int i,j; 58 | 59 | ci_debug_printf(1,"Request Type :\n"); 60 | if(req->type>=0){ 61 | ci_debug_printf(1," Requested: %s\n Server: %s\n Service: %s\n", 62 | ci_method_string(req->type), 63 | req->req_server, 64 | req->service); 65 | if(req->args){ 66 | ci_debug_printf(1," Args: %s\n",req->args); 67 | } 68 | else{ 69 | ci_debug_printf(1,"\n"); 70 | } 71 | } 72 | else{ 73 | ci_debug_printf(1," No Method\n"); 74 | } 75 | 76 | ci_debug_printf(1,"\n\nHEADERS : \n"); 77 | for(i = 0; i < req->head->used; i++){ 78 | ci_debug_printf(1," %s\n",req->head->headers[i]); 79 | } 80 | ci_debug_printf(1,"\n\nEncapsulated Entities: \n"); 81 | i = 0; 82 | while(req->entities[i] != NULL){ 83 | ci_debug_printf(1,"\t %s header at %d\n", 84 | ci_encaps_entity_string_inline(req->entities[i]->type),req->entities[i]->start); 85 | if(req->entities[i]->typeentities[i]->entity; 87 | ci_debug_printf(1,"\t\t HEADERS : \n"); 88 | for(j=0;jused;j++){ 89 | ci_debug_printf(1,"\t\t\t%d. %s\n",j,h->headers[j]); 90 | } 91 | } 92 | i++; 93 | } 94 | } 95 | */ 96 | -------------------------------------------------------------------------------- /tests/test_filetype.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "c-icap.h" 3 | #include "filetype.h" 4 | #include "array.h" 5 | #include "client.h" 6 | 7 | 8 | int USE_DEBUG_LEVEL = -1; 9 | char *MAGIC_DB = NULL; 10 | ci_list_t *FILES = NULL; 11 | 12 | static int cfg_check_files(const char *directive, const char **argv, void *setdata); 13 | 14 | static struct ci_options_entry options[] = { 15 | { 16 | "-d", "debug_level", &USE_DEBUG_LEVEL, ci_cfg_set_int, 17 | "The debug level" 18 | }, 19 | { 20 | "-m", "magic_db", &MAGIC_DB, ci_cfg_set_str, 21 | "The path of the magic_db to use" 22 | }, 23 | {"$$", NULL, &FILES, cfg_check_files, "files to send"}, 24 | {NULL,NULL,NULL,NULL,NULL} 25 | }; 26 | 27 | int cfg_check_files(const char *directive, const char **argv, void *setdata) 28 | { 29 | if (!FILES) 30 | FILES = ci_list_create(512, sizeof(char*)); 31 | 32 | if (!FILES) { 33 | ci_debug_printf(1, "Error allocating memory for ci_list_t object"); 34 | return -0; 35 | } 36 | 37 | char *f = strdup(argv[0]); 38 | ci_list_push_back(FILES, &f); 39 | return 1; 40 | } 41 | 42 | void log_errors(void *unused, const char *format, ...) 43 | { 44 | va_list ap; 45 | va_start(ap, format); 46 | vfprintf(stderr, format, ap); 47 | va_end(ap); 48 | } 49 | 50 | int main(int argc, char *argv[]) 51 | { 52 | char *fname = NULL; 53 | ci_client_library_init(); 54 | 55 | __log_error = (void (*)(void *, const char *, ...)) log_errors; /*set c-icap library log function */ 56 | 57 | if (!ci_args_apply(argc, argv, options)) { 58 | ci_args_usage(argv[0], options); 59 | exit(-1); 60 | } 61 | if (USE_DEBUG_LEVEL >= 0) 62 | CI_DEBUG_LEVEL = USE_DEBUG_LEVEL; 63 | 64 | struct ci_magics_db *db = NULL; 65 | if (MAGIC_DB) 66 | db = ci_magic_db_load(MAGIC_DB); 67 | 68 | if (!db) { 69 | ci_debug_printf(1, "Required a valid magics db, '%s' is given\n", MAGIC_DB ? MAGIC_DB : "none"); 70 | exit(-1); 71 | } 72 | 73 | while(ci_list_pop(FILES, &fname)) { 74 | char buf[4096]; 75 | size_t bytes; 76 | FILE *f; 77 | if ((f = fopen(fname, "r")) == NULL) { 78 | ci_debug_printf(1, "Can not open file '%s'! Ignore\n", fname); 79 | continue; 80 | } 81 | bytes = fread(buf, 1, sizeof(buf), f); 82 | if (bytes > 0) { 83 | ci_debug_printf(5, "%s: read %lu bytes\n", fname, bytes); 84 | char *usefname; 85 | usefname = strrchr(fname, '/'); 86 | if (!usefname) 87 | usefname = fname; 88 | else 89 | usefname++; 90 | int ft = ci_magic_data_type(buf, bytes); 91 | if (ft >= 0) { 92 | const char *type = ci_magic_type_name(ft); 93 | assert(type); 94 | const char *descr = ci_magic_type_descr(ft); 95 | printf("%s: %s, %s\n", usefname, type, (descr ? descr : "-")); 96 | } else { 97 | printf("%s: unknown\n", usefname); 98 | } 99 | } 100 | fclose(f); 101 | free(fname); 102 | } 103 | ci_list_destroy(FILES); 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /docs/man/c-icap-client.8.in: -------------------------------------------------------------------------------- 1 | .TH c-icap-client 8 "@PACKAGE_STRING@" 2 | .SH NAME 3 | c-icap-client - simple ICAP client 4 | .SH SYNOPSIS 5 | .B c-icap-client 6 | [ 7 | .B \-V 8 | ] 9 | [ 10 | .B \-VV 11 | ] 12 | [ 13 | .B \-i "icap_servername" 14 | ] 15 | [ 16 | .B \-p "port" 17 | ] 18 | [ 19 | .B \-s "service" 20 | ] 21 | [ 22 | .B \-tls 23 | ] 24 | [ 25 | .B \-tls-method method 26 | ] 27 | [ 28 | .B \-tls-no-verify 29 | ] 30 | [ 31 | .B \-f "input_file" 32 | ] 33 | [ 34 | .B \-o "out_file" 35 | ] 36 | [ 37 | .B \-req "url" 38 | ] 39 | [ 40 | .B \-resp "url" 41 | ] 42 | [ 43 | .B \-d "debug level" 44 | ] 45 | [ 46 | .B \-noreshdr 47 | ] 48 | [ 49 | .B \-nopreview 50 | ] 51 | [ 52 | .B \-no204 53 | ] 54 | [ 55 | .B \-206 56 | ] 57 | [ 58 | .B \-x "icap-header" 59 | ] 60 | [ 61 | .B \-hx "http-request-header" 62 | ] 63 | [ 64 | .B \-rhx "http-response-header" 65 | ] 66 | [ 67 | .B \-no-h "http-request-header-name" 68 | ] 69 | [ 70 | .B \-no-rh "http-response-header-name" 71 | ] 72 | [ 73 | .B \-w preview_size 74 | ] 75 | [ 76 | .B \-v 77 | ] 78 | .SH DESCRIPTION 79 | .B c-icap-client 80 | is a simple ICAP client. It can be used to test your icap server configuration. 81 | .SH OPTIONS 82 | .IP "-V" 83 | Print version 84 | .IP "-VV" 85 | Print build informations 86 | .IP "-i icap_servername" 87 | The hostname or the IP address of the icap server. The default is localhost. 88 | .IP "-p port" 89 | The server port. The default port value is 1344 90 | .IP "-s service" 91 | The service name. The default service name is "echo" 92 | .IP "-tls" 93 | Use TLS 94 | .IP "-tls-method method" 95 | Select the TLS method to use, normaly one of TLSv1, TLSv1_1, TLSv1_2 or TLSv1_3 96 | .IP "-tls-no-verify" 97 | Disable TLS server certificate verify 98 | .IP "-f filename" 99 | Send this file to the icap server. Default is to send an options request. 100 | .IP "-o filename" 101 | Save output to this file. Default is to send to stdout 102 | .IP "-req url" 103 | Send a request modification ICAP request (reqmod) instead of a response modification, using as HTTP url the url provided with this option. 104 | .IP "-resp url" 105 | Send a response modification ICAP request (respmod) with HTTP request headers, using as HTTP url the url provided with this option. 106 | .IP "-d level" 107 | debug level info to stdout 108 | .IP "-noreshdr" 109 | Do not send reshdr headers 110 | .IP "-nopreview" 111 | Do not send preview request data 112 | .IP "-no204" 113 | Do not allow204 outside preview 114 | .IP "-206" 115 | Support 206 responses 116 | .IP "-x icap-header" 117 | Include the icap-header in ICAP request headers 118 | .IP "-hx http-request-header" 119 | Include the http-request-header in HTTP request headers 120 | .IP "-rhx http-response-header" 121 | Include the http-response-header in HTTP response headers 122 | .IP \-no-h "http-request-header-name" 123 | Do not add the http-request-header-name header in HTTP request headers 124 | .IP \-no-rh "http-response-header-name" 125 | Do not add the http-response-header-name header in HTTP response headers 126 | .IP "-w preview" 127 | Sets the maximum preview data size to preview 128 | .IP "-v" 129 | Print response headers 130 | .SH SEE ALSO 131 | .BR c-icap "(8)" 132 | .BR c-icap-stretch "(8)" 133 | .BR c-icap-config "(8)" 134 | .BR c-icap-libicapapi-config "(8)" 135 | .BR c-icap-mkbdb "(8)" 136 | .SH BUGS 137 | Many... 138 | .SH AUTHOR 139 | Tsantilas Christos 140 | -------------------------------------------------------------------------------- /os/unix/utilfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "util.h" 23 | #include 24 | #include 25 | #include 26 | #include 27 | #if defined(HAVE_TIOCGWINSZ) 28 | #include 29 | #endif 30 | 31 | static const char *days[] = { 32 | "Sun", 33 | "Mon", 34 | "Tue", 35 | "Wed", 36 | "Thu", 37 | "Fri", 38 | "Sat" 39 | }; 40 | 41 | static const char *months[] = { 42 | "Jan", 43 | "Feb", 44 | "Mar", 45 | "Apr", 46 | "May", 47 | "Jun", 48 | "Jul", 49 | "Aug", 50 | "Sep", 51 | "Oct", 52 | "Nov", 53 | "Dec" 54 | }; 55 | 56 | void ci_strtime(char *buf) 57 | { 58 | ci_strntime(buf, STR_TIME_SIZE); 59 | } 60 | 61 | void ci_strtime_rfc822(char *buf) 62 | { 63 | ci_strntime_rfc822(buf, STR_TIME_SIZE); 64 | } 65 | 66 | void ci_strntime(char *buf, size_t size) 67 | { 68 | assert(size > 0); 69 | struct tm br_tm; 70 | time_t tm; 71 | time(&tm); 72 | if (!strftime(buf, size, "%a %b %e %T %Y", localtime_r(&tm, &br_tm))) 73 | buf[0] = '\0'; 74 | } 75 | 76 | void ci_to_strntime(char *buf, size_t size, const time_t *tm) 77 | { 78 | assert(size > 0); 79 | struct tm br_tm; 80 | if (!strftime(buf, size, "%a %b %e %T %Y", localtime_r(tm, &br_tm))) 81 | buf[0] = '\0'; 82 | } 83 | 84 | void ci_to_strntime_rfc822(char *buf, size_t size, const time_t *tm) 85 | { 86 | assert(size > 0); 87 | struct tm br_tm; 88 | gmtime_r(tm, &br_tm); 89 | snprintf(buf, size, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", 90 | days[br_tm.tm_wday], 91 | br_tm.tm_mday, 92 | months[br_tm.tm_mon], 93 | br_tm.tm_year + 1900, br_tm.tm_hour, br_tm.tm_min, br_tm.tm_sec); 94 | } 95 | 96 | void ci_strntime_rfc822(char *buf, size_t size) 97 | { 98 | time_t tm; 99 | time(&tm); 100 | ci_to_strntime_rfc822(buf, size, &tm); 101 | } 102 | 103 | int ci_mktemp_file(char *dir, char *template, char *filename) 104 | { 105 | snprintf(filename, CI_FILENAME_LEN, "%s%s",dir,template); 106 | return mkstemp(filename); 107 | } 108 | 109 | 110 | int ci_usleep(unsigned long usec) 111 | { 112 | struct timespec us, ur; 113 | us.tv_sec = 0; 114 | us.tv_nsec = usec * 1000; 115 | nanosleep(&us, &ur); 116 | return 0; 117 | } 118 | 119 | int ci_screen_columns() 120 | { 121 | int cols = 80; 122 | #if defined(HAVE_TIOCGWINSZ) 123 | struct winsize ws; 124 | int fd; 125 | fd = open("/dev/tty", O_RDWR); 126 | if (fd >= 0 && ioctl(fd, TIOCGWINSZ, &ws) == 0) 127 | cols = ws.ws_col; 128 | close(fd); // dont forget to close files 129 | #endif 130 | return cols; 131 | } 132 | -------------------------------------------------------------------------------- /include/ci_time.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_CI_TIME_H 21 | #define __C_ICAP_CI_TIME_H 22 | 23 | #include "c-icap.h" 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | #ifndef _WIN32 32 | 33 | typedef struct timespec ci_clock_time_t; 34 | 35 | #define CI_CLOCK_TIME_ZERO (ci_clock_time_t){0,0} 36 | 37 | static inline void ci_clock_time_reset(ci_clock_time_t *t) 38 | { 39 | *t = CI_CLOCK_TIME_ZERO; 40 | } 41 | 42 | static inline time_t ci_clock_time_to_unixtime(ci_clock_time_t *tm) { 43 | return tm->tv_sec; 44 | } 45 | 46 | static inline int64_t ci_clock_time_diff_milli(ci_clock_time_t *tsstop, ci_clock_time_t *tsstart) { 47 | return 48 | ((int64_t)tsstop->tv_sec - (int64_t)tsstart->tv_sec) * 1000LL + 49 | ((int64_t)tsstop->tv_nsec - (int64_t)tsstart->tv_nsec) / 1000000LL; 50 | } 51 | 52 | static inline int64_t ci_clock_time_diff_micro(ci_clock_time_t *tsstop, ci_clock_time_t *tsstart) { 53 | return 54 | ((int64_t)tsstop->tv_sec - (int64_t)tsstart->tv_sec) * 1000000LL + 55 | ((int64_t)tsstop->tv_nsec - (int64_t)tsstart->tv_nsec) / 1000LL; 56 | } 57 | 58 | static inline int64_t ci_clock_time_diff_nano(ci_clock_time_t *tsstop, ci_clock_time_t *tsstart) { 59 | return 60 | ((int64_t)tsstop->tv_sec - (int64_t)tsstart->tv_sec) * 1000000000LL + 61 | ((int64_t)tsstop->tv_nsec - (int64_t)tsstart->tv_nsec); 62 | } 63 | 64 | static inline void ci_clock_time_get(ci_clock_time_t *t) 65 | { 66 | clock_gettime(CLOCK_REALTIME, t); 67 | } 68 | 69 | static inline void ci_clock_time_add(ci_clock_time_t *dst, const ci_clock_time_t *t1, const ci_clock_time_t *t2) { 70 | dst->tv_nsec = t1->tv_nsec + t2->tv_nsec; 71 | dst->tv_sec = t1->tv_sec + t2->tv_sec + (dst->tv_nsec / 1000000000); 72 | dst->tv_nsec = dst->tv_nsec % 1000000000; 73 | } 74 | 75 | static inline void ci_clock_time_add_to(ci_clock_time_t *dst, const ci_clock_time_t *t1) { 76 | dst->tv_nsec += t1->tv_nsec; 77 | dst->tv_sec += t1->tv_sec + (dst->tv_nsec / 1000000000); 78 | dst->tv_nsec = dst->tv_nsec % 1000000000; 79 | } 80 | 81 | static inline void ci_clock_time_sub(ci_clock_time_t *dst, const ci_clock_time_t *t1, const ci_clock_time_t *t2) { 82 | //check if t2 greater/later than t1? 83 | if (t1->tv_nsec < t2->tv_nsec) { 84 | dst->tv_sec = t1->tv_sec - 1 - t2->tv_sec; 85 | dst->tv_nsec = 1000000000 + t1->tv_nsec - t2->tv_nsec; 86 | } else { 87 | dst->tv_sec = t1->tv_sec - t2->tv_sec; 88 | dst->tv_nsec = t1->tv_nsec - t2->tv_nsec; 89 | } 90 | } 91 | 92 | #else /*_WIN32*/ 93 | 94 | typedef LARGE_INTEGER ci_clock_time_t; 95 | 96 | #endif 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /include/c-icap-conf.h.in: -------------------------------------------------------------------------------- 1 | /*This is autogenerated file*/ 2 | 3 | #ifndef __C_ICAP_CONF_H 4 | #define __C_ICAP_CONF_H 5 | 6 | 7 | /*C_ICAP VERSION*/ 8 | #define C_ICAP_HEX_VERSION @C_ICAP_HEX_VERSION@ 9 | #define C_ICAP_VERSION_MAJOR_MASK 0xFFFFFFFF0000 10 | #define C_ICAP_HEX_VERSION_MAJOR (C_ICAP_VERSION_MAJOR_MASK & @C_ICAP_HEX_VERSION@) 11 | #define C_ICAP_VERSION_MAJOR_CHECK(version) ((version & C_ICAP_VERSION_MAJOR_MASK) == C_ICAP_HEX_VERSION_MAJOR) 12 | #define C_ICAP_VERSION_CHECK(version) (version == C_ICAP_HEX_VERSION_MAJOR) 13 | 14 | /* Define USE_IPV6 if we are supporting ipv6 */ 15 | #if @USE_IPV6@ 16 | #define USE_IPV6 17 | #endif 18 | 19 | #if @USE_OPENSSL@ 20 | #define USE_OPENSSL 21 | #endif 22 | 23 | #if @SYSV_IPC@ 24 | #define USE_SYSV_IPC 25 | #endif 26 | 27 | #if @POSIX_MAPPED_FILES@ 28 | #define USE_POSIX_MAPPED_FILES 29 | #endif 30 | 31 | #if @POSIX_SHARED_MEM@ 32 | #define USE_POSIX_SHARED_MEM 33 | #endif 34 | 35 | #if @SYSV_IPC@ 36 | # define USE_SYSV_IPC_MUTEX 37 | #endif 38 | #if @POSIX_FILE_LOCK@ 39 | # define USE_POSIX_FILE_LOCK 40 | #endif 41 | #if @POSIX_SEMAPHORES@ 42 | # define USE_POSIX_SEMAPHORES 43 | #endif 44 | 45 | #if @PTHREADS_RWLOCK@ 46 | #define USE_PTHREADS_RWLOCK 47 | #endif 48 | 49 | #if @USE_REGEX@ 50 | #define USE_REGEX 51 | #endif 52 | 53 | #if @USE_COMPAT@ 54 | #define __CI_COMPAT 55 | #endif 56 | 57 | #if @USE_POLL@ 58 | #define USE_POLL 59 | #endif 60 | 61 | /*The following maybe should used...*/ 62 | #if @SYS_TYPES_H@ 63 | #define __SYS_TYPES_H_EXISTS 64 | #endif 65 | 66 | #if @INTTYPES_H@ 67 | #define __INTTYPES_H_EXISTS 68 | #endif 69 | 70 | /* 71 | The 64 bit data models as described by wikipedia are: 72 | Data model short int long long long pointers/size_t 73 | LLP64 16 32 32 64 64 74 | LP64 16 32 64 64 64 75 | ILP64 16 64 64 64 64 76 | SILP64 64 64 64 64 64 77 | 78 | On most 32bit and 64bit unix machines, 'short' is always 16bit, 'int' is 32bit 79 | long is 32bit or 64bit respectively and long long is always 64bit. 80 | We are going to define: 81 | off_t as long on 32bit machines and long long on 64bit (sizeof(void*)==8) 82 | size_t as long on 32bit machines and long long on 64bit 83 | 84 | The c-icap should not use int32_t/uint32_t/int16_t/uint16_t types 85 | */ 86 | 87 | #define CI_SIZEOF_VOID_P @DEFINE_SIZE_VOID_P@ 88 | 89 | /* typedef off_t if does not define. */ 90 | #if @DEFINE_OFF_T@ 91 | #if CI_SIZEOF_VOID_P == 8 92 | typedef long long off_t; 93 | #define CI_SIZEOF_OFF_T 8 94 | #elif CI_SIZEOF_VOID_P == 4 95 | typedef long off_t; 96 | #define CI_SIZEOF_OFF_T 4 97 | #else 98 | #error "Unhandled size of void *" 99 | #endif 100 | #else /*if @DEFINE_OFF_T@*/ 101 | #define CI_SIZEOF_OFF_T @DEFINE_SIZE_OFF_T@ 102 | #define CI_SIZEOF_LONG @DEFINE_SIZE_LONG@ 103 | #endif 104 | 105 | /* typedef size_t if does not define. */ 106 | #if @DEFINE_SIZE_T@ 107 | #if SIZEOF_VOID_P == 8 108 | typedef unsigned long long size_t; 109 | #elif SIZEOF_VOID_P == 4 110 | typedef unsigned int size_t; 111 | #else 112 | #error "Unhandled size of void *" 113 | #endif 114 | #endif 115 | 116 | #if @DEFINE_UINT8@ 117 | typedef unsigned char uint8_t; 118 | #endif 119 | 120 | #if @DEFINE_INT8@ 121 | typedef char int8_t; 122 | #endif 123 | 124 | #if @DEFINE_UINT64@ 125 | typedef unsigned long long uint64_t; 126 | #endif 127 | 128 | #if @DEFINE_INT64@ 129 | typedef long long int64_t; 130 | #endif 131 | 132 | #if @WORDS_BIGENDIAN@ 133 | #define __USE_BIG_ENDIAN 134 | #else 135 | #define __USE_LITTLE_ENDIAN 136 | #endif 137 | 138 | #if @VISIBILITY_ATTR@ 139 | #define USE_VISIBILITY_ATTRIBUTE 140 | #endif 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /os/win32/threads.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "ci_threads.h" 21 | int ci_thread_mutex_init(ci_thread_mutex_t * pmutex) 22 | { 23 | InitializeCriticalSection(pmutex); 24 | return 0; 25 | } 26 | 27 | int ci_thread_mutex_destroy(ci_thread_mutex_t * pmutex) 28 | { 29 | DeleteCriticalSection(pmutex); 30 | return 0; 31 | } 32 | 33 | int ci_thread_mutex_lock(ci_thread_mutex_t * pmutex) 34 | { 35 | EnterCriticalSection(pmutex); 36 | return 0; 37 | } 38 | 39 | int ci_thread_mutex_unlock(ci_thread_mutex_t * pmutex) 40 | { 41 | LeaveCriticalSection(pmutex); 42 | return 0; 43 | } 44 | 45 | int ci_thread_cond_init(ci_thread_cond_t * pcond) 46 | { 47 | *pcond = CreateEvent(NULL, FALSE, FALSE, NULL); 48 | return 0; 49 | } 50 | 51 | int ci_thread_cond_destroy(ci_thread_cond_t * pcond) 52 | { 53 | CloseHandle(*pcond); 54 | *pcond = NULL; 55 | return 0; 56 | } 57 | 58 | int ci_thread_cond_wait(ci_thread_cond_t * pcond, ci_thread_mutex_t * pmutex) 59 | { 60 | ci_thread_mutex_unlock(pmutex); 61 | WaitForSingleObject(*pcond, INFINITE); 62 | ci_thread_mutex_lock(pmutex); 63 | return 0; 64 | } 65 | 66 | int ci_thread_cond_broadcast(ci_thread_cond_t * pcond) 67 | { 68 | SetEvent(*pcond); /*This do not work with autoreset events. 69 | But now the ci_thread_cond_broadcast 70 | not used by the c-icap server. 71 | SS: This is wrong used by worker thread to kill childs..... */ 72 | return 0; 73 | } 74 | 75 | int ci_thread_cond_signal(ci_thread_cond_t * pcond) 76 | { 77 | SetEvent(*pcond); 78 | return 0; 79 | } 80 | 81 | int ci_thread_create(ci_thread_t * pthread_id, void *(*pfunc) (void *), 82 | void *parg) 83 | { 84 | *pthread_id = 85 | CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) pfunc, parg, 0, NULL); 86 | return 0; 87 | } 88 | 89 | int ci_thread_join(ci_thread_t thread_id) 90 | { 91 | if (WaitForSingleObject(thread_id, INFINITE) == WAIT_FAILED) { 92 | return -1; 93 | } 94 | return 0; 95 | } 96 | 97 | /*Needs some work to implement a better solution here. At Vista there are a number of 98 | related functions, but for Windows 2000/XP?? 99 | */ 100 | 101 | int ci_thread_rwlock_init(ci_thread_rwlock_t * rwlock) 102 | { 103 | InitializeCriticalSection(rwlock); 104 | return 0; 105 | } 106 | 107 | int ci_thread_rwlock_destroy(ci_thread_rwlock_t * rwlock) 108 | { 109 | DeleteCriticalSection(rwlock); 110 | return 0; 111 | } 112 | 113 | int ci_thread_rwlock_rdlock(ci_thread_rwlock_t * rwlock) 114 | { 115 | EnterCriticalSection(rwlock); 116 | return 0; 117 | } 118 | 119 | int ci_thread_rwlock_wrlock(ci_thread_rwlock_t * rwlock) 120 | { 121 | EnterCriticalSection(rwlock); 122 | return 0; 123 | } 124 | 125 | int ci_thread_rwlock_unlock(ci_thread_rwlock_t * rwlock) 126 | { 127 | LeaveCriticalSection(rwlock); 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /include/client.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2020 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_CLIENT_H 21 | #define __C_ICAP_CLIENT_H 22 | 23 | #include "net_io.h" 24 | #include "request.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | CI_DECLARE_FUNC(ci_request_t *) ci_client_request(ci_connection_t *conn,const char *server,const char *service); 32 | CI_DECLARE_FUNC(void) ci_client_request_reuse(ci_request_t *req); 33 | 34 | CI_DECLARE_FUNC(int) ci_client_get_server_options(ci_request_t *req,int timeout); 35 | CI_DECLARE_FUNC(int) ci_client_get_server_options_nonblocking(ci_request_t *req); 36 | 37 | CI_DECLARE_FUNC(int) ci_client_icapfilter(ci_request_t *req, 38 | int timeout, 39 | ci_headers_list_t *req_headers, 40 | ci_headers_list_t *resp_headers, 41 | void *data_source, 42 | int (*source_read)(void *,char *,int), 43 | void *data_dest, 44 | int (*dest_write) (void *,char *,int)); 45 | 46 | CI_DECLARE_FUNC(int) ci_client_request_allow_trailers(ci_request_t *req, int yesno); 47 | 48 | /** 49 | \ingroup ICAPCLIENT 50 | * Function to send HTTP objects to an ICAP server for processing. It sends 51 | * the HTTP request headers, and the HTTP response from HTTP server (headers 52 | * plus body data), and receives modified HTTP response headers and body data. 53 | \param req The ci_request_t object. 54 | \param io_action is a combination set of ci_wait_for_read and 55 | * ci_wait_for_write flags. It has the meaning that the 56 | * ci_client_icapfilter_nonblocking can read from or write to ICAP server. 57 | \param req_headers The HTTP request headers to use. 58 | \param resp_headers The HTTP response headers to use. 59 | \param data_source User data to use with source_read callback function. 60 | \param source_read Callback function to use for reading HTTP object body data. 61 | \param data_dest User data to use with dest_write callback function. 62 | \param dest_write Callback function to use for storing modified body data. 63 | \return combination of the following flags: NEEDS_TO_READ_FROM_ICAP, 64 | * NEEDS_TO_WRITE_TO_ICAP, NEEDS_TO_READ_USER_DATA and 65 | * NEEDS_TO_WRITE_USER_DATA. 66 | */ 67 | CI_DECLARE_FUNC(int) ci_client_icapfilter_nonblocking(ci_request_t * req, int io_action, 68 | ci_headers_list_t * req_headers, 69 | ci_headers_list_t * resp_headers, 70 | void *data_source, 71 | int (*source_read) (void *, char *, int), 72 | void *data_dest, 73 | int (*dest_write) (void *, char *, int)); 74 | 75 | CI_DECLARE_FUNC(int) ci_client_http_headers_completed(ci_request_t * req); 76 | 77 | CI_DECLARE_FUNC(void) ci_client_set_user_agent(const char *agent); 78 | 79 | CI_DECLARE_FUNC(void) ci_client_library_init(); 80 | 81 | CI_DECLARE_FUNC(void) ci_client_library_release(); 82 | 83 | /** Deprecated. Use ci_connect_to declared in net_io.h instead. */ 84 | CI_DECLARE_FUNC(ci_connection_t *) ci_client_connect_to(char *servername,int port,int proto); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* __C_ICAP_CLIENT_H */ 91 | -------------------------------------------------------------------------------- /os/win32/shared_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #include 22 | #include "c-icap.h" 23 | #include "debug.h" 24 | #include "shared_mem.h" 25 | 26 | 27 | 28 | void *ci_shared_mem_create(ci_shared_mem_id_t * id, const char *name, int size) 29 | { 30 | HANDLE hMapFile; 31 | LPVOID lpMapAddress; 32 | SECURITY_ATTRIBUTES saAttr; 33 | 34 | saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 35 | saAttr.bInheritHandle = TRUE; 36 | saAttr.lpSecurityDescriptor = NULL; 37 | 38 | hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, // current file handle 39 | NULL, // default security 40 | PAGE_READWRITE, // read/write permission 41 | 0, // First 32 bit of size (Not used) 42 | size, // Second 32 bit of size 43 | NULL); // name of mapping object 44 | 45 | if (hMapFile == NULL) { 46 | ci_debug_printf(1, 47 | "Could not create file mapping object:(error:%d)\n", 48 | GetLastError()); 49 | return NULL; 50 | } 51 | 52 | 53 | lpMapAddress = MapViewOfFile(hMapFile, // handle to mapping object 54 | FILE_MAP_ALL_ACCESS, // read/write permission 55 | 0, // max. object size 56 | 0, // size of hFile 57 | 0); // map entire file 58 | 59 | if (lpMapAddress == NULL) { 60 | ci_debug_printf(1, "Could not map view of file.(error:%d)\n", 61 | GetLastError()); 62 | CloseHandle(hMapFile); 63 | return NULL; 64 | } 65 | 66 | strncpy(id->name, name, CI_SHARED_MEM_NAME_SIZE); 67 | id->size = size; 68 | id->id = hMapFile; 69 | id->mem = lpMapAddress; 70 | return lpMapAddress; 71 | } 72 | 73 | 74 | void *ci_shared_mem_attach(ci_shared_mem_id_t * id) 75 | { 76 | LPVOID lpMapAddress; 77 | lpMapAddress = MapViewOfFile(id->id, // handle to mapping object 78 | FILE_MAP_ALL_ACCESS, // read/write permission 79 | 0, // max. object size 80 | 0, // size of hFile 81 | 0); // map entire file 82 | 83 | if (lpMapAddress == NULL) { 84 | ci_debug_printf(1, "Could not map view of file.(error:%d)\n", 85 | GetLastError()); 86 | CloseHandle(id->id); 87 | return NULL; 88 | } 89 | 90 | id->mem = lpMapAddress; 91 | return lpMapAddress; 92 | } 93 | 94 | int ci_shared_mem_detach(ci_shared_mem_id_t * id) 95 | { 96 | CloseHandle(id->id); 97 | UnmapViewOfFile(id->mem); 98 | return 1; 99 | } 100 | 101 | 102 | int ci_shared_mem_destroy(ci_shared_mem_id_t * id) 103 | { 104 | CloseHandle(id->id); 105 | UnmapViewOfFile(id->mem); 106 | return 1; 107 | } 108 | -------------------------------------------------------------------------------- /include/mem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_MEM_H 21 | #define __C_ICAP_MEM_H 22 | 23 | #include "c-icap.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | enum allocator_types {OS_ALLOC, SERIAL_ALLOC, POOL_ALLOC, PACK_ALLOC}; 31 | 32 | typedef struct ci_mem_allocator { 33 | void *(*alloc)(struct ci_mem_allocator *,size_t size); 34 | void (*free)(struct ci_mem_allocator *,void *); 35 | void (*reset)(struct ci_mem_allocator *); 36 | void (*destroy)(struct ci_mem_allocator *); 37 | void *data; 38 | char *name; 39 | int type; 40 | int must_free; 41 | } ci_mem_allocator_t; 42 | 43 | CI_DECLARE_DATA extern ci_mem_allocator_t *ci_os_allocator; 44 | CI_DECLARE_DATA extern ci_mem_allocator_t *default_allocator; /* Deprecated */ 45 | 46 | CI_DECLARE_FUNC(void) ci_mem_allocator_destroy(ci_mem_allocator_t *allocator); 47 | CI_DECLARE_FUNC(ci_mem_allocator_t *) ci_create_os_allocator(); 48 | CI_DECLARE_FUNC(ci_mem_allocator_t *) ci_create_serial_allocator(size_t size); 49 | 50 | /*pack_allocator related functions ....*/ 51 | CI_DECLARE_FUNC(ci_mem_allocator_t *) ci_create_pack_allocator(char *memblock, size_t size); 52 | CI_DECLARE_FUNC(int) ci_pack_allocator_data_size(ci_mem_allocator_t *allocator); 53 | CI_DECLARE_FUNC(void *) ci_pack_allocator_alloc(ci_mem_allocator_t *allocator,size_t size); 54 | CI_DECLARE_FUNC(void) ci_pack_allocator_free(ci_mem_allocator_t *allocator,void *p); 55 | /*The following six functions are only for c-icap internal use....*/ 56 | CI_DECLARE_FUNC(ci_mem_allocator_t *)ci_create_pack_allocator_on_memblock(char *memblock, size_t size); 57 | CI_DECLARE_FUNC(size_t) ci_pack_allocator_required_size(); 58 | CI_DECLARE_FUNC(void *) ci_pack_allocator_alloc_unaligned(ci_mem_allocator_t *allocator, size_t size); 59 | CI_DECLARE_FUNC(void *) ci_pack_allocator_alloc_from_rear2(ci_mem_allocator_t *allocator, int size, int align); 60 | CI_DECLARE_FUNC(void *) ci_pack_allocator_alloc_from_rear(ci_mem_allocator_t *allocator, int size); 61 | CI_DECLARE_FUNC(void *) ci_pack_allocator_alloc_from_rear_unaligned(ci_mem_allocator_t *allocator, int size); 62 | CI_DECLARE_FUNC(void) ci_pack_allocator_set_start_pos(ci_mem_allocator_t *allocator, void *p); 63 | CI_DECLARE_FUNC(void) ci_pack_allocator_set_end_pos(ci_mem_allocator_t *allocator, void *p); 64 | 65 | CI_DECLARE_FUNC(int) ci_buffers_init(); 66 | CI_DECLARE_FUNC(void) ci_buffers_destroy(); 67 | 68 | CI_DECLARE_FUNC(void *) ci_buffer_alloc(size_t block_size); 69 | CI_DECLARE_FUNC(void *) ci_buffer_alloc2(size_t block_size, size_t *allocated_size); 70 | CI_DECLARE_FUNC(void *) ci_buffer_realloc(void *data, size_t block_size); 71 | CI_DECLARE_FUNC(void *) ci_buffer_realloc2(void *data, size_t block_size, size_t *allocated_size); 72 | CI_DECLARE_FUNC(void) ci_buffer_free(void *data); 73 | 74 | CI_DECLARE_FUNC(size_t) ci_buffer_size(const void *data); 75 | CI_DECLARE_FUNC(int) ci_buffer_check(const void *data); 76 | 77 | CI_DECLARE_FUNC(int) ci_object_pool_register(const char *name, int size); 78 | CI_DECLARE_FUNC(void) ci_object_pool_unregister(int id); 79 | CI_DECLARE_FUNC(void *) ci_object_pool_alloc(int id); 80 | CI_DECLARE_FUNC(void) ci_object_pool_free(void *ptr); 81 | 82 | CI_DECLARE_FUNC(int) ci_mem_init(); 83 | CI_DECLARE_FUNC(void) ci_mem_exit(); 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /port.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 20016 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "array.h" 23 | #include "port.h" 24 | #ifdef USE_OPENSSL 25 | #include "net_io_ssl.h" 26 | #endif 27 | #include "debug.h" 28 | 29 | static int mystrcmp(const char *s1, const char *s2) 30 | { 31 | if (s1 && !s2) 32 | return 1; 33 | if (!s1 && s2) 34 | return -1; 35 | if (!s1 && !s2) 36 | return 0; 37 | return strcmp(s1, s2); 38 | } 39 | 40 | static int ci_port_compare_config(ci_port_t *src, ci_port_t *dst) 41 | { 42 | if (dst->port != src->port) 43 | return 0; 44 | 45 | if (mystrcmp(dst->address, src->address)) 46 | return 0; 47 | 48 | /*fd, configured, protocol_family and secs_to_linger are filled by c-icap while port configured*/ 49 | 50 | if (dst->tls_enabled != src->tls_enabled) 51 | return 0; 52 | return 1; 53 | } 54 | 55 | static void ci_port_move_configured(ci_port_t *dst, ci_port_t *src) 56 | { 57 | dst->configured = src->configured; 58 | dst->accept_socket = src->accept_socket; 59 | dst->stat_connections = src->stat_connections; 60 | dst->proto = src->proto; 61 | src->configured = 0; 62 | src->accept_socket = CI_SOCKET_INVALID; 63 | src->stat_connections = -1; 64 | 65 | dst->tls_enabled = src->tls_enabled; 66 | #ifdef USE_OPENSSL 67 | dst->tls_accept_details = src->tls_accept_details; 68 | src->tls_accept_details = NULL; 69 | if (src->tls_enabled) 70 | ci_port_reconfigure_tls(dst); 71 | #endif 72 | } 73 | 74 | void ci_port_handle_reconfigure(ci_vector_t *new_ports, ci_vector_t *old_ports) 75 | { 76 | int i, k; 77 | ci_port_t *find_port, *check_port, *check_old_port; 78 | for (i = 0; (check_port = (ci_port_t *)ci_vector_get(new_ports, i)) != NULL; ++i) { 79 | for (k = 0, find_port = NULL; (find_port == NULL) && ((check_old_port = (ci_port_t *)ci_vector_get(old_ports, k)) != NULL); ++k ) { 80 | if (ci_port_compare_config(check_port, check_old_port)) { 81 | find_port = check_port; 82 | ci_port_move_configured(check_port, check_old_port); 83 | } 84 | } 85 | if (find_port) 86 | ci_debug_printf(1, "Port %d is already configured\n", find_port->port); 87 | } 88 | } 89 | 90 | void ci_port_close(ci_port_t *port) 91 | { 92 | if (!ci_socket_valid(port->accept_socket)) 93 | return; 94 | 95 | #ifdef USE_OPENSSL 96 | if (port->tls_accept_details) 97 | icap_close_server_tls(port); 98 | else 99 | #endif 100 | close(port->accept_socket); 101 | port->proto = 0; 102 | port->accept_socket = CI_SOCKET_INVALID; 103 | port->configured = 0; 104 | } 105 | 106 | void ci_port_list_release(ci_vector_t *ports) 107 | { 108 | int i; 109 | ci_port_t *p; 110 | 111 | for (i = 0; (p = (ci_port_t *)ci_vector_get(ports, i)) != NULL; ++i) { 112 | ci_port_close(p); 113 | if (p->address) 114 | free(p->address); 115 | #ifdef USE_OPENSSL 116 | if (p->tls_server_cert) 117 | free(p->tls_server_cert); 118 | if (p->tls_server_key) 119 | free(p->tls_server_key); 120 | if (p->tls_client_ca_certs) 121 | free(p->tls_client_ca_certs); 122 | if (p->tls_cafile) 123 | free(p->tls_cafile); 124 | if (p->tls_capath) 125 | free(p->tls_capath); 126 | if (p->tls_ciphers) 127 | free(p->tls_ciphers); 128 | #endif 129 | } 130 | 131 | ci_vector_destroy(ports); 132 | } 133 | -------------------------------------------------------------------------------- /modules/perl_handler.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "service.h" 23 | #include "module.h" 24 | #include "header.h" 25 | #include "body.h" 26 | #include "debug.h" 27 | 28 | #include "EXTERN.h" 29 | #include "perl.h" 30 | #include "XSUB.h" 31 | 32 | 33 | 34 | struct perl_data { 35 | PerlInterpreter *perl; 36 | }; 37 | 38 | int init_perl_handler(struct ci_server_conf *server_conf); 39 | ci_service_module_t *load_perl_module(const char *service_file, const char **args); 40 | 41 | 42 | CI_DECLARE_DATA service_handler_module_t module = { 43 | "perl_handler", 44 | ".pl,.pm,.plx", 45 | init_perl_handler, 46 | NULL, /*post_init .... */ 47 | NULL, /*release handler */ 48 | load_perl_module, 49 | NULL 50 | }; 51 | 52 | 53 | 54 | int perl_init_service(ci_service_xdata_t *srv_xdata, 55 | struct ci_server_conf *server_conf); 56 | void perl_close_service(); 57 | void *perl_init_request_data(ci_request_t *); 58 | void perl_release_request_data(void *data); 59 | 60 | 61 | int perl_check_preview_handler(char *preview_data, int preview_data_len, 62 | ci_request_t *); 63 | int perl_end_of_data_handler(ci_request_t *); 64 | int perl_service_io(char *rbuf, int *rlen, char *wbuf, int *wlen, int iseof, 65 | ci_request_t *req); 66 | 67 | 68 | int init_perl_handler(struct ci_server_conf *server_conf) 69 | { 70 | return 0; 71 | } 72 | 73 | 74 | ci_service_module_t *load_perl_module(const char *service_file, const char **args) 75 | { 76 | ci_service_module_t *service = NULL; 77 | struct perl_data *perl_data; 78 | char *argv[2]; 79 | argv[0] = NULL; 80 | argv[1] = (char *)service_file; 81 | service = malloc(sizeof(ci_service_module_t)); 82 | perl_data = malloc(sizeof(struct perl_data)); 83 | 84 | perl_data->perl = perl_alloc(); /*Maybe it is better to allocate a perl interpreter per request */ 85 | perl_construct(perl_data->perl); 86 | perl_parse(perl_data->perl, NULL, 2, argv, NULL); 87 | perl_run(perl_data->perl); 88 | 89 | service->mod_data = perl_data; 90 | 91 | service->mod_init_service = perl_init_service; 92 | service->mod_post_init_service = NULL; 93 | service->mod_close_service = perl_close_service; 94 | service->mod_init_request_data = perl_init_request_data; 95 | service->mod_release_request_data = perl_release_request_data; 96 | service->mod_check_preview_handler = perl_check_preview_handler; 97 | service->mod_end_of_data_handler = perl_end_of_data_handler; 98 | service->mod_service_io = perl_service_io; 99 | 100 | 101 | service->mod_name = strdup("perl_test"); 102 | service->mod_type = ICAP_REQMOD | ICAP_RESPMOD; 103 | 104 | ci_debug_printf(1, "OK service %s loaded\n", service_file); 105 | return service; 106 | } 107 | 108 | 109 | 110 | 111 | int perl_init_service(ci_service_xdata_t *srv_xdata, 112 | struct ci_server_conf *server_conf) 113 | { 114 | return 0; 115 | } 116 | 117 | void perl_close_service() 118 | { 119 | 120 | } 121 | 122 | 123 | void *perl_init_request_data(ci_request_t *req) 124 | { 125 | return NULL; 126 | } 127 | 128 | void perl_release_request_data(void *data) 129 | { 130 | 131 | } 132 | 133 | 134 | int perl_check_preview_handler(char *preview_data, int preview_data_len, 135 | ci_request_t *req) 136 | { 137 | return EC_500; 138 | } 139 | 140 | int perl_end_of_data_handler(ci_request_t *req) 141 | { 142 | return 0; 143 | } 144 | 145 | 146 | int perl_service_io(char *rbuf, int *rlen, char *wbuf, int *wlen, int iseof, 147 | ci_request_t *req) 148 | { 149 | *rlen = 0; 150 | *wlen = 0; 151 | return CI_OK; 152 | } 153 | -------------------------------------------------------------------------------- /include/proc_threads_queues.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2021 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_PROC_THREADS_QUEUES_H 22 | #define __C_ICAP_PROC_THREADS_QUEUES_H 23 | 24 | #include "array.h" 25 | #include "net_io.h" 26 | #include "ci_threads.h" 27 | #include "proc_mutex.h" 28 | #include "shared_mem.h" 29 | #include "stats.h" 30 | 31 | #ifdef __cplusplus 32 | extern "C" 33 | { 34 | #endif 35 | 36 | enum KILL_MODE {NO_KILL = 0,GRACEFULLY,IMMEDIATELY}; 37 | 38 | #ifdef _WIN32 39 | #define process_pid_t HANDLE 40 | #define ci_pipe_t HANDLE 41 | #else 42 | #define process_pid_t int 43 | #define ci_pipe_t int 44 | #endif 45 | 46 | struct connections_queue_item { 47 | ci_connection_t conn; 48 | int proto; 49 | }; 50 | 51 | struct connections_queue { 52 | ci_list_t *connections; 53 | int used; 54 | int warn_size; 55 | ci_thread_mutex_t queue_mtx; 56 | ci_thread_mutex_t cond_mtx; 57 | ci_thread_cond_t queue_cond; 58 | }; 59 | 60 | 61 | typedef struct child_shared_data { 62 | int servers; 63 | _CI_ATOMIC_TYPE int32_t usedservers; 64 | _CI_ATOMIC_TYPE int64_t requests; 65 | process_pid_t pid; 66 | int idle; 67 | int to_be_killed; 68 | int father_said; 69 | ci_pipe_t pipe; 70 | void *stats; 71 | int stats_size; 72 | } child_shared_data_t; 73 | 74 | typedef struct ci_server_shared_blob { 75 | union { 76 | struct { 77 | uint64_t c1; 78 | uint64_t c2; 79 | uint64_t c3; 80 | uint64_t c4; 81 | } c64; 82 | unsigned char c8[32]; 83 | } blob32b; 84 | } ci_server_shared_blob_t; 85 | 86 | struct server_statistics { 87 | unsigned int started_childs; 88 | unsigned int closed_childs; 89 | unsigned int crashed_childs; 90 | uint64_t history_requests; 91 | int blob_count; 92 | ci_server_shared_blob_t blobs[]; 93 | }; 94 | 95 | struct childs_queue { 96 | child_shared_data_t *childs; 97 | int size; 98 | int shared_mem_size; 99 | int stats_block_size; 100 | void *stats_area; 101 | ci_stat_memblock_t *stats_history; 102 | void *histo_area; 103 | size_t histo_size; 104 | ci_shared_mem_id_t shmid; 105 | ci_proc_mutex_t queue_mtx; 106 | struct server_statistics *srv_stats; 107 | }; 108 | 109 | 110 | 111 | struct connections_queue *init_queue(int size); 112 | void destroy_queue(struct connections_queue *q); 113 | int put_to_queue(struct connections_queue *q, struct connections_queue_item *con); 114 | int get_from_queue(struct connections_queue *q, struct connections_queue_item *con); 115 | int wait_for_queue(struct connections_queue *q); 116 | #define connections_pending(q) (q->used) 117 | 118 | 119 | struct childs_queue *create_childs_queue(int size); 120 | int destroy_childs_queue(struct childs_queue *q); 121 | void announce_child(struct childs_queue *q, process_pid_t pid); 122 | int attach_childs_queue(struct childs_queue *q); 123 | int dettach_childs_queue(struct childs_queue *q); 124 | int childs_queue_is_empty(struct childs_queue *q); 125 | child_shared_data_t *get_child_data(struct childs_queue *q, process_pid_t pid); 126 | child_shared_data_t *register_child(struct childs_queue *q, 127 | process_pid_t pid, 128 | int maxservers, 129 | ci_pipe_t pipe 130 | ); 131 | 132 | int remove_child(struct childs_queue *q, process_pid_t pid, int status); 133 | int find_a_child_to_be_killed(struct childs_queue *q); 134 | int find_a_child_nrequests(struct childs_queue *q,int max_requests); 135 | int find_an_idle_child(struct childs_queue *q); 136 | int childs_queue_stats(struct childs_queue *q, int *childs, 137 | int *freeservers, int *used, int64_t *maxrequests); 138 | void dump_queue_statistics(struct childs_queue *q); 139 | 140 | void ci_server_shared_memblob_shutdown(); 141 | #ifdef __cplusplus 142 | } 143 | #endif 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "hash.h" 22 | #include "debug.h" 23 | #include 24 | 25 | unsigned int ci_hash_compute(unsigned long hash_max_value, const void *key, int len) 26 | { 27 | unsigned long hash = 5381; 28 | const unsigned char *s = key; 29 | int i; 30 | 31 | if (len) { 32 | for (i = 0; ialloc(allocator, sizeof(struct ci_hash_table)); 51 | 52 | if (!htable) { 53 | /*a debug message ....*/ 54 | return NULL; 55 | } 56 | new_hash_size = 63; 57 | if (hash_size > 63) { 58 | while (new_hash_sizehash_table=allocator->alloc(allocator, (new_hash_size+1)*sizeof(struct ci_hash_entry *)); 65 | if (!htable->hash_table) { 66 | allocator->free(allocator, htable); 67 | return NULL; 68 | } 69 | memset(htable->hash_table, 0, (new_hash_size + 1)*sizeof(struct ci_hash_entry *)); 70 | 71 | htable->hash_table_size = new_hash_size; 72 | htable->ops = ops; 73 | htable->allocator = allocator; 74 | return htable; 75 | } 76 | 77 | void ci_hash_destroy(struct ci_hash_table *htable) 78 | { 79 | int i; 80 | struct ci_hash_entry *e; 81 | ci_mem_allocator_t *allocator = htable->allocator; 82 | for (i=0; i<= htable->hash_table_size; i++) { 83 | while (htable->hash_table[i]) { 84 | e = htable->hash_table[i]; 85 | htable->hash_table[i] = htable->hash_table[i]->hnext; 86 | allocator->free(allocator, e); 87 | } 88 | } 89 | htable->allocator->free(allocator,htable->hash_table ); 90 | allocator->free(allocator, htable); 91 | } 92 | 93 | const void * ci_hash_search(struct ci_hash_table *htable,const void *key) 94 | { 95 | struct ci_hash_entry *e; 96 | unsigned int hash=ci_hash_compute(htable->hash_table_size, key, htable->ops->size(key)); 97 | 98 | assert(hash <= htable->hash_table_size); /*is it possible?*/ 99 | 100 | e = htable->hash_table[hash]; 101 | while (e != NULL) { 102 | if (htable->ops->compare(e->key, key) == 0) 103 | return e->val; 104 | e = e->hnext; 105 | } 106 | return NULL; 107 | } 108 | 109 | void * ci_hash_add(struct ci_hash_table *htable, const void *key, const void *val) 110 | { 111 | struct ci_hash_entry *e; 112 | unsigned int hash = ci_hash_compute(htable->hash_table_size, key, htable->ops->size(key)); 113 | assert(hash <= htable->hash_table_size); 114 | 115 | e = htable->allocator->alloc(htable->allocator, sizeof(struct ci_hash_entry)); 116 | 117 | if (!e) 118 | return NULL; 119 | 120 | e->hnext = NULL; 121 | e->key = key; 122 | e->val = val; 123 | e->hash = hash; 124 | 125 | // if(htable->hash_table[hash]) 126 | // ci_debug_printf(9, "ci_hash_update:::Found %s\n", htable->hash_table[hash]->val); 127 | 128 | /*Make it the first entry in the current hash entry*/ 129 | e->hnext=htable->hash_table[hash]; 130 | htable->hash_table[hash] = e; 131 | return e; 132 | } 133 | -------------------------------------------------------------------------------- /include/c-icap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_H 22 | #define __C_ICAP_H 23 | 24 | 25 | #if defined (_MSC_VER) 26 | #include "c-icap-conf-w32.h" 27 | #else 28 | #include "c-icap-conf.h" 29 | #endif 30 | 31 | #ifdef __SYS_TYPES_H_EXISTS 32 | #include 33 | #endif 34 | 35 | #ifdef __INTTYPES_H_EXISTS 36 | #include 37 | #endif 38 | 39 | /* Required for NULL declaration, used by inlined functions. */ 40 | #include 41 | 42 | /*some defines */ 43 | #ifdef _WIN32 44 | # define CI_FILENAME_LEN _MAX_PATH 45 | # define CI_MAX_PATH _MAX_PATH 46 | #else 47 | # if defined(MAXPATHLEN) 48 | # define CI_MAX_PATH MAXPATHLEN 49 | # elif defined(PATH_MAX) 50 | # define CI_MAX_PATH PATH_MAX 51 | # else 52 | # define CI_MAX_PATH 4096 53 | # endif 54 | # define CI_FILENAME_LEN CI_MAX_PATH 55 | #endif 56 | 57 | 58 | #ifdef _WIN32 59 | # if defined(CI_BUILD_LIB) 60 | 61 | # define CI_DECLARE_FUNC(type) __declspec(dllexport) type 62 | # define CI_DECLARE_DATA __declspec(dllexport) 63 | 64 | # else 65 | 66 | # define CI_DECLARE_FUNC(type) __declspec(dllimport) type 67 | # define CI_DECLARE_DATA __declspec(dllimport) 68 | 69 | # endif 70 | 71 | # if defined (CI_BUILD_MODULE) 72 | # define CI_DECLARE_MOD_DATA __declspec(dllexport) 73 | # define CI_DECLARE_MOD_FUNC(type) __declspec(dllexport) type 74 | # endif 75 | 76 | #else 77 | 78 | /* 79 | 80 | */ 81 | #if defined (USE_VISIBILITY_ATTRIBUTE) 82 | #define CI_DECLARE_FUNC(type) __attribute__ ((visibility ("default"))) type 83 | #define CI_DECLARE_DATA __attribute__ ((visibility ("default"))) 84 | #define CI_DECLARE_MOD_DATA __attribute__ ((visibility ("default"))) 85 | #else 86 | #define CI_DECLARE_FUNC(type) type 87 | #define CI_DECLARE_DATA 88 | #define CI_DECLARE_MOD_DATA 89 | #endif 90 | #endif 91 | 92 | /* 93 | Here we are define the ci_off_t type to support large files. 94 | 95 | -A comment about lfs: 96 | In Solaris and Linux to have lfs support, if you are using 97 | only lseek and open function, you are using off_t type for offsets 98 | and compile the program with -D_FILE_OFFSET_BITS=64. This flag 99 | forces the compiler to typedefs the off_t type as an 64bit integer, 100 | uses open64, lseek64, mkstemp64 and fopen64 functions. 101 | 102 | Instead for fseek and ftell the functions fseeko and ftello must be used. 103 | This functions uses off_t argument's instead of long. 104 | Currently we are not using fseek and ftell in c-icap. 105 | 106 | The open's manual page says that the flag O_LARGEFILE must be used. Looks that 107 | it is not actually needed for linux and solaris (version 10) (but must be checked again......) 108 | 109 | The off_t type is a signed integer. It must be on all POSIX/POSIX-like 110 | systems as fseek has to be able to seek forward and backward from SEEK_CUR 111 | and SEEK_END. 112 | 113 | */ 114 | typedef off_t ci_off_t; 115 | #if CI_SIZEOF_OFF_T > CI_SIZEOF_LONG 116 | # define PRINTF_OFF_T "lld" 117 | # define CAST_OFF_T long long int 118 | # define ci_strto_off_t strtoll 119 | # define CI_STRTO_OFF_T_MAX LLONG_MAX 120 | # define CI_STRTO_OFF_T_MIN LLONG_MIN 121 | #else 122 | # define PRINTF_OFF_T "ld" 123 | # define CAST_OFF_T long int 124 | # define ci_strto_off_t strtol 125 | # define CI_STRTO_OFF_T_MAX LONG_MAX 126 | # define CI_STRTO_OFF_T_MIN LONG_MIN 127 | #endif 128 | 129 | /* 130 | Detect n-bytes alignment. 131 | Old 8 bytes alignment macro: 132 | #define _CI_ALIGN(val) ((val+7)&~7) 133 | */ 134 | struct _ci_align_test {char n[1]; double d;}; 135 | #define _CI_NBYTES_ALIGNMENT ((size_t) &(((struct _ci_align_test *)0)[0].d)) 136 | #define _CI_ALIGN(val) ((val+(_CI_NBYTES_ALIGNMENT - 1))&~(_CI_NBYTES_ALIGNMENT - 1)) 137 | 138 | /*The following block defines the base doxygen group (API group)*/ 139 | /** 140 | \defgroup API API Documentation 141 | * Functions, typedefs and structures for use with modules and services 142 | * 143 | */ 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /openssl/openssl_options.c: -------------------------------------------------------------------------------- 1 | /* 2 | Autogenerated file, build_openssl_opts.pl, Thu Jul 30 17:11:05 2020 3 | */ 4 | 5 | struct { 6 | const char *name; 7 | unsigned long int value; 8 | } OPENSSL_OPTS[] = { 9 | #if defined(SSL_OP_MICROSOFT_SESS_ID_BUG) 10 | {"SSL_OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG}, 11 | #endif 12 | #if defined(SSL_OP_NETSCAPE_CHALLENGE_BUG) 13 | {"SSL_OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG}, 14 | #endif 15 | #if defined(SSL_OP_LEGACY_SERVER_CONNECT) 16 | {"SSL_OP_LEGACY_SERVER_CONNECT", SSL_OP_LEGACY_SERVER_CONNECT}, 17 | #endif 18 | #if defined(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) 19 | {"SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG}, 20 | #endif 21 | #if defined(SSL_OP_TLSEXT_PADDING) 22 | {"SSL_OP_TLSEXT_PADDING", SSL_OP_TLSEXT_PADDING}, 23 | #endif 24 | #if defined(SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) 25 | {"SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER}, 26 | #endif 27 | #if defined(SSL_OP_SAFARI_ECDHE_ECDSA_BUG) 28 | {"SSL_OP_SAFARI_ECDHE_ECDSA_BUG", SSL_OP_SAFARI_ECDHE_ECDSA_BUG}, 29 | #endif 30 | #if defined(SSL_OP_SSLEAY_080_CLIENT_DH_BUG) 31 | {"SSL_OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG}, 32 | #endif 33 | #if defined(SSL_OP_TLS_D5_BUG) 34 | {"SSL_OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG}, 35 | #endif 36 | #if defined(SSL_OP_TLS_BLOCK_PADDING_BUG) 37 | {"SSL_OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG}, 38 | #endif 39 | #if defined(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) 40 | {"SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS}, 41 | #endif 42 | #if defined(SSL_OP_ALL) 43 | {"SSL_OP_ALL", SSL_OP_ALL}, 44 | #endif 45 | #if defined(SSL_OP_NO_QUERY_MTU) 46 | {"SSL_OP_NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU}, 47 | #endif 48 | #if defined(SSL_OP_COOKIE_EXCHANGE) 49 | {"SSL_OP_COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE}, 50 | #endif 51 | #if defined(SSL_OP_NO_TICKET) 52 | {"SSL_OP_NO_TICKET", SSL_OP_NO_TICKET}, 53 | #endif 54 | #if defined(SSL_OP_CISCO_ANYCONNECT) 55 | {"SSL_OP_CISCO_ANYCONNECT", SSL_OP_CISCO_ANYCONNECT}, 56 | #endif 57 | #if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION) 58 | {"SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION}, 59 | #endif 60 | #if defined(SSL_OP_NO_COMPRESSION) 61 | {"SSL_OP_NO_COMPRESSION", SSL_OP_NO_COMPRESSION}, 62 | #endif 63 | #if defined(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) 64 | {"SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION}, 65 | #endif 66 | #if defined(SSL_OP_NO_ENCRYPT_THEN_MAC) 67 | {"SSL_OP_NO_ENCRYPT_THEN_MAC", SSL_OP_NO_ENCRYPT_THEN_MAC}, 68 | #endif 69 | #if defined(SSL_OP_ENABLE_MIDDLEBOX_COMPAT) 70 | {"SSL_OP_ENABLE_MIDDLEBOX_COMPAT", SSL_OP_ENABLE_MIDDLEBOX_COMPAT}, 71 | #endif 72 | #if defined(SSL_OP_PRIORITIZE_CHACHA) 73 | {"SSL_OP_PRIORITIZE_CHACHA", SSL_OP_PRIORITIZE_CHACHA}, 74 | #endif 75 | #if defined(SSL_OP_SINGLE_ECDH_USE) 76 | {"SSL_OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE}, 77 | #endif 78 | #if defined(SSL_OP_SINGLE_DH_USE) 79 | {"SSL_OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE}, 80 | #endif 81 | #if defined(SSL_OP_CIPHER_SERVER_PREFERENCE) 82 | {"SSL_OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE}, 83 | #endif 84 | #if defined(SSL_OP_TLS_ROLLBACK_BUG) 85 | {"SSL_OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG}, 86 | #endif 87 | #if defined(SSL_OP_NO_ANTI_REPLAY) 88 | {"SSL_OP_NO_ANTI_REPLAY", SSL_OP_NO_ANTI_REPLAY}, 89 | #endif 90 | #if defined(SSL_OP_NO_SSLv2) 91 | {"SSL_OP_NO_SSLv2", SSL_OP_NO_SSLv2}, 92 | #endif 93 | #if defined(SSL_OP_NO_SSLv3) 94 | {"SSL_OP_NO_SSLv3", SSL_OP_NO_SSLv3}, 95 | #endif 96 | #if defined(SSL_OP_NO_TLSv1) 97 | {"SSL_OP_NO_TLSv1", SSL_OP_NO_TLSv1}, 98 | #endif 99 | #if defined(SSL_OP_NO_TLSv1_2) 100 | {"SSL_OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2}, 101 | #endif 102 | #if defined(SSL_OP_NO_TLSv1_1) 103 | {"SSL_OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1}, 104 | #endif 105 | #if defined(SSL_OP_NO_TLSv1_3) 106 | {"SSL_OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3}, 107 | #endif 108 | #if defined(SSL_OP_NO_DTLSv1) 109 | {"SSL_OP_NO_DTLSv1", SSL_OP_NO_DTLSv1}, 110 | #endif 111 | #if defined(SSL_OP_NO_DTLSv1_2) 112 | {"SSL_OP_NO_DTLSv1_2", SSL_OP_NO_DTLSv1_2}, 113 | #endif 114 | #if defined(SSL_OP_NETSCAPE_CA_DN_BUG) 115 | {"SSL_OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG}, 116 | #endif 117 | #if defined(SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) 118 | {"SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG}, 119 | #endif 120 | #if defined(SSL_OP_NO_RENEGOTIATION) 121 | {"SSL_OP_NO_RENEGOTIATION", SSL_OP_NO_RENEGOTIATION}, 122 | #endif 123 | #if defined(SSL_OP_CRYPTOPRO_TLSEXT_BUG) 124 | {"SSL_OP_CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG}, 125 | #endif 126 | {NULL, 0x0} 127 | }; 128 | -------------------------------------------------------------------------------- /os/unix/proc_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "debug.h" 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | int store_pid(char *pidfile) 30 | { 31 | int fd, bytes; 32 | pid_t pid; 33 | char strPid[30]; /*30 must be enough for storing pids on a string */ 34 | pid = getpid(); 35 | 36 | if ((fd = open(pidfile, O_CREAT | O_TRUNC | O_WRONLY, 0644)) < 0) { 37 | ci_debug_printf(1, "Cannot open the pid file: %s\n", pidfile); 38 | return 0; 39 | } 40 | snprintf(strPid, sizeof(strPid), "%d", pid); 41 | bytes = write(fd, strPid, strlen(strPid)); 42 | if (bytes != strlen(strPid)) { 43 | ci_debug_printf(1, "Cannot write to the pid file: %s\n", pidfile); 44 | } 45 | close(fd); 46 | return 1; 47 | } 48 | 49 | int clear_pid(char *pidfile) 50 | { 51 | if ( 0 != remove(pidfile)) { 52 | ci_debug_printf(1, "Cannot delete the pid file: %s Error:%d\n", pidfile, errno); 53 | return 0; 54 | } 55 | return 1; 56 | } 57 | 58 | int is_icap_running(char *pidfile) 59 | { 60 | int fd, bytes, ret; 61 | pid_t pid; 62 | char strPid[30]; /*30 must be enough for storing pids on a string */ 63 | if ((fd = open(pidfile, O_RDONLY, 0644)) < 0) { 64 | return 0; 65 | } 66 | bytes = read(fd, strPid, sizeof(strPid)); 67 | close(fd); 68 | 69 | if (bytes < 0) 70 | return 0; 71 | 72 | if (bytes < sizeof(strPid) - 1) 73 | strPid[bytes] = '\0'; 74 | else 75 | strPid[sizeof(strPid) - 1] = '\0'; /*Maybe check for errors? */ 76 | pid = strtol(strPid, NULL, 10); 77 | if (pid <= 0) /*garbage */ 78 | return 0; 79 | ret = kill(pid, 0); 80 | if (ret < 0) 81 | return 0; 82 | 83 | return 1; 84 | } 85 | 86 | int set_running_permissions(char *user, char *group) 87 | { 88 | uid_t uid; 89 | gid_t gid; 90 | char *pend; 91 | struct passwd *pwd; 92 | struct group *grp; 93 | 94 | if (group) { /*Configuration request to change ours group id */ 95 | errno = 0; 96 | gid = strtol(group, &pend, 10); 97 | if (*pend != '\0' || errno != 0) { /*string "group" does not contains a clear number */ 98 | if ((grp = getgrnam(group)) == NULL) { 99 | ci_debug_printf(1, 100 | "There is no group %s in password file!\n", 101 | group); 102 | return 0; 103 | } 104 | gid = grp->gr_gid; 105 | } else if (getgrgid(gid) == NULL) { 106 | ci_debug_printf(1, 107 | "There is no group with id=%d in password file!\n", 108 | gid); 109 | return 0; 110 | } 111 | #if HAVE_SETGROUPS 112 | if (setgroups(1, &gid) != 0) { 113 | ci_debug_printf(1, "setggroups to %d failed!!!!\n", gid); 114 | perror("setgroups failure"); 115 | return 0; 116 | } 117 | #endif 118 | 119 | if (setgid(gid) != 0) { 120 | ci_debug_printf(1, "setgid to %d failed!!!!\n", gid); 121 | perror("setgid failure"); 122 | return 0; 123 | } 124 | } 125 | 126 | 127 | if (user) { /*Gonfiguration request to change ours user id */ 128 | errno = 0; 129 | uid = strtol(user, &pend, 10); 130 | if (*pend != '\0' || errno != 0) { /*string "user" does not contain a clear number */ 131 | if ((pwd = getpwnam(user)) == NULL) { 132 | ci_debug_printf(1, 133 | "There is no user %s in password file!\n", 134 | user); 135 | return 0; 136 | } 137 | uid = pwd->pw_uid; 138 | } else if (getpwuid(uid) == NULL) { 139 | ci_debug_printf(1, 140 | "There is no user with id=%d in password file!\n", 141 | uid); 142 | return 0; 143 | } 144 | 145 | if (setuid(uid) != 0) { 146 | ci_debug_printf(1, "setuid to %d failed!!!!\n", uid); 147 | return 0; 148 | } 149 | } 150 | 151 | 152 | return 1; 153 | } 154 | -------------------------------------------------------------------------------- /os/unix/threads.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2012 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "ci_threads.h" 22 | 23 | typedef struct mutex_itm mutex_itm_t; 24 | enum MTX_TYPE { MTX_MUTEX 25 | #ifdef USE_PTHREADS_RWLOCK 26 | , MTX_RWLOCK 27 | #endif 28 | }; 29 | struct mutex_itm { 30 | union { 31 | pthread_mutex_t *mutex; 32 | #ifdef USE_PTHREADS_RWLOCK 33 | pthread_rwlock_t *rwlock; 34 | #endif 35 | } mtx; 36 | int type; 37 | mutex_itm_t *next; 38 | }; 39 | 40 | pthread_mutex_t mutexes_lock = PTHREAD_MUTEX_INITIALIZER; 41 | static mutex_itm_t *mutexes = NULL; 42 | static mutex_itm_t *last = NULL; 43 | 44 | static int init_child_mutexes_scheduled = 0; 45 | 46 | static void init_child_mutexes() 47 | { 48 | mutex_itm_t *m; 49 | pthread_mutex_init(&mutexes_lock, NULL); 50 | for (m = mutexes; m != NULL; m = m->next) { 51 | switch (m->type) { 52 | case MTX_MUTEX: 53 | pthread_mutex_init(m->mtx.mutex, NULL); 54 | break; 55 | #ifdef USE_PTHREADS_RWLOCK 56 | case MTX_RWLOCK: 57 | pthread_rwlock_init(m->mtx.rwlock, NULL); 58 | break; 59 | #endif 60 | default: /*????????*/ 61 | break; 62 | } 63 | } 64 | } 65 | 66 | static mutex_itm_t *add_mutex(void *pmutex, int type) 67 | { 68 | mutex_itm_t *m = malloc(sizeof(mutex_itm_t)); 69 | if (!m) 70 | return NULL; 71 | 72 | switch (type) { 73 | case MTX_MUTEX: 74 | m->mtx.mutex = (pthread_mutex_t *)pmutex; 75 | break; 76 | #ifdef USE_PTHREADS_RWLOCK 77 | case MTX_RWLOCK: 78 | m->mtx.rwlock = (pthread_rwlock_t *)pmutex; 79 | break; 80 | #endif 81 | default: 82 | free(m); 83 | return NULL; 84 | } 85 | 86 | m->type = type; 87 | m->next = NULL; 88 | pthread_mutex_lock(&mutexes_lock); 89 | if (mutexes == NULL) { 90 | mutexes = m; 91 | last = m; 92 | } else { 93 | last->next = m; 94 | last = last->next; 95 | } 96 | if (!init_child_mutexes_scheduled) { 97 | pthread_atfork(NULL, NULL, init_child_mutexes); 98 | init_child_mutexes_scheduled = 1; 99 | } 100 | pthread_mutex_unlock(&mutexes_lock); 101 | return m; 102 | } 103 | 104 | static void del_mutex(void *pmutex) 105 | { 106 | mutex_itm_t *m,*p = NULL; 107 | 108 | pthread_mutex_lock(&mutexes_lock); 109 | for (m = mutexes; m != NULL; m = m->next) { 110 | if (m->mtx.mutex == pmutex) { 111 | if (p == NULL) /*first item*/ 112 | mutexes = mutexes->next; 113 | else 114 | p->next = m->next; 115 | if (m == last) 116 | last = p; 117 | free(m); 118 | pthread_mutex_unlock(&mutexes_lock); 119 | return; 120 | } 121 | p = m; 122 | } 123 | pthread_mutex_unlock(&mutexes_lock); 124 | } 125 | 126 | 127 | int ci_thread_mutex_init(ci_thread_mutex_t *pmutex) 128 | { 129 | int ret; 130 | ret = pthread_mutex_init(pmutex,NULL); 131 | if (ret != 0) 132 | return ret; 133 | add_mutex(pmutex, MTX_MUTEX); //assert result!=NULL? 134 | return ret; 135 | } 136 | 137 | int ci_thread_mutex_destroy(ci_thread_mutex_t *pmutex) 138 | { 139 | del_mutex(pmutex); 140 | return pthread_mutex_destroy(pmutex); 141 | } 142 | 143 | 144 | #ifdef USE_PTHREADS_RWLOCK 145 | int ci_thread_rwlock_init(ci_thread_rwlock_t *rwlock) 146 | { 147 | int ret; 148 | ret = pthread_rwlock_init(rwlock,NULL); 149 | if (ret != 0) 150 | return ret; 151 | add_mutex(rwlock, MTX_RWLOCK); //assert result!=NULL? 152 | return ret; 153 | } 154 | 155 | int ci_thread_rwlock_destroy(ci_thread_rwlock_t *rwlock) 156 | { 157 | del_mutex(rwlock); 158 | return pthread_rwlock_destroy(rwlock); 159 | } 160 | #endif 161 | 162 | int ci_thread_cond_init(ci_thread_cond_t *pcond) 163 | { 164 | return pthread_cond_init(pcond,NULL); 165 | } 166 | 167 | int ci_thread_cond_destroy(ci_thread_cond_t *pcond) 168 | { 169 | return pthread_cond_destroy(pcond); 170 | } 171 | 172 | int ci_thread_create(ci_thread_t *pthread_id, void *(*pfunc)(void *), void *parg) 173 | { 174 | return pthread_create(pthread_id, NULL, pfunc, parg); 175 | } 176 | 177 | int ci_thread_join(ci_thread_t thread_id) 178 | { 179 | return pthread_join(thread_id,NULL); 180 | } 181 | -------------------------------------------------------------------------------- /include/commands.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_COMMANDS_H 21 | #define __C_ICAP_COMMANDS_H 22 | 23 | #include "c-icap.h" 24 | #include "proc_threads_queues.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | #define COMMANDS_BUFFER_SIZE 128 32 | 33 | #define NULL_CMD 0 34 | #define MONITOR_PROC_CMD 1 35 | #define CHILDS_PROC_CMD 2 36 | #define MONITOR_PROC_POST_CMD 4 37 | #define ALL_PROC_CMD 7 38 | #define CHILD_START_CMD 8 39 | #define CHILD_STOP_CMD 16 40 | #define ONDEMAND_CMD 32 41 | 42 | #define CI_CMD_NULL 0 43 | #define CI_CMD_MONITOR_PROC 1 /* on master process before children commands are executed*/ 44 | #define CI_CMD_CHILDS_PROC 2 /* on children*/ 45 | #define CI_CMD_MONITOR_PROC_POST 4 /*on master process after children commands are executed*/ 46 | #define CI_CMD_ALL_PROC 7 47 | #define CI_CMD_CHILD_START 8 48 | #define CI_CMD_CHILD_STOP 16 49 | #define CI_CMD_ONDEMAND 32 50 | #define CI_CMD_CHILD_CLEANUP 64 /* On master process after a child exit */ 51 | #define CI_CMD_POST_CONFIG 128 /*on master process after configuration file is read*/ 52 | #define CI_CMD_MONITOR_START 256 53 | #define CI_CMD_MONITOR_STOP 512 54 | #define CI_CMD_MONITOR_ONDEMAND 1024 55 | 56 | #define CMD_NM_SIZE 128 57 | typedef struct ci_command { 58 | char name[CMD_NM_SIZE]; 59 | int type; 60 | void *data; 61 | union { 62 | void (*command_action)(const char *name, int type,const char **argv); 63 | void (*command_action_extend)(const char *name, int type, void *data); 64 | void (*command_child_cleanup)(const char *name, process_pid_t pid, int reason, void *data); 65 | }; 66 | } ci_command_t; 67 | 68 | 69 | /* Backward compatible function for ci_command_register_ctl */ 70 | CI_DECLARE_FUNC(void) register_command(const char *name, int type, void (*command_action)(const char *name,int type, const char **argv)); 71 | 72 | /* backward compatible function for ci_command_register_action */ 73 | CI_DECLARE_FUNC(void) register_command_extend(const char *name, int type, void *data, 74 | void (*command_action) (const char *name, int type, void *data)); 75 | 76 | CI_DECLARE_FUNC(void) ci_command_register_ctl_cmd(const char *name, int type, void (*command_action)(const char *name,int type, const char **argv)); 77 | CI_DECLARE_FUNC(void) ci_command_register_action(const char *name, int type, void *data, 78 | void (*command_action) (const char *name, int type, void *data)); 79 | CI_DECLARE_FUNC(void) ci_command_schedule_on(const char *name, void *data, time_t time); 80 | CI_DECLARE_FUNC(void) ci_command_schedule(const char *name, void *data, time_t afterSecs); 81 | 82 | enum {CI_PROC_TERMINATED = 0, CI_PROC_CRASHED}; 83 | /** 84 | Register a handler for cleanup stopped children. 85 | \var name A name for this handler 86 | \var data Pointer to the user data to be passed as handler parameter 87 | \var child_cleanup_handler A pointer to the handler. 88 | 89 | The handler will be executed on master process after a child is 90 | terminated, normally or after a crash. 91 | The handler will be executed with the handler name as name parameter, 92 | the terminated process pid as pid parameter, with a non zero integer 93 | as reason parameter if child process terminated abnormally and the 94 | user data as data parameter. 95 | The handler will be executed immediately after the master process 96 | informed, maybe after a new child-process started to replace the killed one. 97 | */ 98 | CI_DECLARE_FUNC(void) ci_command_register_child_cleanup(const char *name, 99 | void *data, 100 | void (*child_cleanup_handler) (const char *name, process_pid_t pid, int reason, void *data)); 101 | 102 | /*For internal use only*/ 103 | void commands_init(); 104 | void commands_reset(); 105 | void commands_destroy(); 106 | int execute_command(ci_command_t *command, char *cmdline, int exec_type); 107 | ci_command_t *find_command(const char *cmd_line); 108 | int commands_execute_start_child(); 109 | int commands_execute_stop_child(); 110 | int execute_commands_no_lock (int cmd_type); 111 | void commands_exec_scheduled(int cmd_type); 112 | void commands_exec_child_cleanup(process_pid_t pid, int reason); 113 | 114 | #ifdef __cplusplus 115 | } 116 | #endif 117 | 118 | #endif /*__C_ICAP_COMMANDS_H*/ 119 | -------------------------------------------------------------------------------- /docs/man/c-icap.8.in: -------------------------------------------------------------------------------- 1 | .TH c-icap 8 "@PACKAGE_STRING@" 2 | .SH NAME 3 | c-icap - ICAP filtering server 4 | .SH SYNOPSIS 5 | .B c-icap 6 | [ 7 | .B \-V 8 | ] 9 | [ 10 | .B \-VV 11 | ] 12 | [ 13 | .B \-f " config-file" 14 | ] 15 | [ 16 | .B \-N 17 | ] 18 | [ 19 | .B \-d " debug-level" 20 | ] 21 | [ 22 | .B \-D 23 | ] 24 | .SH DESCRIPTION 25 | .B c-icap 26 | is an implementation of an ICAP server. It can be used with HTTP proxies that support the ICAP protocol. Most of the comercial HTTP proxies must support ICAP pcotocol. 27 | .SH OPTIONS 28 | .IP "-V" 29 | Print version 30 | .IP "-VV" 31 | Print build informations 32 | .IP "-f config-file" 33 | Specify the configuration file 34 | .IP "-N" 35 | Do not run as daemon 36 | .IP "-d level" 37 | Specify the debug level 38 | .IP "-D" 39 | Print debug info to stdout 40 | .SH FILES 41 | .I @SYSCONFDIR@/c-icap.conf 42 | .RS 43 | The main configuration file 44 | .RE 45 | .I @SYSCONFDIR@/c-icap.magic 46 | .RS 47 | In this file defined the types of files and the groups of file types. 48 | .RE 49 | .I /var/run/c-icap.pid 50 | .RS 51 | By default c-icap writes its pid in this file. The path of this file can changed using the PidFile configuration parameter in the c-icap.conf file 52 | .RE 53 | .I /var/run/c-icap.ctl 54 | .RS 55 | The commands socket. This file used to send commands to the icap server from command line. For information about implemented commands look below in the "Implemented commands" sub-section 56 | .SH NOTES 57 | .SS Implemented commands 58 | Currently the following commands are implemented: 59 | .IP "stop" 60 | .RS 61 | The c-icap will shutdown 62 | .RE 63 | .IP "reconfigure" 64 | .RS 65 | The service will reread the config file without the need to stop and restart 66 | the c-icap server. The services will be reinitialized 67 | .RE 68 | .IP "relog" 69 | .RS 70 | This command causes c-icap to close and reopen the log files. 71 | This is very useful for log rotation. 72 | .RE 73 | .PP 74 | Services and modules can define their own commands. 75 | .PP 76 | \fBExamples:\fR 77 | .IP "To reconfigure c-icap:" 78 | echo \-n "reconfigure" > /var/run/c-icap.ctl 79 | .IP "To rotate access log:" 80 | mv /var/log/c-icap/access.log /var/log/c-icap/access.log.1 81 | echo \-n "relog" > /var/run/c-icap.ctl 82 | .RE 83 | .SS Lookup tables 84 | Lookup tables are simple read-only databases. 85 | A lookup table can defined in c-icap.conf file using the form: 86 | .RE 87 | type:path 88 | .RE 89 | where the \fBtype\fR is the type of lookup table and \fBpath\fR is the extra information required to use the table (e.g. file path). Currently the following lookup table types defined internally by c-icap: 90 | .IP file 91 | Simple text file databases. The database records are stored in text files in the form: 92 | .RS 93 | key[: value1, value2 ...] 94 | .RE 95 | .RS 96 | .IP "example path definition:" 97 | .RS 98 | file:/path/to/the/file.txt 99 | .RE 100 | .RE 101 | .IP hash 102 | Similar to file lookup tables but c-icap uses fast hashes for searching. 103 | .RS 104 | .IP "example path definition:" 105 | .RS 106 | hash:/path/to/the/file.txt 107 | .RE 108 | .RE 109 | .IP regex 110 | Similar to the file lookup tables but the keys are regular expressions in the form /regex/flags . For possible flags values please read 'Regex expressions' paragraph in this manual. 111 | .RS 112 | .IP "example regex lookup table data:" 113 | /^[a-m].*/i: group1 114 | .br 115 | /^[n-z].*/i: group2 116 | .RE 117 | .IP "example path definition:" 118 | .RS 119 | regex:/path/to/the/file.txt 120 | .RE 121 | .RE 122 | .SS Regex expressions 123 | The c-icap regex expressions have the form /regex_definition/flags where "flags" 124 | is one or more letters, its of them express a flag. 125 | .IP "Common flags" 126 | .RS 127 | g This flag forces the score multiplied by the number of regex 128 | expression matches. For example if the expression matches 5 129 | times and the devined score value is 10 then the final score 130 | will be 50. 131 | .RE 132 | .RS 133 | i Do caseless matching 134 | .RE 135 | .RS 136 | m Match-any-character operators don't match a newline 137 | and ^$ operators does not match newlines within data 138 | .RE 139 | .IP "If the module compiled using the pcre library the following flags can be used" 140 | .RS 141 | s (PCRE_DOTALL) matches anything including NL 142 | .RE 143 | .RS 144 | x (PCRE_EXTENDED) Ignore whitespace and # comments 145 | .RE 146 | .RS 147 | A (PCRE_ANCHORED) Force pattern anchoring 148 | .RE 149 | .RS 150 | D (PCRE_DOLLAR_ENDONLY) $ not to match newline at end 151 | .RE 152 | .RS 153 | U (PCRE_UNGREEDY) Invert greediness of quantifiers 154 | .RE 155 | .RS 156 | X (PCRE_EXTRA) PCRE extra features 157 | .RE 158 | .RS 159 | u (PCRE_UTF8) Run in UTF-8 mode 160 | .RE 161 | 162 | .SS Runtime information 163 | Someone can retrieve runtime information using the \fBinfo\fR service. The information includes bytes received and transmited, active services, information about service usage and many other. The information provided in HTML and text format. 164 | .PP 165 | \fBExample:\fR 166 | .IP "Retrieve runtime information from command line:" 167 | .RS 168 | c-icap-client \-i localhost \-s "info?view=text" \-req "a_url" 169 | .RE 170 | .SH SEE ALSO 171 | .BR c-icap-client "(8)" 172 | .BR c-icap-stretch "(8)" 173 | .BR c-icap-config "(8)" 174 | .BR c-icap-libicapapi-config "(8)" 175 | .BR c-icap-mkbdb "(8)" 176 | .SH BUGS 177 | Many... 178 | .SH AUTHOR 179 | Tsantilas Christos 180 | -------------------------------------------------------------------------------- /include/lookup_table.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2009 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef __C_ICAP_LOOKUP_TABLE_H 21 | #define __C_ICAP_LOOKUP_TABLE_H 22 | 23 | #include "c-icap.h" 24 | #include "mem.h" 25 | #include "types_ops.h" 26 | #include "array.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" 30 | { 31 | #endif 32 | 33 | /** 34 | \defgroup LOOKUPTABLE Lookup tables api 35 | \ingroup API 36 | \brief Macros, functions and structures used to implement and use lookup tables 37 | * 38 | * Lookup tables can considered as simple read only databases where the user 39 | * can search a set of values using a key 40 | */ 41 | 42 | 43 | struct ci_lookup_table; 44 | struct ci_lookup_table_type { 45 | void *(*open)(struct ci_lookup_table *table); 46 | void (*close)(struct ci_lookup_table *table); 47 | void *(*search)(struct ci_lookup_table *table, void *key, void ***vals); 48 | void (*release_result)(struct ci_lookup_table *table_data, void **val); 49 | const void * (*get_row)(struct ci_lookup_table *table, const void *key, const char *columns[], void ***vals); 50 | char *type; 51 | }; 52 | 53 | /** 54 | * \brief The lookup table struct 55 | * \ingroup LOOKUPTABLE 56 | */ 57 | struct ci_lookup_table { 58 | void *(*open)(struct ci_lookup_table *table); 59 | void (*close)(struct ci_lookup_table *table); 60 | void *(*search)(struct ci_lookup_table *table, void *key, void ***vals); 61 | void (*release_result)(struct ci_lookup_table *table, void **val); 62 | const void * (*get_row)(struct ci_lookup_table *table, const void *key, const char *columns[], void ***vals); 63 | char *type; 64 | char *path; 65 | char *args; 66 | int cols; 67 | ci_str_vector_t *col_names; 68 | const ci_type_ops_t *key_ops; 69 | const ci_type_ops_t *val_ops; 70 | ci_mem_allocator_t *allocator; 71 | const struct ci_lookup_table_type *_lt_type; 72 | void *data; 73 | }; 74 | 75 | CI_DECLARE_FUNC(struct ci_lookup_table_type *) ci_lookup_table_type_register(struct ci_lookup_table_type *lt_type); 76 | CI_DECLARE_FUNC(void) ci_lookup_table_type_unregister(struct ci_lookup_table_type *lt_type); 77 | CI_DECLARE_FUNC(const struct ci_lookup_table_type *) ci_lookup_table_type_search(const char *type); 78 | 79 | /** 80 | * \brief Create a lookup table 81 | * \ingroup LOOKUPTABLE 82 | * 83 | \param table The path of the lookup table (eg file:/etc/c-icap/users.txt or 84 | * ldap://hostname/o=base?cn,uid?uid=chtsanti) 85 | \return A pointer to a lookup table object 86 | */ 87 | CI_DECLARE_FUNC(struct ci_lookup_table *) ci_lookup_table_create(const char *table); 88 | 89 | /** 90 | * \brief Destroy a lookup table. 91 | * \ingroup LOOKUPTABLE 92 | * 93 | \param lt Pointer to the lookup table will be destroyed. 94 | */ 95 | CI_DECLARE_FUNC(void) ci_lookup_table_destroy(struct ci_lookup_table *lt); 96 | 97 | /** 98 | * \brief Initializes the lookup table. 99 | * 100 | * \param table The lookup table object 101 | */ 102 | CI_DECLARE_FUNC(void *) ci_lookup_table_open(struct ci_lookup_table *table); 103 | 104 | 105 | /** 106 | * \brief Search for an object in the lookup table which matches a key. 107 | * 108 | * \param table The lookup table object 109 | * \param key The key value to search for 110 | * \param vals In this variable stored a 2d array which contains the return 111 | * values 112 | * \return NULL if none object matches, pointer to the object key value. 113 | */ 114 | CI_DECLARE_FUNC(const char *) ci_lookup_table_search(struct ci_lookup_table *table, const char *key, char ***vals); 115 | 116 | /** 117 | * \brief Releases the data values returned from the search method. 118 | * 119 | * \param table The lookup table object 120 | * \param val The 2d array returned from the search method 121 | */ 122 | CI_DECLARE_FUNC(void) ci_lookup_table_release_result(struct ci_lookup_table *table, void **val); 123 | 124 | /** 125 | * \brief Search for an object in the lookup table which supports named columns. 126 | * 127 | * \param table The lookup table object 128 | * \param key The key value to search for 129 | * \param columns NULL terminated array with the names of the columns to 130 | * retrieve. 131 | * \param vals In this variable stored a 2d array which contains the 132 | * requested row 133 | * \return NULL if none object matches, pointer to the object key value. 134 | */ 135 | 136 | CI_DECLARE_FUNC(const char *) ci_lookup_table_get_row(struct ci_lookup_table *table, const char *key, const char *columns[], char ***vals); 137 | 138 | #ifdef __cplusplus 139 | } 140 | #endif 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /tests/test_body.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "c-icap.h" 3 | #include "body.h" 4 | #include "cfg_param.h" 5 | #include "debug.h" 6 | #include "md5.h" 7 | #include "mem.h" 8 | #include 9 | #include 10 | 11 | static void 12 | MDPrint(const char *label, unsigned char digest[16]) 13 | { 14 | unsigned int i; 15 | printf("%s:", label); 16 | for (i = 0; i < 16; i++) 17 | printf("%02x", digest[i]); 18 | printf("\n"); 19 | } 20 | 21 | void log_errors(void *unused, const char *format, ...) 22 | { 23 | va_list ap; 24 | va_start(ap, format); 25 | vfprintf(stderr, format, ap); 26 | va_end(ap); 27 | } 28 | 29 | char *FILENAME = NULL; 30 | int USE_DEBUG_LEVEL = -1; 31 | static struct ci_options_entry options[] = { 32 | { 33 | "-d", "debug_level", &USE_DEBUG_LEVEL, ci_cfg_set_int, 34 | "The debug level" 35 | }, 36 | { 37 | "-f", "file", &FILENAME, ci_cfg_set_str, 38 | "The path of the file to load" 39 | }, 40 | {NULL,NULL,NULL,NULL,NULL} 41 | }; 42 | 43 | int init_body_system(); 44 | int main(int argc,char *argv[]) 45 | { 46 | ci_membuf_t *mb = NULL; 47 | ci_simple_file_t *sf = NULL; 48 | ci_cfg_lib_init(); 49 | ci_mem_init(); 50 | init_body_system(); 51 | 52 | __log_error = (void (*)(void *, const char *,...)) log_errors; /*set c-icap library log function */ 53 | 54 | if (!ci_args_apply(argc, argv, options) || !FILENAME) { 55 | ci_args_usage(argv[0], options); 56 | exit(-1); 57 | } 58 | 59 | if (USE_DEBUG_LEVEL >= 0) 60 | CI_DEBUG_LEVEL = USE_DEBUG_LEVEL; 61 | 62 | FILE *f; 63 | char buf[4096]; 64 | 65 | if ((f = fopen(FILENAME, "r")) == NULL) { 66 | ci_debug_printf(1, "Can not open file '%s'!\n", FILENAME); 67 | exit(-1); 68 | } 69 | 70 | if (!(sf = ci_simple_file_new(0))) { 71 | ci_debug_printf(1, "Error allocating simple body struct!\n"); 72 | exit(-1); 73 | } 74 | 75 | ci_MD5_CTX md; 76 | unsigned char digest[16]; 77 | ci_MD5Init(&md); 78 | size_t bytes; 79 | while ((bytes = fread(buf, 1, sizeof(buf), f))) { 80 | ci_MD5Update(&md, (unsigned char *)buf, bytes); 81 | ci_simple_file_write(sf, buf, bytes, 0); 82 | } 83 | ci_simple_file_write(sf, buf, 0, 1); 84 | 85 | ci_MD5Final(digest, &md); 86 | MDPrint("File md5", digest); 87 | 88 | 89 | mb = ci_simple_file_to_membuf(sf, CI_MEMBUF_CONST); 90 | ci_MD5Init(&md); 91 | ci_MD5Update(&md, (unsigned char *)mb->buf, mb->endpos); 92 | ci_MD5Final(digest, &md); 93 | MDPrint("ci_simple_file_t to ci_membuf_t, whole string md5", digest); 94 | 95 | ci_MD5Init(&md); 96 | int len; 97 | while ((len = ci_membuf_read(mb, buf, sizeof(buf))) > 0) { 98 | ci_MD5Update(&md, (unsigned char *)buf, len); 99 | } 100 | ci_MD5Final(digest, &md); 101 | MDPrint("ci_simple_file_t to ci_membuf_t read blocks md5", digest); 102 | 103 | if (mb) 104 | ci_membuf_free(mb); 105 | 106 | mb = ci_membuf_new_sized(65*1024); 107 | ci_membuf_flag(mb, CI_MEMBUF_NULL_TERMINATED); 108 | while ((len = ci_simple_file_read(sf, buf, sizeof(buf))) > 0) 109 | ci_membuf_write(mb, buf, len, 0); 110 | ci_membuf_write(mb, buf, 0, 1); 111 | ci_MD5Init(&md); 112 | ci_MD5Update(&md, (unsigned char *)mb->buf, mb->endpos); 113 | ci_MD5Final(digest, &md); 114 | MDPrint("new membuf_t build from read blocks from ci_simple_file, whole string md5", digest); 115 | 116 | ci_simple_file_destroy(sf); 117 | 118 | /* Test RING mode*/ 119 | printf("\nTesting ci_simple_file ring mode\n"); 120 | ci_MD5_CTX md2; 121 | unsigned char digest2[16]; 122 | ci_MD5Init(&md); 123 | ci_MD5Init(&md2); 124 | rewind(f); 125 | if (!(sf = ci_simple_file_new(128*1024))) { 126 | ci_debug_printf(1, "Error allocating simple body struct!\n"); 127 | exit(-1); 128 | } 129 | 130 | char buf2[sizeof(buf)]; 131 | int ret; 132 | size_t written, tryread; 133 | int getback; 134 | srand((unsigned int)time(NULL)); 135 | while ((bytes = fread(buf, 1, sizeof(buf), f))) { 136 | ci_MD5Update(&md, (unsigned char *)buf, bytes); 137 | written = 0; 138 | do { 139 | ret = ci_simple_file_write(sf, buf + written, bytes - written, 0); 140 | if (ret < 0) { 141 | ci_debug_printf(1, "Error writing to out file"); 142 | exit(-1); 143 | } 144 | written += ret; 145 | 146 | tryread = ((sizeof(buf2) / 2 ) * rand()) / RAND_MAX; 147 | getback = ci_simple_file_read(sf, buf2, tryread); 148 | ci_debug_printf(7, "written:%lu, read %d (/%lu)\n", written, getback, tryread); 149 | ci_MD5Update(&md2, (unsigned char *)buf2, getback); 150 | } while (written < bytes); 151 | } 152 | ci_simple_file_write(sf, buf, 0, 1); 153 | 154 | while ((getback = ci_simple_file_read(sf, buf2, sizeof(buf2))) > 0) { 155 | ci_debug_printf(7, "written:-, read %d\n", getback); 156 | ci_MD5Update(&md2, (unsigned char *)buf2, getback); 157 | } 158 | 159 | ci_MD5Final(digest, &md); 160 | ci_MD5Final(digest2, &md2); 161 | MDPrint("From ci_simple_file_t ring mode before write md5", digest); 162 | MDPrint("From ci_simple_file_t ring mode after read md5", digest2); 163 | 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /registry.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "array.h" 23 | #include "debug.h" 24 | #include "registry.h" 25 | 26 | static ci_ptr_array_t *REGISTRIES = NULL; 27 | static int32_t REG_ITEMS_COUNT = 0; 28 | 29 | int ci_registry_create(const char *name) 30 | { 31 | /* 32 | Build space for 1024 different registries. 33 | It should be enough. 34 | */ 35 | if (!REGISTRIES) 36 | REGISTRIES = ci_ptr_array_new2(1024); 37 | else if (ci_ptr_array_search(REGISTRIES, name)) { 38 | ci_debug_printf(1, "Registry '%s' already exist!\n", name); 39 | return -1; 40 | } 41 | 42 | ci_ptr_dyn_array_t *registry = ci_ptr_dyn_array_new(1024); 43 | 44 | ci_ptr_array_add(REGISTRIES, name, registry); 45 | ci_debug_printf(4, "Registry '%s' added and is ready to store new registry entries\n", name); 46 | return (REGISTRIES->count - 1); /*Return the pos in the REGISTRIES array*/ 47 | } 48 | 49 | void ci_registry_clean() 50 | { 51 | ci_ptr_dyn_array_t *registry = NULL; 52 | char buf[1024]; 53 | 54 | if (!REGISTRIES) 55 | return; 56 | 57 | while ((registry = (ci_ptr_dyn_array_t *)ci_ptr_array_pop_value(REGISTRIES, buf, sizeof(buf))) != NULL) { 58 | ci_debug_printf(4, "Registry %s removed\n", buf); 59 | ci_ptr_dyn_array_destroy(registry); 60 | } 61 | ci_ptr_array_destroy(REGISTRIES); 62 | REGISTRIES = NULL; 63 | } 64 | 65 | int ci_registry_iterate(const char *name, void *data, int (*fn)(void *data, const char *label, const void *)) 66 | { 67 | const ci_ptr_dyn_array_t *registry = NULL; 68 | if (!REGISTRIES || (registry = ci_ptr_array_search(REGISTRIES, name)) == NULL) { 69 | ci_debug_printf(1, "Registry '%s' does not exist!\n", name); 70 | return 0; 71 | } 72 | ci_ptr_dyn_array_iterate(registry, data, fn); 73 | return 1; 74 | } 75 | 76 | int ci_registry_add_item(const char *name, const char *label, const void *obj) 77 | { 78 | ci_ptr_dyn_array_t *registry = NULL; 79 | if (!REGISTRIES || (registry = ci_ptr_array_search(REGISTRIES, name)) == NULL) { 80 | ci_debug_printf(3, "Registry '%s' does not exist create it\n", name); 81 | if (ci_registry_create(name) < 0) 82 | return 0; 83 | registry = ci_ptr_array_search(REGISTRIES, name); 84 | } 85 | if (ci_ptr_dyn_array_add(registry, label, (void *)obj)) 86 | return ++REG_ITEMS_COUNT; 87 | 88 | return 0; 89 | } 90 | 91 | const void * ci_registry_get_item(const char *name, const char *label) 92 | { 93 | ci_ptr_dyn_array_t *registry = NULL; 94 | if (!REGISTRIES || (registry = ci_ptr_array_search(REGISTRIES, name)) == NULL) { 95 | ci_debug_printf(1, "Registry '%s' does not exist!\n", name); 96 | return NULL; 97 | } 98 | 99 | return ci_ptr_dyn_array_search(registry, label); 100 | } 101 | 102 | struct check_reg_data { 103 | const char *name; 104 | int found; 105 | int count; 106 | }; 107 | 108 | static int check_reg(void *data, const char *name, const void *val) 109 | { 110 | struct check_reg_data *rdata = (struct check_reg_data *) data; 111 | rdata->count++; 112 | if (strcmp(rdata->name, name) == 0) { 113 | rdata->found = 1; 114 | return 1; /*Found the registry, return !=0 to stop iteration*/ 115 | } 116 | return 0; 117 | } 118 | 119 | int ci_registry_get_id(const char *name) 120 | { 121 | struct check_reg_data rdata; 122 | rdata.name = name; 123 | rdata.found = 0; 124 | rdata.count = 0; 125 | 126 | if (REGISTRIES) 127 | ci_ptr_array_iterate(REGISTRIES, &rdata, check_reg); 128 | 129 | if (rdata.found) 130 | return (rdata.count - 1); 131 | else 132 | return -1; 133 | } 134 | 135 | int ci_registry_id_iterate(int reg_id, void *data, int (*fn)(void *data, const char *label, const void *)) 136 | { 137 | const ci_ptr_dyn_array_t *registry = NULL; 138 | const ci_array_item_t *ai; 139 | if (!REGISTRIES || (ai = ci_ptr_array_get_item(REGISTRIES, reg_id)) == NULL || (registry = ai->value) == NULL) { 140 | ci_debug_printf(1, "Registry with id='%d' does not exist!\n", reg_id); 141 | return 0; 142 | } 143 | ci_ptr_dyn_array_iterate(registry, data, fn); 144 | return 1; 145 | } 146 | 147 | const void * ci_registry_id_get_item(int reg_id, const char *label) 148 | { 149 | const ci_ptr_dyn_array_t *registry = NULL; 150 | const ci_array_item_t *ai; 151 | if (!REGISTRIES || (ai = ci_ptr_array_get_item(REGISTRIES, reg_id)) == NULL || (registry = ai->value) == NULL) { 152 | ci_debug_printf(1, "Registry with id='%d' does not exist!\n", reg_id); 153 | return 0; 154 | } 155 | return ci_ptr_dyn_array_search(registry, label); 156 | } 157 | -------------------------------------------------------------------------------- /contrib/config_to_html.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $in=$ARGV[0]; 4 | $out=$ARGV[1]; 5 | 6 | 7 | if(!open(IN,"<$in")) { 8 | print "Can't open input file: $in\n"; 9 | exit -1; 10 | } 11 | 12 | 13 | #if(!open(OUT,"<$out")){ 14 | # print "Can't open input file: $out\n"; 15 | # exit -1; 16 | #} 17 | my @TAGS; 18 | my $CurrentTag = ""; 19 | 20 | $CORE = "c-icap's core"; 21 | my $HAS_CORE = 0; 22 | 23 | my @MODS; 24 | $MODS[0]->{"Name"} = $CORE; 25 | my $CurrentModule = $CORE; 26 | my $CurrentModuleTxt = ""; 27 | my $MODINDX = 0; 28 | 29 | my $line = ; 30 | my $INDX = -1; 31 | 32 | do { 33 | START_LOOP: 34 | if ( $line =~ /#\s*TAG:\s(.*)/ ) { 35 | my $t=$1; 36 | # print "New Tag Found: ".$t."\n"; 37 | $CurrentTag= $t; 38 | $INDX = $INDX + 1; 39 | $TAGS[$INDX]->{'Name'} = $CurrentTag; 40 | $TAGS[$INDX]->{'Module'} = $CurrentModule; 41 | $TAGS[$INDX]->{'Section'} = $CORE; 42 | 43 | if ($CurrentModule eq $CORE) { 44 | $HAS_CORE = 1; 45 | } 46 | } 47 | elsif ($CurrentTag ne "" && $line =~ /#\s*Format:\s(.*)/ ) { 48 | my $f = $1; 49 | $TAGS[$INDX]->{'Format'} = $f; 50 | } 51 | elsif ($CurrentTag ne "" && $line =~ /#\s*Description:\s*/ ) { 52 | # print "Description\n"; 53 | $TAGS[$INDX]->{'Description'} = readLongTag(*IN{IO}, \$line); 54 | goto START_LOOP; 55 | } 56 | elsif ($CurrentTag ne "" && $line =~ /#\s*Default:\s*/ ) { 57 | # print "Default\n"; 58 | $TAGS[$INDX]->{'Default'} = readLongTag(*IN{IO}, \$line); 59 | goto START_LOOP; 60 | } 61 | elsif ($CurrentTag ne "" && $line =~ /#\s*Example:\s*/ ) { 62 | # print "Example\n"; 63 | $TAGS[$INDX]->{'Example'} = readLongTag(*IN{IO}, \$line); 64 | goto START_LOOP; 65 | } 66 | elsif ( $line =~ /#\s*Module:\s(.*)/ ) { 67 | my $m=$1; 68 | # print "New Tag Found: ".$t."\n"; 69 | $CurrentModule= $m; 70 | $CurrentModuleTxt = $m; 71 | $MODINDX = $MODINDX + 1; 72 | $MODS[$MODINDX]->{"Name"} = $CurrentModule; 73 | } 74 | elsif ($CurrentModuleTxt ne "" && $line =~ /#\s*Description:\s*/ ) { 75 | # print "Description module\n"; 76 | $MODS[$MODINDX]->{'Description'} = readLongTag(*IN{IO}, \$line); 77 | goto START_LOOP; 78 | } 79 | elsif ($CurrentModuleTxt ne "" && $line =~ /#\s*Example:\s*/ ) { 80 | # print "Example module\n"; 81 | $MODS[$MODINDX]->{'Example'} = readLongTag(*IN{IO}, \$line); 82 | goto START_LOOP; 83 | } 84 | elsif ( $line =~ /#\s*End module:\s(.*)/ ) { 85 | $CurrentModule= $CORE; 86 | } 87 | else { 88 | $CurrentModuleTxt = ""; 89 | $CurrentTag = ""; 90 | } 91 | } while($line = ); 92 | 93 | close(IN); 94 | # close(OUT); 95 | 96 | print "

Modules/Subsystems

"; 97 | print "
    "; 98 | foreach (@MODS) { 99 | if (!($HAS_CORE == 0 && $_->{"Name"} eq $CORE)) { 100 | print_mod_index_html("", $_->{"Name"}); 101 | } 102 | } 103 | print "
"; 104 | 105 | print "

Configuration parameters

\n\n"; 106 | foreach (@MODS) { 107 | my $modname = $_->{'Name'}; 108 | if (!($HAS_CORE == 0 && $_->{"Name"} eq $CORE)) { 109 | print_mod_html($_); 110 | print "
    "; 111 | foreach (@TAGS) { 112 | if ($modname eq $_->{'Module'}) { 113 | print_tag_index_html("", $_->{'Name'}); 114 | } 115 | } 116 | print "
\n\n"; 117 | } 118 | } 119 | print "
\n\n"; 120 | print "

Configuration parameters description

\n\n"; 121 | 122 | foreach (@TAGS) { 123 | print_tag_html($_); 124 | } 125 | 126 | 127 | 128 | sub readLongTag { 129 | my $in = shift; 130 | my $tagline = shift; 131 | my $line; 132 | my $descr; 133 | my $putLN; 134 | 135 | $descr = ""; 136 | $putLN = ""; 137 | while ($line = <$in>) { 138 | if ($line !~ /#\ *\t(.*)/) { 139 | #print "Last line for Descr: ".$line; 140 | $$tagline = $line; 141 | last; 142 | } 143 | else { 144 | $descr = $descr.$putLN.$1; 145 | $putLN = "\n"; 146 | } 147 | } 148 | $descr =~ s//>/g; 150 | return $descr; 151 | } 152 | 153 | sub print_tag_index_html{ 154 | my $indx = shift; 155 | my $tagname = shift; 156 | my $tn = $tagname; 157 | $tn =~ s/[\.|\s]/_/g; 158 | print "
  • $indx $tagname
  • \n"; 159 | } 160 | 161 | sub print_tag_html { 162 | my $tag = shift; 163 | my $tagname = $tag->{'Name'}; 164 | $tagname =~ s/[\.|\s]/_/g; 165 | print "
    \n"; 166 | print "
    ".$tag->{'Name'}."
    \n"; 167 | print "
    \n"; 168 | print "Format:
    ".$tag->{'Format'}."
    \n"; 169 | print "Description:
    ".$tag->{'Description'}."
    \n"; 170 | print "Default:
    ".$tag->{'Default'}."
    \n"; 171 | if (exists($tag->{'Example'})) { 172 | print "Example:
    ".$tag->{'Example'}."
    \n"; 173 | } 174 | print "
    "; 175 | print "
    \n\n"; 176 | } 177 | 178 | 179 | sub print_mod_index_html{ 180 | my $indx = shift; 181 | my $modname = shift; 182 | my $mn = $modname; 183 | $mn =~ s/[\.|\s]/_/g; 184 | print "
  • $indx $modname
  • \n"; 185 | } 186 | 187 | sub print_mod_html { 188 | my $mod = shift; 189 | my $modname = $mod->{'Name'}; 190 | $modname =~ s/[\.|\s]/_/g; 191 | print "

    ".$mod->{'Name'}." configuration

    \n"; 192 | if (exists($mod->{'Description'})) { 193 | print "Description:
    ".$mod->{'Description'}."
    \n"; 194 | } 195 | if (exists($mod->{'Example'})) { 196 | print "Example:
    ".$mod->{'Example'}."
    \n"; 197 | } 198 | print "\n\n"; 199 | } 200 | -------------------------------------------------------------------------------- /default_acl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | #include "common.h" 21 | #include "c-icap.h" 22 | #include "request.h" 23 | #include "module.h" 24 | #include "cfg_param.h" 25 | #include "debug.h" 26 | #include "access.h" 27 | #include "acl.h" 28 | 29 | 30 | /*********************************************************************************************/ 31 | /* Default Authenticator definitions */ 32 | int default_acl_init(struct ci_server_conf *server_conf); 33 | int default_acl_post_init(struct ci_server_conf *server_conf); 34 | void default_acl_release(); 35 | int default_acl_client_match(ci_request_t *req); 36 | int default_acl_request_match(ci_request_t *req); 37 | 38 | int cfg_default_acl_add(const char *directive, const char **argv, void *setdata); 39 | int cfg_default_acl_access(const char *directive, const char **argv, void *setdata); 40 | 41 | 42 | ci_access_entry_t *acl_connection_access_list = NULL; 43 | ci_access_entry_t *acl_access_list = NULL; 44 | 45 | /*Configuration Table .....*/ 46 | static struct ci_conf_entry acl_conf_variables[] = { 47 | {"acl", NULL, cfg_default_acl_add, NULL}, 48 | {"client_access", NULL, cfg_default_acl_access, NULL}, 49 | {"icap_access", NULL, cfg_default_acl_access, NULL}, 50 | {NULL, NULL, NULL, NULL} 51 | }; 52 | 53 | 54 | access_control_module_t default_acl = { 55 | "default_acl", 56 | default_acl_init, 57 | default_acl_post_init, /*post_init */ 58 | default_acl_release, 59 | default_acl_client_match, 60 | default_acl_request_match, 61 | acl_conf_variables 62 | }; 63 | 64 | int default_acl_init(struct ci_server_conf *server_conf) 65 | { 66 | 67 | return 1; 68 | } 69 | 70 | int default_acl_post_init(struct ci_server_conf *server_conf) 71 | { 72 | return 1; 73 | } 74 | 75 | void default_acl_release() 76 | { 77 | ci_access_entry_release(acl_access_list); 78 | ci_access_entry_release(acl_connection_access_list); 79 | acl_access_list = NULL; 80 | acl_connection_access_list = NULL; 81 | } 82 | 83 | int default_acl_client_match(ci_request_t *req) 84 | { 85 | return ci_access_entry_match_request(acl_connection_access_list, req); 86 | } 87 | 88 | int default_acl_request_match(ci_request_t *req) 89 | { 90 | return ci_access_entry_match_request(acl_access_list, req); 91 | } 92 | 93 | 94 | int cfg_default_acl_add(const char *directive, const char **argv, void *setdata) 95 | { 96 | return 1; 97 | } 98 | 99 | int cfg_default_acl_access(const char *directive, const char **argv, void *setdata) 100 | { 101 | int type, argc, error = 0; 102 | int only_connection = 0; 103 | const char *acl_spec_name; 104 | ci_access_entry_t **tolist,*access_entry; 105 | const ci_acl_spec_t *acl_spec; 106 | const ci_acl_type_t *spec_type ; 107 | 108 | if (argv[0] == NULL || argv[1] == NULL) { 109 | ci_debug_printf(1, "Parse error in directive %s \n", directive); 110 | return 0; 111 | } 112 | 113 | if (strcmp("client_access", directive) == 0) { 114 | tolist = &acl_connection_access_list; 115 | only_connection = 1; 116 | } else if (strcmp("icap_access", directive) == 0) { 117 | tolist = &acl_access_list; 118 | } else 119 | return 0; 120 | 121 | if (strcmp(argv[0], "allow") == 0) { 122 | type = CI_ACCESS_ALLOW; 123 | 124 | } else if (strcmp(argv[0], "deny") == 0) { 125 | type = CI_ACCESS_DENY; 126 | } else { 127 | ci_debug_printf(1, "Invalid directive :%s. Disabling %s acl rule \n", 128 | argv[0], argv[1]); 129 | return 0; 130 | } 131 | 132 | if ((access_entry = ci_access_entry_new(tolist, type)) == NULL) { 133 | ci_debug_printf(1,"Error creating new access entry as %s access list\n", argv[0]); 134 | return 0; 135 | } 136 | 137 | ci_debug_printf(2,"Creating new access entry as %s with specs:\n", argv[0]); 138 | for (argc=1; argv[argc] != NULL; argc++) { 139 | acl_spec_name = argv[argc]; 140 | acl_spec = ci_acl_search(acl_spec_name); 141 | if (acl_spec) 142 | spec_type = acl_spec->type; 143 | else 144 | spec_type = NULL; 145 | if (only_connection && spec_type && 146 | strcmp(spec_type->name,"port") != 0 && 147 | strcmp(spec_type->name,"src") != 0 && 148 | strcmp(spec_type->name,"srvip") != 0 ) { 149 | ci_debug_printf(1, "Only \"port\", \"src\" and \"srvip\" acl types allowed in client_access access list (given :%s)\n", acl_spec_name); 150 | error = 1; 151 | } else { 152 | if (ci_access_entry_add_acl_by_name(access_entry, acl_spec_name)) { 153 | ci_debug_printf(2,"\tAdded acl spec: %s\n", acl_spec_name); 154 | } else { 155 | ci_debug_printf(1,"The required acl spec '%s' is missing\n", acl_spec_name); 156 | error = 1; 157 | } 158 | } 159 | } 160 | if (error) 161 | return 0; 162 | else 163 | return 1; 164 | } 165 | -------------------------------------------------------------------------------- /include/ci_threads.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2008 Christos Tsantilas 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | #ifndef __C_ICAP_CI_THREADS_H 22 | #define __C_ICAP_CI_THREADS_H 23 | 24 | #include "c-icap.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | #ifndef _WIN32 32 | 33 | #include 34 | 35 | typedef pthread_mutex_t ci_thread_mutex_t; 36 | typedef pthread_cond_t ci_thread_cond_t; 37 | typedef pthread_t ci_thread_t; 38 | 39 | CI_DECLARE_FUNC(int) ci_thread_mutex_init(ci_thread_mutex_t *pmutex); 40 | CI_DECLARE_FUNC(int) ci_thread_mutex_destroy(ci_thread_mutex_t *pmutex); 41 | 42 | static inline int ci_thread_mutex_lock(ci_thread_mutex_t *mtx) { 43 | return pthread_mutex_lock(mtx); 44 | } 45 | 46 | static inline int ci_thread_mutex_unlock(ci_thread_mutex_t *mtx) { 47 | return pthread_mutex_unlock(mtx); 48 | } 49 | 50 | static inline ci_thread_t ci_thread_self() { 51 | return pthread_self(); 52 | } 53 | 54 | #ifdef USE_PTHREADS_RWLOCK 55 | 56 | typedef pthread_rwlock_t ci_thread_rwlock_t; 57 | 58 | CI_DECLARE_FUNC(int) ci_thread_rwlock_init(ci_thread_rwlock_t *); 59 | CI_DECLARE_FUNC(int) ci_thread_rwlock_destroy(ci_thread_rwlock_t *); 60 | 61 | static inline int ci_thread_rwlock_rdlock(ci_thread_rwlock_t *rwlock) { 62 | return pthread_rwlock_rdlock(rwlock); 63 | } 64 | 65 | static inline int ci_thread_rwlock_wrlock(ci_thread_rwlock_t *rwlock) { 66 | return pthread_rwlock_wrlock(rwlock); 67 | } 68 | 69 | static inline int ci_thread_rwlock_unlock(ci_thread_rwlock_t *rwlock) { 70 | return pthread_rwlock_unlock(rwlock); 71 | } 72 | 73 | #else 74 | 75 | /*Someone can implement a better solution here using a mutex and a cond 76 | object to simulate rwlocks. 77 | */ 78 | typedef pthread_mutex_t ci_thread_rwlock_t; 79 | 80 | static inline int ci_thread_rwlock_init(ci_thread_rwlock_t * rwlock) { 81 | return ci_thread_mutex_init(rwlock); 82 | } 83 | 84 | static inline int ci_thread_rwlock_destroy(ci_thread_rwlock_t * rwlock) { 85 | return ci_thread_mutex_destroy(rwlock); 86 | } 87 | 88 | static inline int ci_thread_rwlock_rdlock(ci_thread_rwlock_t * rwlock) { 89 | return ci_thread_mutex_lock(rwlock); 90 | } 91 | 92 | static inline int ci_thread_rwlock_wrlock(ci_thread_rwlock_t * rwlock) { 93 | return ci_thread_mutex_lock(rwlock); 94 | } 95 | 96 | static inline int ci_thread_rwlock_unlock(ci_thread_rwlock_t * rwlock) { 97 | return ci_thread_mutex_unlock(rwlock); 98 | } 99 | 100 | #endif 101 | 102 | CI_DECLARE_FUNC(int) ci_thread_cond_init(ci_thread_cond_t *pcond); 103 | CI_DECLARE_FUNC(int) ci_thread_cond_destroy(ci_thread_cond_t *pcond); 104 | 105 | static inline int ci_thread_cond_wait(ci_thread_cond_t *pcond, ci_thread_mutex_t *pmtx) { 106 | /*The pthread_cond_Wait can be interrupted by a signal. 107 | This is a desired behavior in many cases, but also in other 108 | cases the operation should repeated after a such abort. 109 | As this is implemented, the caller should handle signal aborts. 110 | */ 111 | return pthread_cond_wait(pcond, pmtx); 112 | } 113 | 114 | static inline int ci_thread_cond_broadcast(ci_thread_cond_t *pcond) { 115 | return pthread_cond_broadcast(pcond); 116 | } 117 | 118 | static inline int ci_thread_cond_signal(ci_thread_cond_t *pcond) { 119 | return pthread_cond_signal(pcond); 120 | } 121 | 122 | CI_DECLARE_FUNC(int) ci_thread_create(ci_thread_t *pthread_id, void *(*pfunc)(void *), void *parg); 123 | CI_DECLARE_FUNC(int) ci_thread_join(ci_thread_t thread_id); 124 | 125 | #else /*ifdef _WIN32*/ 126 | 127 | #include 128 | 129 | #define ci_thread_mutex_t CRITICAL_SECTION 130 | #define ci_thread_rwlock_t CRITICAL_SECTION 131 | #define ci_thread_cond_t HANDLE 132 | #define ci_thread_t DWORD 133 | 134 | CI_DECLARE_FUNC(int) ci_thread_mutex_init(ci_thread_mutex_t *pmutex); 135 | CI_DECLARE_FUNC(int) ci_thread_mutex_destroy(ci_thread_mutex_t *pmutex); 136 | CI_DECLARE_FUNC(int) ci_thread_mutex_lock(ci_thread_mutex_t *pmutex); 137 | CI_DECLARE_FUNC(int) ci_thread_mutex_unlock(ci_thread_mutex_t *pmutex); 138 | 139 | CI_DECLARE_FUNC(int) ci_thread_rwlock_init(ci_thread_rwlock_t *); 140 | CI_DECLARE_FUNC(int) ci_thread_rwlock_destroy(ci_thread_rwlock_t *); 141 | CI_DECLARE_FUNC(int) ci_thread_rwlock_rdlock(ci_thread_rwlock_t *); 142 | CI_DECLARE_FUNC(int) ci_thread_rwlock_wrlock(ci_thread_rwlock_t *); 143 | CI_DECLARE_FUNC(int) ci_thread_rwlock_unlock(ci_thread_rwlock_t *); 144 | 145 | CI_DECLARE_FUNC(int) ci_thread_cond_init(ci_thread_cond_t *pcond); 146 | CI_DECLARE_FUNC(int) ci_thread_cond_destroy(ci_thread_cond_t *pcond); 147 | CI_DECLARE_FUNC(int) ci_thread_cond_wait(ci_thread_cond_t *pcond,ci_thread_mutex_t *pmutex); 148 | CI_DECLARE_FUNC(int) ci_thread_cond_broadcast(ci_thread_cond_t *pcond); 149 | CI_DECLARE_FUNC(int) ci_thread_cond_signal(ci_thread_cond_t *pcond); 150 | 151 | 152 | CI_DECLARE_FUNC(int) ci_thread_create(ci_thread_t *thread_id, void *(*pfunc)(void *), void *parg); 153 | CI_DECLARE_FUNC(int) ci_thread_join(ci_thread_t thread_id); 154 | 155 | #endif 156 | 157 | #ifdef __cplusplus 158 | } 159 | #endif 160 | 161 | #endif /*__C_ICAP_CI_THREADS_H */ 162 | --------------------------------------------------------------------------------