Группа :: Система/Серверы
Пакет: c-icap
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: c-icap-20080706-alt.patch
Скачать
Скачать
Makefile.am | 6 +-
Makefile.in | 6 +-
c-icap.conf.in | 58 ++-
configure | 6 +-
configure.in | 4 +-
contrib/get_file.pl | 2 +-
filetype.c | 2 +-
include/debug.h | 2 +-
services/Makefile.am | 2 +-
services/Makefile.in | 4 +-
services/clamav/srv_clamav.c | 2 +-
services/url_filter/Makefile.am | 12 +
services/url_filter/Makefile.in | 501 +++++++++++++++++++
services/url_filter/makefile.w32 | 15 +
services/url_filter/srv_url_filter.c | 892 ++++++++++++++++++++++++++++++++++
15 files changed, 1481 insertions(+), 33 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 2e86d25..45937b2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -28,7 +28,7 @@ c_icap_SOURCES = aserver.c request.c cfg_param.c \
# libicapapi ......
libicapapi_la_CFLAGS= -Iinclude/ @ZLIB_ADD_FLAG@ -DCI_BUILD_LIB
-libicapapi_la_LIBADD = @ZLIB_ADD_LDFLAG@
+libicapapi_la_LIBADD = @ZLIB_ADD_LDFLAG@ @DL_ADD_FLAG@ @THREADS_LDADD@
libicapapi_la_LDFLAGS= -shared -version-info 0:1:0
@@ -71,10 +71,6 @@ install-data-local:
if test ! -f $(DESTDIR)$(CONFIGDIR)/c-icap.magic; then $(INSTALL) c-icap.magic $(DESTDIR)$(CONFIGDIR)/c-icap.magic; fi
$(mkinstalldirs) $(DESTDIR)$(LOGDIR);
$(mkinstalldirs) $(DESTDIR)$(SOCKDIR);
- chgrp nobody $(DESTDIR)$(LOGDIR)
- chmod 775 $(DESTDIR)$(LOGDIR)
- chgrp nobody $(DESTDIR)$(SOCKDIR)
- chmod 775 $(DESTDIR)$(SOCKDIR)
EXTRA_DIST= RECONF INSTALL.txt include/config-w32.h makefile.w32 c-icap.conf c_icap_dll.mak c-icap.conf.in c-icap.magic c_icap.mak c_icap.def \
contrib/get_file.pl contrib/convert_old_magic.pl \
diff --git a/Makefile.in b/Makefile.in
index 8ce6f2a..b6dadf8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -294,7 +294,7 @@ c_icap_SOURCES = aserver.c request.c cfg_param.c \
# libicapapi ......
libicapapi_la_CFLAGS = -Iinclude/ @ZLIB_ADD_FLAG@ -DCI_BUILD_LIB
-libicapapi_la_LIBADD = @ZLIB_ADD_LDFLAG@
+libicapapi_la_LIBADD = @ZLIB_ADD_LDFLAG@ @DL_ADD_FLAG@ @THREADS_LDADD@
libicapapi_la_LDFLAGS = -shared -version-info 0:1:0
#c_icap the main server
@@ -1306,10 +1306,6 @@ install-data-local:
if test ! -f $(DESTDIR)$(CONFIGDIR)/c-icap.magic; then $(INSTALL) c-icap.magic $(DESTDIR)$(CONFIGDIR)/c-icap.magic; fi
$(mkinstalldirs) $(DESTDIR)$(LOGDIR);
$(mkinstalldirs) $(DESTDIR)$(SOCKDIR);
- chgrp nobody $(DESTDIR)$(LOGDIR)
- chmod 775 $(DESTDIR)$(LOGDIR)
- chgrp nobody $(DESTDIR)$(SOCKDIR)
- chmod 775 $(DESTDIR)$(SOCKDIR)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/c-icap.conf.in b/c-icap.conf.in
index 2fbe4cc..665f418 100644
--- a/c-icap.conf.in
+++ b/c-icap.conf.in
@@ -3,7 +3,7 @@
#
-PidFile /var/run/c-icap.pid
+PidFile /var/run/c-icap/c-icap.pid
CommandsSocket /var/run/c-icap/c-icap.ctl
Timeout 300
KeepAlive On
@@ -19,26 +19,26 @@ MaxRequestsPerChild 0
Port 1344
-User wwwrun
+User _c_icap
Group nobody
#ServerAdmin you@your.address # Not implemented yet
#ServerName localhost:1344 # Not implemented yet
-TmpDir /var/tmp
+TmpDir /var/cache/c-icap
MaxMemObject 131072
-ServerLog @prefix@/var/log/server.log
-AccessLog @prefix@/var/log/access.log
+ServerLog /var/log/c-icap/server.log
+AccessLog /var/log/c-icap/access.log
#DebugLevel 3
-ModulesDir @prefix@/lib/c_icap
+ModulesDir @libdir@/c-icap
Module logger sys_logger.so
Module perl_handler perl_handler.so
-sys_logger.Prefix "C-ICAP:"
-sys_logger.Facility local1
+sys_logger.Prefix "C-ICAP"
+sys_logger.Facility daemon
##Specify wich logger to use......
#Logger sys_logger
@@ -89,7 +89,7 @@ Logger file_logger
#AuthMethod basic file_basic
-ServicesDir @prefix@/lib/c_icap
+ServicesDir @libdir@/c-icap
Service echo_module srv_echo.so
Service url_check_module srv_url_check.so
Service antivirus_module srv_clamav.so
@@ -112,7 +112,7 @@ srv_clamav.StartSendPercentDataAfter 2M
# The Maximum object to be scanned.
srv_clamav.MaxObjectSize 5M
#The directory which clamav library will use as temporary.
-#srv_clamav.ClamAvTmpDir /var/tmp
+#srv_clamav.ClamAvTmpDir /var/cache/c-icap
#Sets the maximum number of files in archive.)i Set it to 0 to disable it
srv_clamav.ClamAvMaxFilesInArchive 0
#Sets the maximal archived file size. Set it to 0 to disable it.
@@ -122,10 +122,46 @@ srv_clamav.ClamAvMaxRecLevel 5
# And here the viralator-like mode.
# where to save documents
-srv_clamav.VirSaveDir /srv/www/htdocs/downloads/
+srv_clamav.VirSaveDir /var/www/html/downloads/
# from where the documents can be retrieved (you can find the get_file.pl script in contrib dir)
srv_clamav.VirHTTPServer "http://fortune/cgi-bin/get_file.pl?usename=%f&remove=1&file="
# The refresh rate....
srv_clamav.VirUpdateTime 15
# For which filetypes the "virelator like mode" will be used.
srv_clamav.VirScanFileTypes ARCHIVE EXECUTABLE
+
+Service url_filter_module srv_url_filter.so
+
+# Memcached server list for url_filter
+url_filter.MemcachedServers "127.0.0.1:11211"
+
+# host2cat server for url_filter
+url_filter.Host2CatServer "127.0.0.1:6666"
+
+# Database settings
+url_filter.DBEngine "sqlite3"
+#url_filter.DBHost "localhost"
+#url_filter.DBPort "5432"
+url_filter.DBName "/var/cache/host2cat/filter.db"
+#url_filter.DBUser "username"
+#url_filter.DBPass "password"
+
+url_filter.RedirectUrl "http://www.google.com"
+
+#url_filter.ClientIPHeader "X-Client-IP"
+#url_filter.AuthUserHeader "X-Authenticated-User"
+#url_filter.AuthUserPrefix "Local://"
+#url_filter.AuthUserEncoded 0
+
+# Default policy settings
+# Values are: 0 - accept, 1 - reject, 2 - redirect
+#url_filter.DBOpenErrorPolicy 1
+#url_filter.DBQueryErrorPolicy 0
+#url_filter.UnknownRolePolicy 1
+#url_filter.MemcachedConnectErrorPolicy 1
+#url_filter.MemcachedMissPolicy 0
+#url_filter.EmptyCategoryPolicy 0
+#url_filter.CategoryNotFoundPolicy 1
+
+# Default value - LOG_INFO
+#url_filter.SyslogPriority 6
diff --git a/configure b/configure
index 00dc733..4791a03 100755
--- a/configure
+++ b/configure
@@ -719,7 +719,7 @@ MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
-PACKAGE_NAME='c_icap'
+PACKAGE_NAME='c-icap'
PACKAGE_TARNAME='c_icap'
PACKAGE_VERSION='060708rc3'
PACKAGE_STRING='c_icap 060708rc3'
@@ -2306,7 +2306,7 @@ fi
# Define the identity of the package.
- PACKAGE='c_icap'
+ PACKAGE='c-icap'
VERSION='060708rc3'
@@ -13714,7 +13714,7 @@ else
fi
-ac_config_files="$ac_config_files Makefile c-icap.conf services/Makefile services/echo/Makefile services/url_check/Makefile services/clamav/Makefile modules/Makefile"
+ac_config_files="$ac_config_files Makefile c-icap.conf services/Makefile services/echo/Makefile services/url_check/Makefile services/clamav/Makefile modules/Makefile services/url_filter/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
diff --git a/configure.in b/configure.in
index afcaab0..a42c217 100644
--- a/configure.in
+++ b/configure.in
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
#AC_INIT(c_icap,m4_normalize(m4_include([VERSION.m4])))
-AC_INIT(c_icap,060708rc3)
+AC_INIT(c-icap,060708rc3)
AC_CONFIG_SRCDIR(aserver.c)
AM_MAINTAINER_MODE
@@ -417,4 +417,4 @@ AM_CONDITIONAL(ISCYGWIN,[test a"$iscygwin" != a])
AM_CONDITIONAL(USEPERL,[test a"$perlcore" != a])
AM_CONDITIONAL(USECLAMAV,[test a"$clamav" != ano])
-AC_OUTPUT([Makefile c-icap.conf services/Makefile services/echo/Makefile services/url_check/Makefile services/clamav/Makefile modules/Makefile])
+AC_OUTPUT([Makefile c-icap.conf services/Makefile services/echo/Makefile services/url_check/Makefile services/clamav/Makefile modules/Makefile services/url_filter/Makefile])
diff --git a/contrib/get_file.pl b/contrib/get_file.pl
index f14d315..9860749 100644
--- a/contrib/get_file.pl
+++ b/contrib/get_file.pl
@@ -24,7 +24,7 @@ else{
}
-$filename="/srv/www/htdocs/downloads/".$args{"file"};
+$filename="/var/www/html/downloads/".$args{"file"};
my(@stat)=stat $filename;
binmode(STDOUT);
if(open (F,"<$filename")){
diff --git a/filetype.c b/filetype.c
index e019b12..a1bb997 100644
--- a/filetype.c
+++ b/filetype.c
@@ -299,7 +299,7 @@ int ci_magics_db_file_add(struct ci_magics_db *db, char *filename)
struct ci_magic_record record;
FILE *f;
- if ((f = fopen(filename, "r+")) == NULL) {
+ if ((f = fopen(filename, "r")) == NULL) {
ci_debug_printf(1, "Error opening magic file: %s\n", filename);
return 0;
}
diff --git a/include/debug.h b/include/debug.h
index 684ace6..ea44f12 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -36,7 +36,7 @@ CI_DECLARE_FUNC(void) __ldebug_printf(int i,const char *format, ...);
#else
extern void (*__log_error)(void *req, const char *format,... );
-#define ci_debug_printf(i, args...) if(i<=CI_DEBUG_LEVEL){ if(__log_error) (*__log_error)(NULL,args); if(CI_DEBUG_STDOUT) printf(args);}
+#define ci_debug_printf(i, args...) if(i<=CI_DEBUG_LEVEL){ if(CI_DEBUG_STDOUT) printf(args); if(__log_error) (*__log_error)(NULL,args);}
#endif
diff --git a/services/Makefile.am b/services/Makefile.am
index 8396ed3..2e5dabd 100644
--- a/services/Makefile.am
+++ b/services/Makefile.am
@@ -3,7 +3,7 @@
#SUBDIRS = @BUILD_SERVICES@
-SUBDIRS=echo url_check
+SUBDIRS=echo url_check url_filter
if USECLAMAV
SUBDIRS += clamav
diff --git a/services/Makefile.in b/services/Makefile.in
index c7373ea..240a387 100644
--- a/services/Makefile.in
+++ b/services/Makefile.in
@@ -58,7 +58,7 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = echo url_check clamav
+DIST_SUBDIRS = echo url_check clamav url_filter
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -185,7 +185,7 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-SUBDIRS = echo url_check $(am__append_1)
+SUBDIRS = echo url_check url_filter $(am__append_1)
all: all-recursive
.SUFFIXES:
diff --git a/services/clamav/srv_clamav.c b/services/clamav/srv_clamav.c
index 0ad512f..4f4fe23 100644
--- a/services/clamav/srv_clamav.c
+++ b/services/clamav/srv_clamav.c
@@ -144,7 +144,7 @@ static struct ci_conf_entry conf_variables[] = {
CI_DECLARE_MOD_DATA ci_service_module_t service = {
- "srv_clamav", /*Module name */
+ "clamav", /*Module name */
"Clamav/Antivirus service", /*Module short description */
ICAP_RESPMOD | ICAP_REQMOD, /*Service type responce or request modification */
srvclamav_init_service, /*init_service. */
diff --git a/services/url_filter/Makefile.am b/services/url_filter/Makefile.am
new file mode 100644
index 0000000..5a7f19a
--- /dev/null
+++ b/services/url_filter/Makefile.am
@@ -0,0 +1,12 @@
+
+pkglib_LTLIBRARIES=srv_url_filter.la
+INCLUDES = -I$(top_srcdir)
+
+srv_url_filter_la_LIBADD = @MODULES_LIBADD@ -lmemcache -lopendbx
+srv_url_filter_la_CFLAGS= -I../../include/
+srv_url_filter_la_LDFLAGS= -no-undefined -module -avoid-version
+srv_url_filter_la_SOURCES = srv_url_filter.c
+
+
+
+EXTRA_DIST= makefile.w32 srv_url_filter.def
diff --git a/services/url_filter/Makefile.in b/services/url_filter/Makefile.in
new file mode 100644
index 0000000..b89fc7d
--- /dev/null
+++ b/services/url_filter/Makefile.in
@@ -0,0 +1,501 @@
+# Makefile.in generated by automake 1.8.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SOURCES = $(srv_url_filter_la_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+subdir = services/url_filter
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(mkdir_p)
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+pkglibLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(pkglib_LTLIBRARIES)
+srv_url_filter_la_DEPENDENCIES =
+am_srv_url_filter_la_OBJECTS = srv_url_filter_la-srv_url_filter.lo
+srv_url_filter_la_OBJECTS = $(am_srv_url_filter_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = \
+@AMDEP_TRUE@ ./$(DEPDIR)/srv_url_filter_la-srv_url_filter.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(srv_url_filter_la_SOURCES)
+DIST_SOURCES = $(srv_url_filter_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_ADD_FLAG = @DL_ADD_FLAG@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCYGWIN_FALSE = @ISCYGWIN_FALSE@
+ISCYGWIN_TRUE = @ISCYGWIN_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MODULES_LIBADD = @MODULES_LIBADD@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+THREADS_LDADD = @THREADS_LDADD@
+THREADS_LDFLAGS = @THREADS_LDFLAGS@
+USECLAMAV_FALSE = @USECLAMAV_FALSE@
+USECLAMAV_TRUE = @USECLAMAV_TRUE@
+USEPERL_FALSE = @USEPERL_FALSE@
+USEPERL_TRUE = @USEPERL_TRUE@
+VERSION = @VERSION@
+ZLIB_ADD_FLAG = @ZLIB_ADD_FLAG@
+ZLIB_ADD_LDFLAG = @ZLIB_ADD_LDFLAG@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_AS = @ac_ct_AS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DLLTOOL = @ac_ct_DLLTOOL@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+clamavinc = @clamavinc@
+clamavlib = @clamavlib@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+perlccflags = @perlccflags@
+perlcore = @perlcore@
+perlldflags = @perlldflags@
+perllib = @perllib@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+pkglib_LTLIBRARIES = srv_url_filter.la
+INCLUDES = -I$(top_srcdir)
+srv_url_filter_la_LIBADD = @MODULES_LIBADD@ -lmemcache -lopendbx
+srv_url_filter_la_CFLAGS = -I../../include/ -I@prefix@/include
+srv_url_filter_la_LDFLAGS = -no-undefined -module -avoid-version -L@prefix@/lib
+srv_url_filter_la_SOURCES = srv_url_filter.c
+EXTRA_DIST = makefile.w32 srv_url_filter.def
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/url_filter/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu services/url_filter/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)"
+ @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(LIBTOOL) --mode=install $(pkglibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(pkglibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pkglibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ p="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \
+ done
+
+clean-pkglibLTLIBRARIES:
+ -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+ @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" = "$$p" && dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+srv_url_filter.la: $(srv_url_filter_la_OBJECTS) $(srv_url_filter_la_DEPENDENCIES)
+ $(LINK) -rpath $(pkglibdir) $(srv_url_filter_la_LDFLAGS) $(srv_url_filter_la_OBJECTS) $(srv_url_filter_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srv_url_filter_la-srv_url_filter.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+srv_url_filter_la-srv_url_filter.o: srv_url_filter.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(srv_url_filter_la_CFLAGS) $(CFLAGS) -MT srv_url_filter_la-srv_url_filter.o -MD -MP -MF "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo" -c -o srv_url_filter_la-srv_url_filter.o `test -f 'srv_url_filter.c' || echo '$(srcdir)/'`srv_url_filter.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo" "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Po"; else rm -f "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='srv_url_filter.c' object='srv_url_filter_la-srv_url_filter.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/srv_url_filter_la-srv_url_filter.Po' tmpdepfile='$(DEPDIR)/srv_url_filter_la-srv_url_filter.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(srv_url_filter_la_CFLAGS) $(CFLAGS) -c -o srv_url_filter_la-srv_url_filter.o `test -f 'srv_url_filter.c' || echo '$(srcdir)/'`srv_url_filter.c
+
+srv_url_filter_la-srv_url_filter.obj: srv_url_filter.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(srv_url_filter_la_CFLAGS) $(CFLAGS) -MT srv_url_filter_la-srv_url_filter.obj -MD -MP -MF "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo" -c -o srv_url_filter_la-srv_url_filter.obj `if test -f 'srv_url_filter.c'; then $(CYGPATH_W) 'srv_url_filter.c'; else $(CYGPATH_W) '$(srcdir)/srv_url_filter.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo" "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Po"; else rm -f "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='srv_url_filter.c' object='srv_url_filter_la-srv_url_filter.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/srv_url_filter_la-srv_url_filter.Po' tmpdepfile='$(DEPDIR)/srv_url_filter_la-srv_url_filter.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(srv_url_filter_la_CFLAGS) $(CFLAGS) -c -o srv_url_filter_la-srv_url_filter.obj `if test -f 'srv_url_filter.c'; then $(CYGPATH_W) 'srv_url_filter.c'; else $(CYGPATH_W) '$(srcdir)/srv_url_filter.c'; fi`
+
+srv_url_filter_la-srv_url_filter.lo: srv_url_filter.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(srv_url_filter_la_CFLAGS) $(CFLAGS) -MT srv_url_filter_la-srv_url_filter.lo -MD -MP -MF "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo" -c -o srv_url_filter_la-srv_url_filter.lo `test -f 'srv_url_filter.c' || echo '$(srcdir)/'`srv_url_filter.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo" "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Plo"; else rm -f "$(DEPDIR)/srv_url_filter_la-srv_url_filter.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='srv_url_filter.c' object='srv_url_filter_la-srv_url_filter.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/srv_url_filter_la-srv_url_filter.Plo' tmpdepfile='$(DEPDIR)/srv_url_filter_la-srv_url_filter.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(srv_url_filter_la_CFLAGS) $(CFLAGS) -c -o srv_url_filter_la-srv_url_filter.lo `test -f 'srv_url_filter.c' || echo '$(srcdir)/'`srv_url_filter.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(pkglibdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-pkglibLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-pkglibLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pkglibLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-pkglibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am \
+ uninstall-pkglibLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/services/url_filter/makefile.w32 b/services/url_filter/makefile.w32
new file mode 100644
index 0000000..67b87d6
--- /dev/null
+++ b/services/url_filter/makefile.w32
@@ -0,0 +1,15 @@
+!include <win32.mak>
+
+all: srv_url_filter.Dll
+
+.c.obj:
+ $(cc) /I..\..\include /I..\..\ $(cdebug) $(cflags) $(cvarsdll) -I. -DCI_BUILD_MODULE -DUNICODE $*.c
+
+srv_url_filter.Dll: srv_url_filter.obj
+ $(link) $(linkdebug) $(dlllflags) /LIBPATH:..\..\ c_icap.lib -def:srv_url_filter.def -out:$*.Dll $** $(DLL_ENTRY) $(EXTRA_LIBS)
+
+clean:
+ del *.obj *.dll *.lib
+
+
+
diff --git a/services/url_filter/srv_url_filter.c b/services/url_filter/srv_url_filter.c
new file mode 100644
index 0000000..eaca9e9
--- /dev/null
+++ b/services/url_filter/srv_url_filter.c
@@ -0,0 +1,892 @@
+/*
+ * Copyright (C) 2004 Christos Tsantilas
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "c-icap.h"
+#include "service.h"
+#include "header.h"
+#include "body.h"
+#include "simple_api.h"
+#include "debug.h"
+#include "ci_threads.h"
+#include <memcache.h>
+#include <errno.h>
+#undef HAVE_CONFIG_H
+#include <odbx.h>
+#include <regex.h>
+#include <syslog.h>
+#ifndef REG_BASIC
+#define REG_BASIC 0
+#endif
+
+#define CACHETTL 3600
+
+struct memcache *mc;
+
+int url_filter_init_service(ci_service_xdata_t *srv_xdata,struct ci_server_conf *server_conf);
+int url_filter_post_init_service(ci_service_xdata_t *srv_xdata,struct ci_server_conf *server_conf);
+void url_filter_close_service (ci_service_xdata_t *srv_xdata);
+void * url_filter_init_request_data(ci_request_t *req);
+void url_filter_release_data(void *data);
+int url_filter_process(ci_request_t *);
+int url_filter_check_preview(char *preview_data,int preview_data_len,ci_request_t *);
+int url_filter_io(char *wbuf,int *wlen,char *rbuf,int *rlen,int iseof,ci_request_t *req);
+//int url_filter_write(char *buf,int len ,int iseof,request_t *req);
+//int url_filter_read(char *buf,int len,request_t *req);
+static unsigned dotip2int (char *str);
+static unsigned str2int (const char *str);
+
+static char *MemcachedServers;
+static char *Host2CatServer;
+static char *DBEngine;
+static char *DBHost;
+static char *DBPort;
+static char *DBName;
+static char *DBUser;
+static char *DBPass;
+static char *RedirectUrl;
+static char *ClientIPHeader = "X-Client-IP";
+static char *AuthUserHeader = "X-Authenticated-User";
+static char *AuthUserPrefix;
+static int AuthUserEncoded = 1;
+// Values 0 - ACCEPT, 1 - REJECT, 2 - REDIRECT
+static int DBOpenErrorPolicy = 1; // SQLite database doesn't opened
+static int DBQueryErrorPolicy = 0; // Error executing SQLite query
+static int UnknownRolePolicy = 1; // Can't find role for user@ip
+static int MemcachedConnectErrorPolicy = 1;// No connection to memcached server(s)
+static int MemcachedMissPolicy = 0; // Host category missed at memcached server(s)
+static int EmptyCategoryPolicy = 0; // No categories for host
+static int CategoryNotFoundPolicy = 1; // Host categories doesn't exists in roles definition
+static int SyslogPriority = LOG_INFO; // Priority for syslog()
+
+static int fd = -1;
+static struct sockaddr_in addr;
+static odbx_t *dbh;
+
+static ci_thread_mutex_t mtx;
+
+static struct ci_conf_entry conf_variables[]={
+ {"MemcachedServers",&MemcachedServers,ci_cfg_set_str,NULL},
+ {"Host2CatServer",&Host2CatServer,ci_cfg_set_str,NULL},
+ {"DBEngine",&DBEngine,ci_cfg_set_str,NULL},
+ {"DBHost",&DBHost,ci_cfg_set_str,NULL},
+ {"DBPort",&DBPort,ci_cfg_set_str,NULL},
+ {"DBName",&DBName,ci_cfg_set_str,NULL},
+ {"DBUser",&DBUser,ci_cfg_set_str,NULL},
+ {"DBPass",&DBPass,ci_cfg_set_str,NULL},
+ {"RedirectUrl",&RedirectUrl,ci_cfg_set_str,NULL},
+ {"ClientIPHeader",&ClientIPHeader,ci_cfg_set_str,NULL},
+ {"AuthUserHeader",&AuthUserHeader,ci_cfg_set_str,NULL},
+ {"AuthUserPrefix",&AuthUserPrefix,ci_cfg_set_str,NULL},
+ {"AuthUserEncoded",&AuthUserEncoded,ci_cfg_set_int,NULL},
+ {"DBOpenErrorPolicy",&DBOpenErrorPolicy,ci_cfg_set_int,NULL},
+ {"DBQueryErrorPolicy",&DBQueryErrorPolicy,ci_cfg_set_int,NULL},
+ {"UnknownRolePolicy",&UnknownRolePolicy,ci_cfg_set_int,NULL},
+ {"MemcachedConnectErrorPolicy",&MemcachedConnectErrorPolicy,ci_cfg_set_int,NULL},
+ {"MemcachedMissPolicy",&MemcachedMissPolicy,ci_cfg_set_int,NULL},
+ {"EmptyCategoryPolicy",&EmptyCategoryPolicy,ci_cfg_set_int,NULL},
+ {"CategoryNotFoundPolicy",&CategoryNotFoundPolicy,ci_cfg_set_int,NULL},
+ {"SyslogPriority",&SyslogPriority,ci_cfg_set_int,NULL},
+ {NULL,NULL,NULL,NULL}
+};
+
+
+//service_module echo={
+CI_DECLARE_MOD_DATA ci_service_module_t service={
+ "url_filter",
+ "Url Filter service",
+ ICAP_REQMOD,
+ url_filter_init_service, /* init_service*/
+ url_filter_post_init_service, /*post_init_service*/
+ url_filter_close_service, /*close_Service*/
+ url_filter_init_request_data,/* init_request_data*/
+ url_filter_release_data, /*Release request data*/
+ url_filter_check_preview,
+ url_filter_process,
+ url_filter_io,
+ conf_variables,
+ NULL
+};
+
+struct url_filter_data{
+ ci_cached_file_t *body;
+ int denied;
+};
+
+enum http_methods {HTTP_UNKNOWN=0,HTTP_GET, HTTP_POST};
+
+struct http_info{
+ int http_major;
+ int http_minor;
+ int method;
+ char site[CI_MAXHOSTNAMELEN+1];
+ char page[1024]; /*I think it is enough*/
+// char server_ip [CI_IPLEN + 1];
+ char *client_ip;
+ char auth_user [MAX_USERNAME_LEN + 1];
+};
+
+
+int url_filter_init_service(ci_service_xdata_t *srv_xdata,struct ci_server_conf *server_conf){
+ unsigned int xops;
+ printf("Initialization of url_filter module......\n");
+ ci_service_set_preview(srv_xdata, 0);
+ xops = CI_XCLIENTIP | CI_XSERVERIP;
+ xops |= CI_XAUTHENTICATEDUSER | CI_XAUTHENTICATEDGROUPS;
+ ci_service_set_xopts(srv_xdata, xops);
+ return CI_OK;
+}
+
+int url_filter_post_init_service (ci_service_xdata_t *srv_xdata,struct ci_server_conf *server_conf)
+{
+ int nservers, retval;
+ char *p, *p1, *ep;
+
+ if (!MemcachedServers || !*MemcachedServers) {
+ ci_debug_printf (1, "Empty MemcachedServers list\n");
+ return CI_ERROR;
+ }
+
+ if (!(mc = mc_new ())) {
+ ci_debug_printf (1, "No memory for mc structure\n");
+ return CI_ERROR;
+ }
+
+ ep = MemcachedServers + strlen(MemcachedServers);
+ for (nservers = 0, p = MemcachedServers; p < ep; p = p1 + 1) {
+ // p points to beginning of server, p1 points to end of server
+ p1 = strchr (p, ',');
+ if (!p1) p1 = p + strlen (p);
+
+ if (p1 == p) {
+ ci_debug_printf (5, "Empty server in '%s' - ignored\n", MemcachedServers);
+ } else if ((retval = mc_server_add5 (mc, p, p1 - p))) {
+ ci_debug_printf (5, "server add for server %.*s returns %d\n", (int)(p1 - p), p, retval);
+ } else {
+ nservers++;
+ ci_debug_printf (5, "server %.*s successfully added\n", (int)(p1 - p), p);
+ }
+ }
+
+ if (!nservers) {
+ ci_debug_printf (1, "No servers added\n");
+ mc_free (mc);
+ mc = NULL;
+ return CI_ERROR;
+ }
+
+ if (!Host2CatServer || !*Host2CatServer) {
+ ci_debug_printf (1, "Empty Host2CatServer\n");
+ return CI_ERROR;
+ }
+
+ if (!(p = strchr (Host2CatServer, ':'))) {
+ ci_debug_printf (1, "No port number in Host2CatServer %s\n", Host2CatServer);
+ return CI_ERROR;
+ }
+
+ *p = 0;
+ bzero (&addr, sizeof addr);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons (atoi (p + 1));
+ inet_pton (AF_INET, Host2CatServer, &addr.sin_addr);
+ *p = ':';
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ ci_debug_printf (1, "Can't open UDP socket to Host2CatServer: %s\n", strerror (errno));
+ return CI_ERROR;
+ }
+
+ if (!DBEngine || !*DBEngine) {
+ ci_debug_printf (1, "Empty DBEngine\n");
+ return CI_ERROR;
+ }
+
+ retval = odbx_init (&dbh, DBEngine, DBHost, DBPort);
+ if (retval != ODBX_ERR_SUCCESS) {
+ ci_debug_printf (1, "Error initializing DB handle: %s\n", odbx_error (dbh, retval));
+ return CI_ERROR;
+ }
+
+ if (!DBName || !*DBName) {
+ ci_debug_printf (1, "Empty DBName\n");
+ return CI_ERROR;
+ }
+
+ retval = odbx_bind_simple (dbh, DBName, DBUser, DBPass);
+ if (retval != ODBX_ERR_SUCCESS) {
+ ci_debug_printf (1, "Error binding to database: %s\n", odbx_error (dbh, retval));
+ odbx_finish (dbh);
+ dbh = NULL;
+ return CI_ERROR;
+ }
+
+ if (!RedirectUrl || !*RedirectUrl) ci_debug_printf (1, "Empty redirect URL\n");
+
+ if (ci_thread_mutex_init(&mtx))
+ return CI_ERROR;
+
+ return CI_OK;
+}
+
+
+void url_filter_close_service (ci_service_xdata_t *srv_xdata)
+{
+ if (mc) {
+ mc_free (mc);
+ mc = NULL;
+ }
+ if (fd != -1) close (fd);
+ if (dbh) {
+ odbx_unbind (dbh);
+ odbx_finish (dbh);
+ }
+
+ ci_thread_mutex_destroy(&mtx);
+}
+
+void *url_filter_init_request_data(ci_request_t *req){
+ struct url_filter_data *uc=malloc(sizeof(struct url_filter_data));
+ uc->body=NULL;
+ uc->denied = 0;
+ return uc; /*Get from a pool of pre-allocated structs better......*/
+}
+
+
+void url_filter_release_data(void *data){
+ struct url_filter_data *uc=data;
+ if(uc->body)
+ ci_cached_file_destroy(uc->body);
+ free(uc); /*Return object to pool.....*/
+}
+
+
+static int get_http_info(ci_request_t *req,ci_headers_list_t *req_header , struct http_info *httpinf){
+ char *str;
+ int i;
+
+ /*Now get the site name*/
+ str=ci_headers_value(req_header,"Host");
+ strncpy(httpinf->site,str,CI_MAXHOSTNAMELEN);
+ httpinf->site[CI_MAXHOSTNAMELEN]='\0';
+
+ str=req_header->headers[0];
+ if(str[0]=='g' || str[0]=='G') /*Get request....*/
+ httpinf->method=HTTP_GET;
+ else if(str[0]=='p' || str[0]=='P') /*post request....*/
+ httpinf->method=HTTP_POST;
+ else{
+ httpinf->method=HTTP_UNKNOWN;
+ return 0;
+ }
+ if((str=strchr(str,' '))==NULL){ /*The request must have the form:GETPOST page HTTP/X.X */
+ return 0;
+ }
+ while(*str==' ') str++;
+ i=0;
+ while(*str!=' ' && *str!='\0' && i<1022) /*copy page to the struct.*/
+ httpinf->page[i++]=*str++;
+ httpinf->page[i]='\0';
+
+ if(*str!=' '){ /*Where is the protocol info?????*/
+ return 0;
+ }
+ while(*str==' ') str++;
+ if(*str!='H' || *(str+4)!='/'){ /*Not in HTTP/X.X form*/
+ return 0;
+ }
+ str+=5;
+ httpinf->http_major=strtol(str,&str,10);
+ if(*str!='.'){
+ return 0;
+ }
+ str++;
+ httpinf->http_minor=strtol(str,&str,10);
+
+
+ return 1;
+}
+
+static int check_destination (struct http_info *httpinf, int policy)
+{
+ odbx_result_t *sth;
+ unsigned ip, role = 0, *ncats;
+ int i, rc = CategoryNotFoundPolicy, retval;
+ char *cats = NULL, *p, *p1, buf [1024], rname[64], *uname;
+ char key[64], *val = NULL;
+ int valsz, found;
+
+ uname = AuthUserPrefix && *AuthUserPrefix && !strncmp (httpinf->auth_user, AuthUserPrefix, strlen (AuthUserPrefix)) ? httpinf->auth_user + strlen (AuthUserPrefix) : httpinf->auth_user;
+ ip = dotip2int (httpinf->client_ip);
+ snprintf (key, sizeof key, "%s@%s", uname, httpinf->client_ip);
+ ci_debug_printf (5, "Uname: %s\n", uname);
+ ci_debug_printf (5, "IP: %s\n", httpinf->client_ip);
+ ci_debug_printf (5, "URL: %s\n", httpinf->page);
+ ci_debug_printf (5, "Host: %s\n", httpinf->site);
+
+ if (!dbh) {
+ ci_debug_printf (1, "DB handle doesn't opened\n");
+ rc = DBOpenErrorPolicy;
+ goto print_log;
+ }
+
+ // Find user role
+ ci_thread_mutex_lock(&mtx);
+ val = mc_aget(mc, key, strlen(key));
+ ci_thread_mutex_unlock(&mtx);
+ if (val) {
+ char *ptr;
+
+ ci_debug_printf(5, "Found role in cache\n");
+ role = strtol(val, NULL, 10);
+ ptr = strchr(val, ':') + 1;
+ strlcpy(rname, ptr, sizeof rname);
+ free(val);
+ goto cached_role;
+ }
+
+ snprintf (buf, sizeof buf, "SELECT u.addr, u.mask, u.rolid, r.rname FROM users u, roles r WHERE u.uname = '%s' AND u.rolid = r.rolid ORDER BY mask DESC", uname);
+
+ ci_thread_mutex_lock(&mtx);
+ retval = odbx_query (dbh, buf, strlen (buf));
+ if (retval != ODBX_ERR_SUCCESS) {
+ ci_debug_printf (1, "Error executing SQL query '%s': %s\n", buf, odbx_error (dbh, retval));
+ rc = DBQueryErrorPolicy;
+ ci_thread_mutex_unlock(&mtx);
+ goto print_log;
+ }
+
+ retval = odbx_result (dbh, &sth, NULL, 0);
+ ci_thread_mutex_unlock(&mtx);
+ if (retval < 0) {
+ ci_debug_printf (1, "Error getting SQL query result '%s': %s\n", buf, odbx_error (dbh, retval));
+ rc = DBQueryErrorPolicy;
+ goto print_log;
+ }
+
+ while ((retval = odbx_row_fetch (sth)) != 0) {
+ unsigned net, mask;
+ if (retval < 0) {
+ ci_debug_printf (1, "Error fetching result row '%s', :%s\n", buf, odbx_error (dbh, retval));
+ break;
+ }
+ net = str2int (odbx_field_value (sth, 0));
+ mask = str2int (odbx_field_value (sth, 1));
+ if ((ip & mask) == net) {
+ role = str2int (odbx_field_value (sth, 2));
+ strlcpy (rname, odbx_field_value (sth, 3), sizeof rname);
+ break;
+ }
+ }
+
+ // Find default role
+ if (!role) {
+ odbx_result_free (sth);
+ snprintf (buf, sizeof buf, "SELECT u.addr, u.mask, u.rolid, r.rname FROM users u, roles r WHERE u.uname = '%s' AND u.rolid = r.rolid ORDER BY mask DESC", "");
+
+ ci_thread_mutex_lock(&mtx);
+ retval = odbx_query (dbh, buf, strlen (buf));
+ if (retval != ODBX_ERR_SUCCESS) {
+ ci_debug_printf (1, "Error executing SQL query '%s': %s\n", buf, odbx_error (dbh, retval));
+ rc = DBQueryErrorPolicy;
+ ci_thread_mutex_unlock(&mtx);
+ goto print_log;
+ }
+
+ retval = odbx_result (dbh, &sth, NULL, 0);
+ ci_thread_mutex_unlock(&mtx);
+ if (retval < 0) {
+ ci_debug_printf (1, "Error getting SQL query result '%s': %s\n", buf, odbx_error (dbh, retval));
+ rc = DBQueryErrorPolicy;
+ goto print_log;
+ }
+
+ while ((retval = odbx_row_fetch (sth)) != 0) {
+ unsigned net, mask;
+ if (retval < 0) {
+ ci_debug_printf (1, "Error fetching result row '%s', :%s\n", buf, odbx_error (dbh, retval));
+ break;
+ }
+ net = str2int (odbx_field_value (sth, 0));
+ mask = str2int (odbx_field_value (sth, 1));
+ if ((ip & mask) == net) {
+ role = str2int (odbx_field_value (sth, 2));
+ strlcpy (rname, odbx_field_value (sth, 3), sizeof rname);
+ break;
+ }
+ }
+ }
+ odbx_result_free (sth);
+
+ if (role) {
+ snprintf(buf, sizeof buf, "%d:%s", role, rname);
+ ci_thread_mutex_lock(&mtx);
+ mc_add(mc, key, strlen(key), buf, strlen(buf) + 1, CACHETTL, 0);
+ ci_thread_mutex_unlock(&mtx);
+ }
+
+cached_role:
+ ci_debug_printf (5, "Role: %s\n", role ? rname : "UNKNOWN");
+ if (!role) {
+ rc = UnknownRolePolicy;
+ goto print_log;
+ }
+
+ // Read URL list
+ snprintf (key, sizeof key, "url:%s", rname);
+ ci_thread_mutex_lock(&mtx);
+ val = mc_aget(mc, key, strlen(key));
+ ci_thread_mutex_unlock(&mtx);
+ if (val) {
+ char *s;
+
+ ci_debug_printf(5, "Found URL list in cache\n");
+
+ for (s = val; *s;) {
+ regex_t preg;
+ const char *url;
+ int action;
+
+ action = strtol(s, NULL, 10);
+ url = strchr(s, ':') + 1;
+ s = strchr(url, ' ');
+ *s++ = '\0';
+
+ ci_debug_printf(9, "checking url %s against list: "
+ "action %d, regex %s", httpinf->page, action, url);
+ rc = regcomp(&preg, url, REG_BASIC | REG_ICASE |
+ REG_NOSUB);
+ if (rc) {
+ ci_debug_printf(1, "Error compiling regular "
+ "expression '%s': %d\n", url, rc);
+ continue;
+ }
+ rc = regexec(&preg, httpinf->page, 0, NULL, 0);
+ regfree(&preg);
+ if (!rc) {
+ free(val);
+ rc = action;
+ goto print_log;
+ }
+ }
+ free(val);
+ goto cached_urls;
+ }
+
+ snprintf (buf, sizeof buf, "SELECT l.url, l.action FROM lists l, hierarchy h WHERE h.child = %d AND h.parent = l.rolid ORDER BY action DESC, rolid, stars, length (l.url)", role);
+
+ ci_thread_mutex_lock(&mtx);
+ retval = odbx_query (dbh, buf, strlen (buf));
+ if (retval != ODBX_ERR_SUCCESS) {
+ ci_debug_printf (1, "Error executing SQL query '%s': %s\n", buf, odbx_error (dbh, retval));
+ rc = DBQueryErrorPolicy;
+ ci_thread_mutex_unlock(&mtx);
+ goto print_log;
+ }
+
+ retval = odbx_result (dbh, &sth, NULL, 0);
+ ci_thread_mutex_unlock(&mtx);
+ if (retval < 0) {
+ ci_debug_printf (1, "Error getting SQL query result '%s': %s\n", buf, odbx_error (dbh, retval));
+ rc = DBQueryErrorPolicy;
+ goto print_log;
+ }
+
+
+ // Check URL list
+ val = NULL;
+ valsz = 1;
+ found = 0;
+ while ((retval = odbx_row_fetch (sth)) != 0) {
+ regex_t preg;
+ const char *url;
+ int action;
+
+ if (retval < 0) {
+ ci_debug_printf (1, "Error fetching result row '%s': %s\n", buf, odbx_error (dbh, retval));
+ break;
+ }
+
+ if (val != (void *)-1) {
+ char *ptr;
+ int len;
+
+ len = strlen(odbx_field_value(sth, 0)) +
+ strlen(odbx_field_value(sth, 1)) + 2;
+ if ((ptr = realloc(val, valsz + len)) == NULL) {
+ free(val);
+ val = (void *)-1;
+ } else {
+ val = ptr;
+ asprintf(&ptr, "%s:%s ",
+ odbx_field_value(sth, 1),
+ odbx_field_value(sth, 0));
+ if (ptr == NULL) {
+ free(val);
+ val = (void *)-1;
+ } else {
+ strcat(val, ptr);
+ valsz += len;
+ }
+ }
+ }
+
+ url = odbx_field_value (sth, 0);
+ action = str2int (odbx_field_value (sth, 1));
+ ci_debug_printf (9, "checking url %s against list: action %d, regex %s", httpinf->page, action, url);
+ rc = regcomp (&preg, url, REG_BASIC | REG_ICASE | REG_NOSUB);
+ if (rc) {
+ ci_debug_printf (1, "Error compiling regular expression '%s': %d\n", url, rc);
+ continue;
+ }
+ rc = regexec (&preg, httpinf->page, 0, NULL, 0);
+ regfree (&preg);
+ if (!rc && !found) {
+ found = 1;
+ rc = action;
+ }
+ }
+ odbx_result_free (sth);
+
+ if (val && val != (void *)-1) {
+ ci_thread_mutex_lock(&mtx);
+ mc_add(mc, key, strlen(key), val, strlen(val) + 1,
+ CACHETTL, 0);
+ ci_thread_mutex_unlock(&mtx);
+ free(val);
+ }
+
+ if (found)
+ goto print_log;
+
+cached_urls:
+ // Get host category
+ if (!mc) {
+ rc = MemcachedConnectErrorPolicy;
+ goto print_log;
+ }
+ ci_thread_mutex_lock(&mtx);
+ cats = mc_aget (mc, (char *) httpinf->site, strlen (httpinf->site));
+ ci_thread_mutex_unlock(&mtx);
+ ci_debug_printf (5, "Cats: %s\n", cats ? cats : "MISSED");
+ if (!cats) {
+ if (fd != -1) sendto (fd, httpinf->site, strlen (httpinf->site) + 1, 0, (struct sockaddr *)&addr, sizeof addr);
+ rc = MemcachedMissPolicy;
+ goto print_log;
+ }
+ if (!*cats) {
+ rc = EmptyCategoryPolicy;
+ goto print_log;
+ }
+
+ // Convert cats to array of unsigned
+ for (i = 1, p = strchr (cats, ':'); p; p = strchr (p + 1, ':'), i++)
+ ;
+ ncats = calloc (i + 1, sizeof (unsigned));
+ for (i = 0, p = cats, p1 = strchr (p, ':'); *p; p1 = strchr (p, ':'), i++) {
+ if (p1) *p1 = 0;
+ ncats [i] = str2int (p);
+ if (p1) {
+ *p1 = ':';
+ p = p1 + 1;
+ } else
+ p += strlen (p);
+ }
+ ncats [i] = 0;
+
+ // Read category list
+ snprintf(key, sizeof key, "cat:%d", role);
+ ci_thread_mutex_lock(&mtx);
+ val = mc_aget(mc, key, strlen(key));
+ ci_thread_mutex_unlock(&mtx);
+ if (val) {
+ char *s;
+
+ ci_debug_printf(5, "Found category list in cache\n");
+
+ for (s = val; *s;) {
+ char *catstr;
+ int cat, action;
+ unsigned *u;
+
+ action = strtol(s, NULL, 10);
+ catstr = strchr(s, ':') + 1;
+ s = strchr(catstr, ' ');
+ *s++ = '\0';
+
+ cat = str2int(catstr);
+ for (u = ncats; *u; u++) {
+ ci_debug_printf(9, "checking host category %d "
+ "against REJECT and REDIRECT category %d\n",
+ *u, cat);
+ if (cat == *u) {
+ free(val);
+ rc = action;
+ goto print_log;
+ }
+ }
+ }
+
+ free(val);
+ goto print_log;
+ }
+
+ snprintf (buf, sizeof buf, "SELECT p.cat, p.action FROM perms p, hierarchy h WHERE h.child = %d AND h.parent = p.rolid ORDER BY action DESC, rolid", role);
+
+ ci_thread_mutex_lock(&mtx);
+ retval = odbx_query (dbh, buf, strlen (buf));
+ if (retval != ODBX_ERR_SUCCESS) {
+ ci_debug_printf (1, "Error executing SQL query '%s': %s\n", buf, odbx_error (dbh, retval));
+ free (ncats);
+ rc = DBQueryErrorPolicy;
+ ci_thread_mutex_unlock(&mtx);
+ goto print_log;
+ }
+
+ retval = odbx_result (dbh, &sth, NULL, 0);
+ ci_thread_mutex_unlock(&mtx);
+ if (retval < 0) {
+ ci_debug_printf (1, "Error getting SQL query result '%s': %s\n", buf, odbx_error (dbh, retval));
+ free (ncats);
+ rc = DBQueryErrorPolicy;
+ goto print_log;
+ }
+
+ // Check category list
+ val = NULL;
+ valsz = 1;
+ found = 0;
+ while ((retval = odbx_row_fetch (sth)) != 0) {
+ int cat, action;
+ unsigned *u;
+
+ if (retval < 0) {
+ ci_debug_printf (1, "Error fetching result row '%s': %s\n", buf, odbx_error (dbh, retval));
+ break;
+ }
+
+ if (val != (void *)-1) {
+ char *ptr;
+ int len;
+
+ len = strlen(odbx_field_value(sth, 0)) +
+ strlen(odbx_field_value(sth, 1)) + 2;
+ if ((ptr = realloc(val, valsz + len)) == NULL) {
+ free(val);
+ val = (void *)-1;
+ } else {
+ val = ptr;
+ asprintf(&ptr, "%s:%s ",
+ odbx_field_value(sth, 1),
+ odbx_field_value(sth, 0));
+ if (ptr == NULL) {
+ free(val);
+ val = (void *)-1;
+ } else {
+ strcat(val, ptr);
+ valsz += len;
+ }
+ }
+ }
+
+ cat = str2int (odbx_field_value (sth, 0));
+ action = str2int (odbx_field_value (sth, 1));
+ for (u = ncats; *u; u++) {
+ ci_debug_printf (9, "checking host category %d against REJECT and REDIRECT category %d\n", *u, cat);
+ if (cat == *u && !found) {
+ found = 1;
+ rc = action;
+ }
+ }
+ }
+ free (ncats);
+ odbx_result_free (sth);
+
+ if (val && val != (void *)-1) {
+ ci_thread_mutex_lock(&mtx);
+ mc_add(mc, key, strlen(key), val, strlen(val) + 1,
+ CACHETTL, 0);
+ ci_thread_mutex_unlock(&mtx);
+ free(val);
+ }
+
+print_log:
+ // uname, ip, url, role, cats, action
+ syslog (SyslogPriority, "%s %s %s %s %s %s",
+ uname,
+ httpinf->client_ip,
+ httpinf->page,
+ role ? rname : "-",
+ cats ? cats : "-",
+ rc == 0 ? "ACCEPT" : rc == 1 ? "REJECT" : "REDIRECT"
+ );
+ if (cats) free (cats);
+ return rc;
+}
+
+static char *reject_message="<H1>Permition deny!<H1>";
+static char *redirect_message="<H1>You are redirected!<H1>";
+//static char *server_ip = "X-Server-IP";
+
+int url_filter_check_preview(char *preview_data,int preview_data_len, ci_request_t *req){
+ ci_headers_list_t* req_header;
+ struct url_filter_data *uc=ci_service_data(req);
+ struct http_info httpinf;
+ int rc;
+
+ if((req_header=ci_http_request_headers(req))==NULL) /*It is not possible but who knows .....*/
+ return CI_ERROR;
+
+// httpinf.server_ip = ci_headers_value (req->request_header, server_ip);
+// ci_conn_remote_ip (req->connection, httpinf.server_ip);
+ httpinf.client_ip = ci_headers_value (req->request_header, ClientIPHeader);
+ httpinf.auth_user [0] = 0;
+ if (AuthUserEncoded)
+ ci_base64_decode (ci_headers_value (req->request_header, AuthUserHeader), httpinf.auth_user, MAX_USERNAME_LEN);
+ else
+ strncpy(httpinf.auth_user,ci_headers_value (req->request_header, AuthUserHeader),MAX_USERNAME_LEN);
+
+ get_http_info(req,req_header, &httpinf);
+
+ ci_debug_printf(9,"URL to host %s\n",httpinf.site);
+ ci_debug_printf(9,"URL page %s\n",httpinf.page);
+
+ rc=check_destination(&httpinf, 1);
+ ci_debug_printf (5, "Action: %s\n", rc == 0 ? "ACCEPT" : rc == 1 ? "REJECT" : "REDIRECT");
+
+ if (!rc) {
+ /*if we are inside preview negotiation or client allow204 responces oudsite of preview then*/
+ if(preview_data || ci_req_allow204(req))
+ return CI_MOD_ALLOW204;
+
+ /*
+ Squid does not support preview of data in reqmod requests neither 204 responces outside preview
+ so we need to read all the body if exists and send it back to squid.
+ Allocate a new body for it
+ */
+ if(ci_req_hasbody(req)){
+ int clen=ci_http_content_lenght(req)+100;
+ uc->body=ci_cached_file_new(clen);
+ }
+
+ } else if (rc == 2 && RedirectUrl && *RedirectUrl) {
+ char buf [strlen (RedirectUrl) + 20];
+ /*The URL is not a good one so....*/
+ ci_debug_printf(9,"Oh!!! we are going to redirect this site.....\n");
+
+ uc->denied = 1;
+ uc->body=ci_cached_file_new(strlen(redirect_message)+10);
+ ci_http_response_create(req,1,1); /*Build the responce headers*/
+
+ ci_http_response_add_header(req,"HTTP/1.1 302 Found");/*Send an 302 Found http responce to web client*/
+ ci_http_response_add_header(req,"Server: C-ICAP");
+ snprintf (buf, sizeof buf, "Location: %s", RedirectUrl);
+ ci_http_response_add_header(req,buf);
+ ci_http_response_add_header(req,"Content-Type: text/html");
+ ci_http_response_add_header(req,"Content-Language: en");
+
+ ci_cached_file_write(uc->body,redirect_message,strlen(redirect_message),1);
+ } else {
+ /*The URL is not a good one so....*/
+ ci_debug_printf(9,"Oh!!! we are going to deny this site.....\n");
+
+ uc->denied = 1;
+ uc->body=ci_cached_file_new(strlen(reject_message)+10);
+ ci_http_response_create(req,1,1); /*Build the responce headers*/
+
+ ci_http_response_add_header(req,"HTTP/1.1 403 Forbidden");/*Send an 403 Forbidden http responce to web client*/
+ ci_http_response_add_header(req,"Server: C-ICAP");
+ ci_http_response_add_header(req,"Content-Type: text/html");
+ ci_http_response_add_header(req,"Content-Language: en");
+
+ ci_cached_file_write(uc->body,reject_message,strlen(reject_message),1);
+ }
+
+ unlock_data(req);
+ return CI_MOD_CONTINUE;
+}
+
+
+int url_filter_process(ci_request_t *req){
+
+/*
+ printf("Buffer size=%d, Data size=%d\n ",
+ ((struct membuf *)b)->bufsize,((struct membuf *)b)->endpos);
+*/
+// printf("url_filter process\n");
+ return CI_MOD_DONE;
+}
+
+int url_filter_io(char *wbuf, int *wlen, char *rbuf, int *rlen, int iseof,
+ ci_request_t * req)
+{
+ int ret;
+ struct url_filter_data *uc = ci_service_data(req);
+ if (!uc->body)
+ return CI_ERROR;
+
+ ret = CI_OK;
+ if (uc->denied == 0) {
+ if (rbuf && rlen) {
+ *rlen = ci_cached_file_write(uc->body, rbuf, *rlen, iseof);
+ if (*rlen == CI_ERROR)
+ ret = CI_ERROR;
+ }
+ else if (iseof)
+ ci_cached_file_write(uc->body, NULL, 0, iseof);
+ }
+
+ if (wbuf && wlen) {
+ *wlen = ci_cached_file_read(uc->body, wbuf, *wlen);
+ if (*wlen == CI_ERROR)
+ ret = CI_ERROR;
+ }
+
+ return ret;
+}
+
+static unsigned dotip2int (char *str)
+{
+ unsigned ip = 0, byte = 0;
+
+ for (; *str; str++) {
+ if (*str == '.') {
+ ip <<= 8;
+ ip += byte;
+ byte = 0;
+ } else {
+ byte *= 10;
+ byte += *str - '0';
+ }
+ }
+ ip <<= 8;
+ ip += byte;
+ return ip;
+}
+
+static unsigned str2int (const char *str)
+{
+ unsigned ip = 0;
+
+ if (!str) return 0;
+ for (; *str; str++) {
+ ip *= 10;
+ ip += *str - '0';
+ }
+ return ip;
+}