diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f9e5a9f4..8ec2b0ea 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -2,4 +2,5 @@ Christos Tsantilas Alexandros Tsantilas : has wrote some of the parsers used by c-icap Tofig Suleymanov: Implemented the ListenAddress configuration option Alfred Klomp, Bokxing IT: bug fixes -Trever L. Adams: Implement txtTemplates +Trever L. Adams: txtTemplates, bzip,gzip/deflate encoding routings +Jeffrey Merkey: brotli compression/decompression support diff --git a/COPYING b/COPYING index 5ab7695a..602bfc94 100644 --- a/COPYING +++ b/COPYING @@ -146,7 +146,7 @@ such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. - + 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an diff --git a/Makefile.am b/Makefile.am index aad2e93a..acfa0d0c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,5 @@ +srcdir = @srcdir@ +top_builddir=@top_builddir@ CONFIGDIR=@sysconfdir@ PKGLIBDIR=@pkglibdir@ @@ -29,9 +31,12 @@ UTIL_LIB_SOURCES += regex.c endif UTIL_SOURCES=os/unix/proc_utils.c +RPATH_FLAG= +if USE_RPATH +RPATH_FLAG+=-rpath @libdir@ +endif - -libicapapi_la_SOURCES= header.c body.c decode.c simple_api.c request_common.c \ +libicapapi_la_SOURCES= header.c body.c decode.c encode.c simple_api.c request_common.c \ filetype.c debug.c cfg_lib.c mem.c service_lib.c \ cache.c lookup_table.c lookup_file_table.c hash.c \ txt_format.c stats.c types_ops.c acl.c txtTemplate.c \ @@ -45,23 +50,22 @@ c_icap_SOURCES = aserver.c request.c cfg_param.c \ # libicapapi ...... -libicapapi_la_CFLAGS= $(INVISIBILITY_CFLAG) -Iinclude/ @ZLIB_ADD_FLAG@ @OPENSSL_ADD_FLAG@ @BZLIB_ADD_FLAG@ @PCRE_ADD_FLAG@ -DCI_BUILD_LIB +libicapapi_la_CFLAGS= $(INVISIBILITY_CFLAG) -I$(srcdir)/include/ -Iinclude/ @ZLIB_ADD_FLAG@ @OPENSSL_ADD_FLAG@ @BZLIB_ADD_FLAG@ @BROTLI_ADD_FLAG@ @PCRE_ADD_FLAG@ -DCI_BUILD_LIB -libicapapi_la_LIBADD = @ZLIB_ADD_LDADD@ @BZLIB_ADD_LDADD@ @PCRE_ADD_LDADD@ @DL_ADD_FLAG@ @THREADS_LDADD@ @OPENSSL_ADD_LDADD@ +libicapapi_la_LIBADD = @ZLIB_ADD_LDADD@ @BZLIB_ADD_LDADD@ @BROTLI_ADD_LDADD@ @PCRE_ADD_LDADD@ @DL_ADD_FLAG@ @THREADS_LDADD@ @OPENSSL_ADD_LDADD@ libicapapi_la_LDFLAGS= -shared -version-info @CICAPLIB_VERSION@ @THREADS_LDFLAGS@ +export EXT_PROGRAMS_MKLIB = @ZLIB_LNDIR_LDADD@ @BZLIB_LNDIR_LDADD@ @BROTLI_LNDIR_LDADD@ @PCRE_LNDIR_LDADD@ @OPENSSL_LNDIR_LDADD@ -#c_icap the main server +#c_icap the main server c_icap_DEPENDENCIES=libicapapi.la -c_icap_CFLAGS= $(INVISIBILITY_CFLAG) -Iinclude/ \ +c_icap_CFLAGS= $(INVISIBILITY_CFLAG) -I$(top_srcdir)/include/ -I$(top_builddir)/include/ \ -DCONFDIR=\"$(CONFIGDIR)\" -DMODSDIR=\"$(MODULESDIR)\" \ -DSERVDIR=\"$(SERVICESDIR)\" -DLOGDIR=\"$(LOGDIR)\" \ -DDATADIR=\"$(DATADIR)\" @OPENSSL_ADD_FLAG@ -c_icap_LDADD = libicapapi.la @DL_ADD_FLAG@ @THREADS_LDADD@ @OPENSSL_ADD_LDADD@ -c_icap_LDFLAGS = -rdynamic -rpath @libdir@ @THREADS_LDFLAGS@ - -EXT_PROGRAMS_MKLIB = -licapapi +c_icap_LDADD = libicapapi.la @DL_ADD_FLAG@ @THREADS_LDADD@ $(EXT_PROGRAMS_MKLIB) +c_icap_LDFLAGS = -rdynamic $(RPATH_FLAG) @THREADS_LDFLAGS@ INCS = access.h body.h cfg_param.h c-icap-conf.h c-icap.h ci_threads.h \ @@ -93,30 +97,30 @@ do_subst=sed -e 's%[@]SYSCONFDIR[@]%$(CONFIGDIR)%g' \ CLEANFILES = c-icap-config c-icap-libicapapi-config -# The c-icap.conf, c-icap-config, and c-icap-libicapapi-config must rebuild +# The c-icap.conf, c-icap-config, and c-icap-libicapapi-config must rebuild # on every new configure run. The include/c-icap-conf.h is rebuild when # configure runs so it is a good test. c-icap.conf: c-icap.conf.in include/c-icap-conf.h - $(do_subst) < c-icap.conf.in > $@ + $(do_subst) < $(srcdir)/c-icap.conf.in > $@ c-icap-config: c-icap-config.in include/c-icap-conf.h - $(do_subst) < c-icap-config.in > $@ + $(do_subst) < $(srcdir)/c-icap-config.in > $@ chmod 755 $@ c-icap-libicapapi-config: c-icap-libicapapi-config.in include/c-icap-conf.h - $(do_subst) < c-icap-libicapapi-config.in > $@ + $(do_subst) < $(srcdir)/c-icap-libicapapi-config.in > $@ chmod 755 $@ doc: - $(DOXYGEN) c-icap.dox + $(DOXYGEN) $(srcdir)/c-icap.dox install-data-local: c-icap.conf $(mkinstalldirs) $(DESTDIR)$(CONFIGDIR); $(INSTALL) c-icap.conf $(DESTDIR)$(CONFIGDIR)/c-icap.conf.default - $(INSTALL) c-icap.magic $(DESTDIR)$(CONFIGDIR)/c-icap.magic.default + $(INSTALL) $(srcdir)/c-icap.magic $(DESTDIR)$(CONFIGDIR)/c-icap.magic.default if test ! -f $(DESTDIR)$(CONFIGDIR)/c-icap.conf; then $(INSTALL) c-icap.conf $(DESTDIR)$(CONFIGDIR)/c-icap.conf; fi - if test ! -f $(DESTDIR)$(CONFIGDIR)/c-icap.magic; then $(INSTALL) c-icap.magic $(DESTDIR)$(CONFIGDIR)/c-icap.magic; fi - $(mkinstalldirs) $(DESTDIR)$(LOGDIR); + if test ! -f $(DESTDIR)$(CONFIGDIR)/c-icap.magic; then $(INSTALL) $(srcdir)/c-icap.magic $(DESTDIR)$(CONFIGDIR)/c-icap.magic; fi + $(mkinstalldirs) $(DESTDIR)$(LOGDIR); $(mkinstalldirs) $(DESTDIR)$(SOCKDIR); chgrp nogroup $(DESTDIR)$(LOGDIR) || echo -e "*********\nWARNING! Can not set group for the log dir $(DESTDIR)$(LOGDIR)\n*********\n" chmod 775 $(DESTDIR)$(LOGDIR) diff --git a/README b/README index 4cdf6715..0c7af2d8 100644 --- a/README +++ b/README @@ -1,44 +1,23 @@ -This is NOT a real release. Must considered just as a stable snapshot -from cvs repository. Read the INSTALL.txt file and web pages at -http://c-icap.sourceforge.net/ for information about how to configure. +The c-icap server http://c-icap.sourceforge.net/ -COMMENTS: -*c-icap is more tested in Linux systems. However compiles and runs at least -in FreeBSD 6.x and possibly in other platforms. At regular times I am -testing it also in solaris 10. I was not able to check this release due -to a problem in my solaris machine. I will do it soon... +c-icap is an implementation of an ICAP server. It can be used with HTTP +proxies that support the ICAP protocol to implement content adaptation +and filtering services. -*ipv6 support for Linux and Solaris looks that works OK but it is not -enough tested. +Most of the commercial HTTP proxies must support the ICAP protocol. The +open source Squid proxy server supports it. -*Although I was able to compile c-icap with IPv6 support in FreeBSD 5.x-6.x -it was not possible for me to make it to work. Maybe becouse of bugs in -implementation maybe becouse of my inability to correctly setup the ipv6 -in FreeBSD. +Major features: + - ICAP over TLS support + - C API for developing custom content adaptation and filtering services + - plugins interface + - LDAP integration + - simple ICAP client API -NEW FEATURES: -* ServiceAlias: They are useful in the case the icap client has hardcoded -the service name. As an example in the default config file there is the -avscan service alias which can used by samba vscan-icap module. - -* You can send commands to the c-icap server from command line using the -following syndax: - echo -n command_name > /var/run/c-icap.ctl -Currently the following commands are implemented: - "stop": The c-icap will shutdown - "reconfigure": The service will reread the config file without the need - for stop and restart the c-icap server. The services will - be reinitialized - "relog": This command causes c_icap to close and reopen the log files. - This is very useful for log rotation if you have services that - take a long time to start, such as srv_classify can. - "srv_clamav:dbreload" - : It reloads the clamav virus database - -Examples: - - To reconfigure c-icap: - echo -n "reconfigure" > /var/run/c-icap.ctl - - To close and reopen all log files (for log rotation, etc.) - echo -n "relog" > /var/run/c-icap.ctl - - To reload clamav virusdb without stoping the c-icap: - echo -n "srv_clamav:dbreload" > /var/run/c-icap.ctl +For support, use the following resources: + - General discussion related to c-icap server: + c-icap-users@lists.sourceforge.net + - Basic installation and configuration instructions: + https://sourceforge.net/p/c-icap/wiki/configcicap/ + - c-icap service developers should start from here: + https://sourceforge.net/p/c-icap/wiki/Developers/ diff --git a/RECONF b/RECONF index 61477532..2820b679 100644 --- a/RECONF +++ b/RECONF @@ -1,5 +1,5 @@ echo trunk-`svnversion | cut -d ':' -f 2` > VERSION.m4 -autoreconf -f -i -v +autoreconf -f -i -v #aclocal #autoconf ##autoheader diff --git a/access.c b/access.c index 5e5f3add..5027fd46 100644 --- a/access.c +++ b/access.c @@ -91,9 +91,9 @@ int access_check_request(ci_request_t * req) res = check_request(req); - ci_debug_printf(9,"Access control: %s\n", (res==CI_ACCESS_ALLOW? + ci_debug_printf(9,"Access control: %s\n", (res == CI_ACCESS_ALLOW? "ALLOW": - (res==CI_ACCESS_DENY?"DENY":"UNKNOWN"))); + (res == CI_ACCESS_DENY?"DENY":"UNKNOWN"))); return res; } diff --git a/acl.c b/acl.c index 9ace7b0d..fd40a36b 100644 --- a/acl.c +++ b/acl.c @@ -102,49 +102,49 @@ void free_http_req_method(ci_request_t *req, void *param); void *get_data_type(ci_request_t *req, char *param); void free_data_type(ci_request_t *req,void *param); -ci_acl_type_t acl_user= { +ci_acl_type_t acl_user = { "user", get_user, NULL, &ci_str_ops }; -ci_acl_type_t acl_service= { +ci_acl_type_t acl_service = { "service", get_service, NULL, &ci_str_ops }; -ci_acl_type_t acl_req_type= { +ci_acl_type_t acl_req_type = { "type", get_reqtype, NULL, &ci_str_ops }; -ci_acl_type_t acl_tcp_port= { +ci_acl_type_t acl_tcp_port = { "port", get_port, NULL, &ci_int32_ops }; -ci_acl_type_t acl_tcp_src= { +ci_acl_type_t acl_tcp_src = { "src", get_client_ip, NULL, &ci_ip_sockaddr_ops }; -ci_acl_type_t acl_tcp_srvip= { +ci_acl_type_t acl_tcp_srvip = { "srvip", get_srv_ip, NULL, &ci_ip_sockaddr_ops }; -ci_acl_type_t acl_tcp_xclientip= { +ci_acl_type_t acl_tcp_xclientip = { "http_client_ip", get_http_client_ip, NULL, @@ -202,14 +202,14 @@ ci_acl_type_t acl_http_resp_line = { }; #endif -ci_acl_type_t acl_http_req_method= { +ci_acl_type_t acl_http_req_method = { "http_req_method", get_http_req_method, free_http_req_method, &ci_str_ops }; -ci_acl_type_t acl_data_type= { +ci_acl_type_t acl_data_type = { "data_type", get_data_type, free_data_type, @@ -258,7 +258,7 @@ static const ci_type_ops_t acl_cmp_uint64_ops = { void free_cmp_uint64_data(ci_request_t *req,void *param); void *get_content_length(ci_request_t *req, char *param); -static ci_acl_type_t acl_content_length= { +static ci_acl_type_t acl_content_length = { "content_length", get_content_length, free_cmp_uint64_data, @@ -298,7 +298,7 @@ static const ci_type_ops_t acl_time_ops = { /*The acl type*/ void free_time_data(ci_request_t *req,void *param); void *get_time_data(ci_request_t *req, char *param); -static ci_acl_type_t acl_time= { +static ci_acl_type_t acl_time = { "time", get_time_data, free_time_data, @@ -492,7 +492,7 @@ ci_access_entry_t *ci_access_entry_new(ci_access_entry_t **list, int type) *list = access_entry; } else { cur = *list; - while (cur->next!=NULL) + while (cur->next != NULL) cur = cur->next; cur->next = access_entry; } @@ -506,7 +506,6 @@ void ci_access_entry_release(ci_access_entry_t *list) if (!list) return; - access_entry = list; while (list) { access_entry = list; list = list->next; @@ -593,10 +592,10 @@ ci_acl_spec_t * ci_acl_spec_new(const char *name, const char *type, const char spec->data = NULL; spec->next = NULL; - if (spec_list!=NULL) { - if (*spec_list!=NULL) { + if (spec_list != NULL) { + if (*spec_list != NULL) { cur = *spec_list; - while (cur->next!=NULL) + while (cur->next != NULL) cur = cur->next; cur->next = spec; } else @@ -626,7 +625,7 @@ ci_acl_data_t *ci_acl_spec_new_data(ci_acl_spec_t *spec, const char *val) } new_data->data = data; new_data->next = NULL; - if ((list=spec->data) != NULL) { + if ((list = spec->data) != NULL) { while (list->next != NULL) list = list->next; list->next = new_data; @@ -642,7 +641,7 @@ ci_acl_spec_t *ci_acl_spec_search(ci_acl_spec_t *list, const char *name) if (!list || !name) return NULL; spec = list; - while (spec!= NULL) { + while (spec != NULL) { ci_debug_printf(9,"Checking name:%s with specname %s\n", name, spec->name); if (strcmp(spec->name, name) == 0 ) { return spec; @@ -671,8 +670,8 @@ void ci_acl_spec_list_release(ci_acl_spec_t *spec) { ci_acl_spec_t *cur; while (spec) { - cur=spec; - spec=spec->next; + cur = spec; + spec = spec->next; ci_acl_spec_release(cur); } } @@ -690,6 +689,14 @@ int ci_acl_typelist_init(struct ci_acl_type_list *list) return 1; } +void ci_acl_typelist_destroy(struct ci_acl_type_list *list) +{ + free(list->acl_type_list); + list->acl_type_list = NULL; + list->acl_type_list_size = 0; + list->acl_type_list_num = 0; +} + int ci_acl_typelist_add(struct ci_acl_type_list *list, const ci_acl_type_t *type) { ci_acl_type_t *cur; @@ -719,6 +726,7 @@ int ci_acl_typelist_add(struct ci_acl_type_list *list, const ci_acl_type_t *type cur->name[MAX_NAME_LEN] = '\0'; cur->type = type->type; cur->get_test_data = type->get_test_data; + cur->free_test_data = type->free_test_data; list->acl_type_list_num++; return 1; } @@ -726,8 +734,8 @@ int ci_acl_typelist_add(struct ci_acl_type_list *list, const ci_acl_type_t *type const ci_acl_type_t *ci_acl_typelist_search(struct ci_acl_type_list *list,const char *name) { int i; - for (i=0; iacl_type_list_num; i++) { - if (strcmp(list->acl_type_list[i].name,name)==0) + for (i = 0; i < list->acl_type_list_num; i++) { + if (strcmp(list->acl_type_list[i].name,name) == 0) return (const ci_acl_type_t *)&list->acl_type_list[i]; } return NULL; @@ -754,16 +762,16 @@ int ci_acl_typelist_reset(struct ci_acl_type_list *list) int spec_data_check(const ci_acl_spec_t *spec, const void *req_raw_data) { // int (*comp)(void *req_spec, void *acl_spec); - struct ci_acl_data *spec_data=spec->data; + struct ci_acl_data *spec_data = spec->data; const ci_type_ops_t *ops = spec->type->type; ci_debug_printf(9,"Check request with ci_acl_spec_t:%s\n", spec->name); - while (spec_data!=NULL) { + while (spec_data != NULL) { if (ops->equal(spec_data->data, (void *)req_raw_data)) { ci_debug_printf(9,"The ci_acl_spec_t:%s matches\n", spec->name); return 1; } - spec_data=spec_data->next; + spec_data = spec_data->next; } return 0; } @@ -776,7 +784,7 @@ int request_match_specslist(ci_request_t *req, const struct ci_specs_list *spec_ void *test_data; ret = 1; - while (spec_list!=NULL) { + while (spec_list != NULL) { spec = spec_list->spec; negate = spec_list->negate; type = spec->type; @@ -787,9 +795,9 @@ int request_match_specslist(ci_request_t *req, const struct ci_specs_list *spec_ } check_result = spec_data_check(spec, test_data); - if (check_result==0 && negate==0) + if (check_result == 0 && negate == 0) ret = 0; - else if (check_result!=0 && negate!=0) + else if (check_result != 0 && negate != 0) ret = 0; if (type->free_test_data) @@ -798,7 +806,7 @@ int request_match_specslist(ci_request_t *req, const struct ci_specs_list *spec_ if (ret == 0) return 0; - spec_list=spec_list->next; + spec_list = spec_list->next; } return 1; } @@ -816,7 +824,7 @@ int ci_access_entry_match_request(ci_access_entry_t *access_entry, ci_request_t if (spec_list && spec_list->spec && request_match_specslist(req, spec_list)) return access_entry->type; - access_entry=access_entry->next; + access_entry = access_entry->next; } return CI_ACCESS_UNKNOWN; } @@ -869,6 +877,11 @@ void ci_acl_reset() acl_load_defaults(); } +void ci_acl_destroy() +{ + ci_acl_typelist_destroy(&types_list); +} + const ci_acl_spec_t *ci_acl_search(const char *name) { return (const ci_acl_spec_t *)ci_acl_spec_search(specs_list, name); @@ -897,11 +910,11 @@ int ci_acl_add_data(const char *name, const char *type, const char *data) } s = acl_type; - if ((s=strchr(s,'{')) != NULL) { - *s='\0'; - param=s+1; - if ((s=strchr(param,'}')) != NULL) - *s= '\0'; + if ((s = strchr(s,'{')) != NULL) { + *s = '\0'; + param = s+1; + if ((s = strchr(param,'}')) != NULL) + *s = '\0'; } if ((spec = ci_acl_spec_search(specs_list, name)) != NULL) { @@ -919,7 +932,7 @@ int ci_acl_add_data(const char *name, const char *type, const char *data) if (!spec) { ci_debug_printf(1, "Error in acl:%s! Maybe the acl type \"%s\" does not exists!\n", - name, acl_type); + name, type); return 0; } ci_acl_spec_new_data(spec, data); @@ -1138,7 +1151,7 @@ void *get_data_type(ci_request_t *req, char *param) if (type < 0) return NULL; - ret_type = malloc(sizeof(unsigned int)); + ret_type = malloc(sizeof(int)); if (!ret_type) return NULL; diff --git a/array.c b/array.c index 58ad7e97..2d70e417 100644 --- a/array.c +++ b/array.c @@ -105,7 +105,7 @@ const ci_array_item_t * ci_array_add(ci_array_t *array, const char *name, const const void * ci_array_search(ci_array_t *array, const char *name) { int i; - for (i=0; i < array->count; i++) { + for (i = 0; i < array->count; i++) { if (strcmp(array->items[i].name, name) == 0) { return array->items[i].value; } @@ -116,7 +116,7 @@ const void * ci_array_search(ci_array_t *array, const char *name) void ci_array_iterate(const ci_array_t *array, void *data, int (*fn)(void *data, const char *name, const void *)) { int i, ret = 0; - for (i=0; i < array->count && ret == 0; i++) { + for (i = 0; i < array->count && ret == 0; i++) { ret = (*fn)(data, array->items[i].name, array->items[i].value); } } @@ -328,7 +328,7 @@ const void * ci_dyn_array_search(ci_dyn_array_t *array, const char *name) void ci_dyn_array_iterate(const ci_dyn_array_t *array, void *data, int (*fn)(void *data, const char *name, const void *value)) { int i, ret = 0; - for (i=0; i < array->count && ret == 0; i++) + for (i = 0; i < array->count && ret == 0; i++) ret = (*fn)(data, array->items[i]->name, array->items[i]->value); } @@ -451,7 +451,7 @@ void * ci_vector_pop(ci_vector_t *vector) void ci_vector_iterate(const ci_vector_t *vector, void *data, int (*fn)(void *data, const void *)) { int i, ret = 0; - for (i=0; vector->items[i] != NULL && ret == 0; i++) + for (i = 0; vector->items[i] != NULL && ret == 0; i++) ret = (*fn)(data, vector->items[i]); } @@ -465,7 +465,7 @@ void ci_str_vector_iterate(const ci_str_vector_t *vector, void *data, int (*fn)( const char * ci_str_vector_search(ci_str_vector_t *vector, const char *item) { int i; - for (i=0; vector->items[i] != NULL; i++) { + for (i = 0; vector->items[i] != NULL; i++) { if (strcmp(vector->items[i], item) == 0) return vector->items[i]; } @@ -777,7 +777,7 @@ void ci_list_sort2(ci_list_t *list, int (*cmp_func)(const void *obj1, const void currentSorted = &sortedHead; while (!(*currentSorted == NULL || cmp_func(currentHead->item, (*currentSorted)->item, list->obj_size) < 0)) currentSorted = &(*currentSorted)->next; - currentHead->next = *currentSorted; + currentHead->next = *currentSorted; *currentSorted = currentHead; if ((*currentSorted)->next == NULL) sortedTail = (*currentSorted); diff --git a/aserver.c b/aserver.c index 2278d5b9..9eaa6093 100644 --- a/aserver.c +++ b/aserver.c @@ -44,6 +44,7 @@ char MY_HOSTNAME[CI_MAXHOSTNAMELEN + 1]; void init_conf_tables(); int init_body_system(); int config(int, char **); +void config_destroy(); int init_server(); int start_server(); int store_pid(char *pidfile); @@ -153,7 +154,7 @@ int main(int argc, char **argv) init_services(); config(argc, argv); compute_my_hostname(); - ci_debug_printf(2, "My hostname is:%s\n", MY_HOSTNAME); + ci_debug_printf(2, "My hostname is: %s\n", MY_HOSTNAME); if (!log_open()) { ci_debug_printf(1, "Can not init loggers. Exiting.....\n"); @@ -172,11 +173,16 @@ int main(int argc, char **argv) store_pid(CI_CONF.PIDFILE); #endif + execute_commands_no_lock(CI_CMD_POST_CONFIG); if (!init_server()) return -1; post_init_modules(); post_init_services(); start_server(); + config_destroy(); + commands_destroy(); + ci_acl_destroy(); clear_pid(CI_CONF.PIDFILE); + ci_mem_exit(); return 0; } diff --git a/body.c b/body.c index a627d023..5eec78e0 100644 --- a/body.c +++ b/body.c @@ -171,13 +171,13 @@ int ci_membuf_write(struct ci_membuf *b, const char *data, int len, int iseof) int terminate = b->flags & CI_MEMBUF_NULL_TERMINATED; if ((b->flags & CI_MEMBUF_RO) || (b->flags & CI_MEMBUF_CONST)) { - ci_debug_printf( 1, "ci_membuf_write: can not write: buffer is read-only!\n"); + ci_debug_printf(1, "ci_membuf_write: can not write: buffer is read-only!\n"); return 0; } if ((b->flags & CI_MEMBUF_HAS_EOF)) { if (len > 0) { - ci_debug_printf( 1, "Cannot write to membuf: the eof flag is set!\n"); + ci_debug_printf(1, "Cannot write to membuf: the eof flag is set!\n"); } return 0; } @@ -196,7 +196,7 @@ int ci_membuf_write(struct ci_membuf *b, const char *data, int len, int iseof) newsize = b->bufsize + INCSTEP; newbuf = ci_buffer_realloc(b->buf, newsize); if (newbuf == NULL) { - ci_debug_printf( 1, "ci_membuf_write: Failed to grow membuf for new data!\n"); + ci_debug_printf(1, "ci_membuf_write: Failed to grow membuf for new data!\n"); if (remains >= 0) { if (remains) memcpy(b->buf + b->endpos, data, remains); @@ -206,7 +206,7 @@ int ci_membuf_write(struct ci_membuf *b, const char *data, int len, int iseof) } else b->endpos = b->bufsize; } else { - ci_debug_printf( 1, "ci_membuf_write: Failed to NULL terminate membuf!\n"); + ci_debug_printf(1, "ci_membuf_write: Failed to NULL terminate membuf!\n"); } return remains; } @@ -288,7 +288,7 @@ int do_write(int fd, const void *buf, size_t count) errno = 0; do { bytes = write(fd, buf, count); - } while ( bytes < 0 && errno == EINTR); + } while (bytes < 0 && errno == EINTR); return bytes; } @@ -299,7 +299,7 @@ int do_read(int fd, void *buf, size_t count) errno = 0; do { bytes = read(fd, buf, count); - } while ( bytes < 0 && errno == EINTR); + } while (bytes < 0 && errno == EINTR); return bytes; } @@ -316,7 +316,7 @@ int do_open(const char *pathname, int flags) errno = 0; do { fd = open(pathname, flags, F_PERM); - } while ( fd < 0 && errno == EINTR); + } while (fd < 0 && errno == EINTR); return fd; } @@ -500,11 +500,11 @@ int ci_cached_file_write(ci_cached_file_t * body, const char *buf, int len, int return -1; } ret = do_write(body->fd, body->buf, body->endpos); - if ( ret>=0 && do_write(body->fd, buf, len) >=0 ) { + if (ret >= 0 && do_write(body->fd, buf, len) >= 0) { body->endpos += len; return len; } else { - ci_debug_printf( 1, "Cannot write to cachefile: %s\n", strerror( errno ) ); + ci_debug_printf(1, "Cannot write to cachefile: %s\n", strerror(errno)); return CI_ERROR; } } /* if remainsfd = ci_mktemp_file(CI_TMPDIR, tmp_template, body->filename)) < 0) { + char err_buf[512]; ci_debug_printf(1, - "ci_simple_file_new: Can not open temporary filename in directory:%s\n", - CI_TMPDIR); + "ci_simple_file_new: Can not open temporary filename in directory:%s (%d/%s)\n", CI_TMPDIR, errno, ci_strerror(errno, err_buf, sizeof(err_buf))); ci_object_pool_free(body); return NULL; } @@ -595,6 +595,10 @@ ci_simple_file_t *ci_simple_file_new(ci_off_t maxsize) body->bytes_in = 0; body->bytes_out = 0; body->attributes = NULL; +#if defined(USE_POSIX_MAPPED_FILES) + body->mmap_addr = NULL; + body->mmap_size = 0; +#endif return body; } @@ -610,18 +614,23 @@ ci_simple_file_t *ci_simple_file_named_new(char *dir, char *filename,ci_off_t ma if (filename) { snprintf(body->filename, CI_FILENAME_LEN, "%s/%s", dir, filename); - if ((body->fd = - do_open(body->filename, O_CREAT | O_RDWR | O_EXCL)) < 0) { - ci_debug_printf(1, "Can not open temporary filename: %s\n", - body->filename); + if ((body->fd = do_open(body->filename, O_CREAT | O_RDWR | O_EXCL)) < 0) { + char err_buf[512]; + ci_debug_printf(1, "Can not open temporary filename: %s (%d/%s)\n", + body->filename, + errno, + ci_strerror(errno, err_buf, sizeof(err_buf))); ci_object_pool_free(body); return NULL; } - } else if ((body->fd = - ci_mktemp_file(dir, tmp_template, body->filename)) < 0) { + } else if ((body->fd = ci_mktemp_file(dir, tmp_template, body->filename)) < 0) { + char err_buf[512]; ci_debug_printf(1, - "Can not open temporary filename in directory: %s\n", - dir); + "Can not open temporary filename in directory: %s (%d/%s)\n", + dir, + errno, + ci_strerror(errno, err_buf, sizeof(err_buf)) + ); ci_object_pool_free(body); return NULL; } @@ -692,7 +701,7 @@ int ci_simple_file_write(ci_simple_file_t * body, const char *buf, int len, int if (body->flags & CI_FILE_HAS_EOF) { if (len > 0) { - ci_debug_printf( 1, "Cannot write to file: '%s', the eof flag is set!\n", body->filename); + ci_debug_printf(1, "Cannot write to file: '%s', the eof flag is set!\n", body->filename); } return 0; } @@ -707,7 +716,7 @@ int ci_simple_file_write(ci_simple_file_t * body, const char *buf, int len, int wsize = min(body->readpos-body->endpos-1, len); } else if (body->max_store_size && body->endpos >= body->max_store_size) { /*If we are going to entre ring mode. If we are using locking we can not enter ring mode.*/ - if (body->readpos!=0 && (body->flags & CI_FILE_USELOCK)==0) { + if (body->readpos != 0 && (body->flags & CI_FILE_USELOCK) == 0) { body->endpos = 0; if (!(body->flags & CI_FILE_RING_MODE)) { body->flags |= CI_FILE_RING_MODE; @@ -728,7 +737,7 @@ int ci_simple_file_write(ci_simple_file_t * body, const char *buf, int len, int lseek(body->fd, body->endpos, SEEK_SET); if ((ret = do_write(body->fd, buf, wsize)) < 0) { - ci_debug_printf( 1, "Cannot write to file: %s\n", strerror( errno ) ); + ci_debug_printf(1, "Cannot write to file: %s\n", strerror(errno)); } else { body->endpos += ret; body->bytes_in += ret; @@ -752,7 +761,7 @@ int ci_simple_file_read(ci_simple_file_t * body, char *buf, int len) if (len <= 0) return 0; - if ((body->readpos == body->endpos)) { + if (body->readpos == body->endpos) { if ((body->flags & CI_FILE_HAS_EOF)) { ci_debug_printf(9, "Has EOF and no data to read, send EOF\n"); return CI_EOF; @@ -814,35 +823,42 @@ int ci_simple_file_truncate(ci_simple_file_t *body, ci_off_t new_size) return 1; } -#if defined(USE_POSIX_MAPPED_FILES) - const char * ci_simple_file_to_const_string(ci_simple_file_t *body) { +#if defined(USE_POSIX_MAPPED_FILES) ci_off_t map_size; char *addr = NULL; if (!(body->flags & CI_FILE_HAS_EOF)) { - ci_debug_printf( 1, "mmap to file: '%s' failed, the eof flag is not set!\n", body->filename); + ci_debug_printf(1, "mmap to file: '%s' failed, the eof flag is not set!\n", body->filename); return NULL; } /* We need one more byte for string termination*/ map_size = body->endpos + 1; + if (ftruncate(body->fd, map_size) != 0) + return NULL; /*failed to resize*/ + if (body->mmap_addr == NULL) { addr = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, body->fd, 0); if (!addr) - return 0; - /*Terminate buffer */ + return NULL; + + /*Terminate buffer (already terminated by ftruncate?) */ addr[map_size - 1] = '\0'; body->mmap_addr = addr; body->mmap_size = map_size; } return body->mmap_addr; +#else + ci_debug_printf( 1, "ci_simple_file_to_const_string: Requires posix mapped files to work, which is not supported."); + return NULL; +#endif } #define CI_MEMBUF_SF_FLAGS (CI_MEMBUF_CONST | CI_MEMBUF_RO | CI_MEMBUF_NULL_TERMINATED) ci_membuf_t *ci_simple_file_to_membuf(ci_simple_file_t *body, unsigned int flags) { - assert((CI_MEMBUF_SF_FLAGS & flags) ==flags); + assert((CI_MEMBUF_SF_FLAGS & flags) == flags); assert(flags & CI_MEMBUF_CONST); void *addr = (void *)ci_simple_file_to_const_string(body); if (!addr) @@ -850,8 +866,6 @@ ci_membuf_t *ci_simple_file_to_membuf(ci_simple_file_t *body, unsigned int flags return ci_membuf_from_content(body->mmap_addr, body->mmap_size, body->endpos, CI_MEMBUF_CONST | CI_MEMBUF_RO | CI_MEMBUF_NULL_TERMINATED | CI_MEMBUF_HAS_EOF); } -#endif - /*******************************************************************/ /*ring memory buffer implementation */ @@ -867,7 +881,7 @@ struct ci_ring_buf *ci_ring_buf_new(int size) return NULL; } - buf->end_buf=buf->buf+size-1; + buf->end_buf = buf->buf+size-1; buf->read_pos = buf->buf; buf->write_pos = buf->buf; buf->full = 0; @@ -882,7 +896,7 @@ void ci_ring_buf_destroy(struct ci_ring_buf *buf) int ci_ring_buf_is_empty(struct ci_ring_buf *buf) { - return (buf->read_pos==buf->write_pos) && (buf->full==0); + return (buf->read_pos == buf->write_pos) && (buf->full == 0); } int ci_ring_buf_write_block(struct ci_ring_buf *buf, char **wb, int *len) @@ -911,7 +925,7 @@ int ci_ring_buf_read_block(struct ci_ring_buf *buf, char **rb, int *len) } else if (buf->read_pos >= buf->write_pos) { *rb = buf->read_pos; *len = buf->end_buf - buf->read_pos +1; - return (buf->read_pos!=buf->buf? 1:0); + return (buf->read_pos != buf->buf? 1:0); } else { /*buf->read_pos < buf->write_pos*/ *rb = buf->read_pos; *len = buf->write_pos - buf->read_pos; @@ -958,7 +972,7 @@ int ci_ring_buf_write(struct ci_ring_buf *buf, const char *data,int size) data += wb_len; written += wb_len; } - } while ((ret!=0) && (size>0)); + } while ((ret != 0) && (size > 0)); return written; } @@ -978,6 +992,6 @@ int ci_ring_buf_read(struct ci_ring_buf *buf, char *data,int size) data += rb_len; data_read += rb_len; } - } while ((ret!=0) && (size>0 )); + } while ((ret != 0) && (size > 0)); return data_read; } diff --git a/c-icap-config.in b/c-icap-config.in index f3768773..7342579f 100644 --- a/c-icap-config.in +++ b/c-icap-config.in @@ -21,7 +21,7 @@ LIBS=@MODULES_LIBADD@ LDFLAGS="" -usage() +usage() { cat <a: Http Client IP Address. Only supported if the proxy +# %>a: Http Client IP Address. Only supported if the proxy # client supports the "X-Client-IP" header # %