diff options
Diffstat (limited to 'util/src')
62 files changed, 19208 insertions, 0 deletions
diff --git a/util/src/Makefile.am b/util/src/Makefile.am new file mode 100644 index 0000000..5b1ab14 --- /dev/null +++ b/util/src/Makefile.am @@ -0,0 +1,51 @@ +SUBDIRS = platforms/unix @ZLIBBUILD@ +lib_LTLIBRARIES = libaxutil.la +libaxutil_la_SOURCES = hash.c \ + allocator.c \ + env.c \ + error.c \ + stream.c \ + log.c \ + string.c \ + string_util.c \ + qname.c \ + array_list.c \ + linked_list.c \ + utils.c \ + dir_handler.c \ + file_handler.c \ + class_loader.c\ + network_handler.c \ + file.c\ + uuid_gen.c\ + thread_pool.c \ + property.c \ + types.c \ + param.c \ + param_container.c \ + dll_desc.c\ + url.c\ + stack.c \ + generic_obj.c \ + base64.c \ + uri.c \ + date_time.c \ + base64_binary.c \ + properties.c \ + rand.c \ + date_time_util.c \ + version.c \ + duration.c \ + md5.c \ + http_chunked_stream.c \ + digest_calc.c + +libaxutil_la_LIBADD = $(top_builddir)/src/platforms/unix/libaxis2_unix.la \ + -lpthread \ + @ZLIBLIBS@ + +libaxutil_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include + +EXTRA_DIST=platforms/windows string_util.c diff --git a/util/src/allocator.c b/util/src/allocator.c new file mode 100644 index 0000000..1b31048 --- /dev/null +++ b/util/src/allocator.c @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_allocator.h> +#include <axutil_utils.h> +#include <stdlib.h> +#include <string.h> + +void *AXIS2_CALL axutil_allocator_malloc_impl( + axutil_allocator_t * allocator, + size_t size); + +void *AXIS2_CALL axutil_allocator_realloc_impl( + axutil_allocator_t * allocator, + void *ptr, + size_t size); + +void AXIS2_CALL axutil_allocator_free_impl( + axutil_allocator_t * allocator, + void *ptr); + +AXIS2_EXTERN axutil_allocator_t *AXIS2_CALL +axutil_allocator_init( + axutil_allocator_t * allocator) +{ + if(allocator) + return allocator; + + else + { + allocator = (axutil_allocator_t *)malloc(sizeof(axutil_allocator_t)); + memset(allocator, 0, sizeof(axutil_allocator_t)); + if(allocator) + { + allocator->malloc_fn = axutil_allocator_malloc_impl; + allocator->realloc = axutil_allocator_realloc_impl; + allocator->free_fn = axutil_allocator_free_impl; + allocator->global_pool_ref = 0; + + return allocator; + } + } + return NULL; +} + +AXIS2_EXTERN axutil_allocator_t *AXIS2_CALL +axutil_allocator_clone( + axutil_allocator_t * allocator) +{ + if(!allocator) + return NULL; + + else + { + axutil_allocator_t* clone = NULL; + clone = (axutil_allocator_t *)malloc(sizeof(axutil_allocator_t)); + memset(clone, 0, sizeof(axutil_allocator_t)); + if(clone) + { + clone->malloc_fn = allocator->malloc_fn; + clone->realloc = allocator->realloc; + clone->free_fn = allocator->free_fn; + clone->current_pool = allocator->current_pool; + clone->global_pool = allocator->global_pool; + clone->local_pool = allocator->local_pool; + clone->global_pool_ref = 0; + + return clone; + } + } + return NULL; +} +AXIS2_EXTERN void AXIS2_CALL +axutil_allocator_free( + axutil_allocator_t * allocator) +{ + if(allocator) + { + allocator->free_fn(allocator, allocator); + } + return; +} + +void *AXIS2_CALL +axutil_allocator_malloc_impl( + axutil_allocator_t * allocator, + size_t size) +{ + return malloc(size); +} + +void *AXIS2_CALL +axutil_allocator_realloc_impl( + axutil_allocator_t * allocator, + void *ptr, + size_t size) +{ + return realloc(ptr, size); +} + +void AXIS2_CALL +axutil_allocator_free_impl( + axutil_allocator_t * allocator, + void *ptr) +{ + free(ptr); +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_allocator_switch_to_global_pool( + axutil_allocator_t * allocator) +{ + if(!allocator) + return; + allocator->global_pool_ref++; + allocator->current_pool = allocator->global_pool; + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_allocator_switch_to_local_pool( + axutil_allocator_t * allocator) +{ + if(!allocator) + return; + if(allocator->global_pool_ref > 0) + { + allocator->global_pool_ref--; + } + + if(allocator->global_pool_ref == 0) + { + allocator->current_pool = allocator->local_pool; + } + return; +} + diff --git a/util/src/array_list.c b/util/src/array_list.c new file mode 100644 index 0000000..a40ecf9 --- /dev/null +++ b/util/src/array_list.c @@ -0,0 +1,304 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_array_list.h> +#include <axutil_utils.h> +#include <string.h> + +struct axutil_array_list +{ + + /**The number of elements in this list. */ + int size; + + /**Current capacity of this list. */ + int capacity; + + /** Where the data is stored. */ + void **data; +}; + +AXIS2_EXTERN struct axutil_array_list *AXIS2_CALL +axutil_array_list_create( + const axutil_env_t * env, + int capacity) +{ + axutil_array_list_t *array_list = NULL; + + array_list = AXIS2_MALLOC(env->allocator, sizeof(axutil_array_list_t)); + if(!array_list) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + array_list->size = 0; + array_list->capacity = 0; + array_list->data = NULL; + + /* Check capacity, and set the default if error */ + if(capacity <= 0) + capacity = AXIS2_ARRAY_LIST_DEFAULT_CAPACITY; + array_list->data = AXIS2_MALLOC(env->allocator, sizeof(void *) * capacity); + if(!array_list->data) + { + axutil_array_list_free(array_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + array_list->capacity = capacity; + + return array_list; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_array_list_ensure_capacity( + struct axutil_array_list * array_list, + const axutil_env_t * env, + int min_capacity) +{ + AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); + if(min_capacity > array_list->capacity) + { + int new_capacity = (array_list->capacity * 2 > min_capacity) ? (array_list->capacity * 2) + : min_capacity; + void **data = (void **)AXIS2_MALLOC(env->allocator, sizeof(void *) * new_capacity); + if(!data) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return AXIS2_FAILURE; + } + memcpy(data, array_list->data, sizeof(void *) * array_list->capacity); + + AXIS2_FREE(env->allocator, array_list->data); + + array_list->data = data; + array_list->capacity = new_capacity; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_array_list_size( + struct axutil_array_list *array_list, + const axutil_env_t * env) +{ + /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers + env->error->status_code on no error destroying the information + therein that an error has already occurred. */ + if(!array_list) + return 0; + return array_list->size; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_array_list_is_empty( + struct axutil_array_list * array_list, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); + return array_list->size == 0; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_array_list_contains( + struct axutil_array_list * array_list, + const axutil_env_t * env, + void *e) +{ + AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); + return axutil_array_list_index_of(array_list, env, e) != -1; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_array_list_index_of( + struct axutil_array_list *array_list, + const axutil_env_t * env, + void *e) +{ + int i = 0; + + AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); + for(i = 0; i < array_list->size; i++) + if(e == array_list->data[i]) + return i; + return -1; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_array_list_get( + struct axutil_array_list *array_list, + const axutil_env_t * env, + int index) +{ + /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers + env->error->status_code on no error destroying the information + therein that an error has already occurred. */ + if(axutil_array_list_check_bound_exclusive(array_list, env, index)) + return array_list->data[index]; + else + return NULL; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_array_list_set( + struct axutil_array_list *array_list, + const axutil_env_t * env, + int index, + void *e) +{ + void *result = NULL; + + AXIS2_PARAM_CHECK(env->error, array_list, NULL); + if(axutil_array_list_check_bound_exclusive(array_list, env, index)) + { + result = array_list->data[index]; + array_list->data[index] = e; + } + return result; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_array_list_add( + struct axutil_array_list * array_list, + const axutil_env_t * env, + const void *e) +{ + AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); + if(array_list->size == array_list->capacity) + if(axutil_array_list_ensure_capacity(array_list, env, array_list->size + 1) + != AXIS2_SUCCESS) + return AXIS2_FAILURE; + array_list->data[array_list->size++] = (void *)e; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_array_list_add_at( + struct axutil_array_list * array_list, + const axutil_env_t * env, + const int index, + const void *e) +{ + int i = 0; + AXIS2_PARAM_CHECK(env->error, array_list, AXIS2_FAILURE); + + if(!axutil_array_list_check_bound_inclusive(array_list, env, index)) + return AXIS2_FAILURE; + if(array_list->size == array_list->capacity) + { + if(axutil_array_list_ensure_capacity(array_list, env, array_list->size + 1) + != AXIS2_SUCCESS) + return AXIS2_FAILURE; + } + if(index != array_list->size) + { + for(i = array_list->size; i > index; i--) + array_list->data[i] = array_list->data[i - 1]; + } + array_list->data[index] = (void *)e; + array_list->size++; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_array_list_remove( + struct axutil_array_list *array_list, + const axutil_env_t * env, + int index) +{ + void *result = NULL; + int i = 0; + AXIS2_PARAM_CHECK(env->error, array_list, NULL); + + if(axutil_array_list_check_bound_exclusive(array_list, env, index)) + { + result = array_list->data[index]; + for(i = index; i < array_list->size - 1; i++) + array_list->data[i] = array_list->data[i + 1]; + array_list->size--; + } + + return result; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_array_list_check_bound_inclusive( + struct axutil_array_list * array_list, + const axutil_env_t * env, + int index) +{ + /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers + env->error->status_code on no error destroying the information + therein that an error has already occurred. */ + if(!array_list || index < 0 || index > array_list->size) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INDEX_OUT_OF_BOUNDS, AXIS2_FAILURE); + return AXIS2_FALSE; + } + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_array_list_check_bound_exclusive( + struct axutil_array_list * array_list, + const axutil_env_t * env, + int index) +{ + /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers + env->error->status_code on no error destroying the information + therein that an error has already occurred. */ + if(!array_list || index < 0 || index >= array_list->size) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INDEX_OUT_OF_BOUNDS, AXIS2_FAILURE); + return AXIS2_FALSE; + } + return AXIS2_TRUE; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_array_list_free( + struct axutil_array_list *array_list, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK_VOID(env->error, array_list); + + if(array_list->data) + { + AXIS2_FREE(env->allocator, array_list->data); + } + AXIS2_FREE(env->allocator, array_list); + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_array_list_free_void_arg( + void *array_list, + const axutil_env_t * env) +{ + axutil_array_list_t *array_list_l = NULL; + + AXIS2_PARAM_CHECK_VOID(env->error, array_list); + + array_list_l = (axutil_array_list_t *)array_list; + axutil_array_list_free(array_list_l, env); + return; +} + diff --git a/util/src/base64.c b/util/src/base64.c new file mode 100644 index 0000000..0789169 --- /dev/null +++ b/util/src/base64.c @@ -0,0 +1,284 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* base64 encoder/decoder. Originally part of main/util.c + * but moved here so that support/ab and axis2_sha1.c could + * use it. This meant removing the axis2_palloc()s and adding + * ugly 'len' functions, which is quite a nasty cost. + */ + +#include <axutil_base64.h> + +static const unsigned char pr2six[256] = { +#ifndef __OS400__ + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +#else /* __OS400__ */ + /* EBCDIC table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64, + 64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64, + 64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 64, 64, 64, 64, 64, 64, + 64, 9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64, + 64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64 +#endif /* AXIS2_CHARSET_EBCDIC */ +}; + +#ifdef __OS400__ + +static unsigned char os_toascii[256] = { + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + 0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31, + 128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7, + 144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26, + 32, 160, 226, 228, 224, 225, 227, 229, 231, 241, 162, 46, 60, 40, 43, 124, + 38, 233, 234, 235, 232, 237, 238, 239, 236, 223, 33, 36, 42, 41, 59, 172, + 45, 47, 194, 196, 192, 193, 195, 197, 199, 209, 166, 44, 37, 95, 62, 63, + 248, 201, 202, 203, 200, 205, 206, 207, 204, 96, 58, 35, 64, 39, 61, 34, + 216, 97, 98, 99, 100, 101, 102, 103, 104, 105, 171, 187, 240, 253, 254, 177, + 176, 106, 107, 108, 109, 110, 111, 112, 113, 114, 170, 186, 230, 184, 198, + 164, + 181, 126, 115, 116, 117, 118, 119, 120, 121, 122, 161, 191, 208, 221, 222, + 174, + 94, 163, 165, 183, 169, 167, 182, 188, 189, 190, 91, 93, 175, 168, 180, 215, + 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 173, 244, 246, 242, 243, 245, + 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 185, 251, 252, 249, 250, 255, + 92, 247, 83, 84, 85, 86, 87, 88, 89, 90, 178, 212, 214, 210, 211, 213, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 179, 219, 220, 217, 218, 159 +}; + +#endif /* __OS400__ */ + +AXIS2_EXTERN int AXIS2_CALL +axutil_base64_decode_len( + const char *bufcoded) +{ + int nbytesdecoded; + register const unsigned char *bufin; + register int nprbytes; + + if(!bufcoded) + { + return -1; + } + + bufin = (const unsigned char *)bufcoded; + while(pr2six[*(bufin++)] <= 63) + ; + + nprbytes = (int)(bufin - (const unsigned char *)bufcoded) - 1; + /* We are sure that the difference lies within the int range */ + + nbytesdecoded = ((nprbytes >> 2) * 3); + + if(nprbytes & 0x03) + nbytesdecoded += (nprbytes & 0x03) - 1; + + return nbytesdecoded; + +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_base64_decode( + char *bufplain, + const char *bufcoded) +{ + int len; + len = axutil_base64_decode_binary((unsigned char *)bufplain, bufcoded); + bufplain[len] = '\0'; + return len; +} + +/* This is the same as axutil_base64_decode() except on EBCDIC machines, where + * the conversion of the output to ebcdic is left out. + */ + +AXIS2_EXTERN int AXIS2_CALL +axutil_base64_decode_binary( + unsigned char *bufplain, + const char *bufcoded) +{ + int nbytesdecoded; + register const unsigned char *bufin; + register unsigned char *bufout; + register int nprbytes; + + if(!bufcoded) + { + return -1; + } + + bufin = (const unsigned char *)bufcoded; + while(pr2six[*(bufin++)] <= 63) + ; + nprbytes = (int)(bufin - (const unsigned char *)bufcoded) - 1; + /* We are sure that the difference lies within the int range */ + nbytesdecoded = ((nprbytes + 3) / 4) * 3; + + bufout = (unsigned char *)bufplain; + bufin = (const unsigned char *)bufcoded; + + while(nprbytes > 4) + { + *(bufout++) = (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); + *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); + *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); + bufin += 4; + nprbytes -= 4; + } + + /* Note: (nprbytes == 1) would be an error, so just ingore that case */ + if(nprbytes > 1) + { + *(bufout++) = (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); + } + if(nprbytes > 2) + { + *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); + } + if(nprbytes > 3) + { + *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); + } + + nbytesdecoded -= (4 - nprbytes) & 3; + return nbytesdecoded; +} + +static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +AXIS2_EXTERN int AXIS2_CALL +axutil_base64_encode_len( + int len) +{ + return ((len + 2) / 3 * 4) + 1; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_base64_encode( + char *encoded, + const char *string, + int len) +{ +#ifndef __OS400__ + return axutil_base64_encode_binary(encoded, (const unsigned char *)string, len); +#else /* __OS400__ */ + int i; + char *p; + + p = encoded; + for (i = 0; i < len - 2; i += 3) + { + *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; + *p++ = + basis_64[((os_toascii[string[i]] & 0x3) << 4) | + ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; + *p++ = + basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) | + ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)]; + *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F]; + } + if (i < len) + { + *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; + if (i == (len - 1)) + { + *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)]; + *p++ = '='; + } + else + { + *p++ = + basis_64[((os_toascii[string[i]] & 0x3) << 4) | + ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; + *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)]; + } + *p++ = '='; + } + + *p++ = '\0'; + return p - encoded; +#endif /* __OS400__ */ +} + +/* This is the same as axutil_base64_encode() except on EBCDIC machines, where + * the conversion of the input to ascii is left out. + */ +AXIS2_EXTERN int AXIS2_CALL +axutil_base64_encode_binary( + char *encoded, + const unsigned char *string, + int len) +{ + int i; + char *p; + + p = encoded; + for(i = 0; i < len - 2; i += 3) + { + *p++ = basis_64[(string[i] >> 2) & 0x3F]; + *p++ = basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)]; + *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int)(string[i + 2] & 0xC0) >> 6)]; + *p++ = basis_64[string[i + 2] & 0x3F]; + } + if(i < len) + { + *p++ = basis_64[(string[i] >> 2) & 0x3F]; + if(i == (len - 1)) + { + *p++ = basis_64[((string[i] & 0x3) << 4)]; + *p++ = '='; + } + else + { + *p++ = basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)]; + *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; + } + *p++ = '='; + } + + *p++ = '\0'; + return (int)(p - encoded); + /* We are sure that the difference lies within the int range */ +} diff --git a/util/src/base64_binary.c b/util/src/base64_binary.c new file mode 100644 index 0000000..2d3ff87 --- /dev/null +++ b/util/src/base64_binary.c @@ -0,0 +1,258 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_base64_binary.h> +#include <string.h> +#include <axutil_utils.h> + +struct axutil_base64_binary +{ + unsigned char *plain_binary; + int plain_binary_len; +}; + +AXIS2_EXTERN axutil_base64_binary_t *AXIS2_CALL +axutil_base64_binary_create( + const axutil_env_t * env) +{ + axutil_base64_binary_t *base64_binary = NULL; + AXIS2_ENV_CHECK(env, NULL); + + base64_binary = (axutil_base64_binary_t *)AXIS2_MALLOC(env->allocator, + sizeof(axutil_base64_binary_t)); + + if(!base64_binary) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + base64_binary->plain_binary = NULL; + base64_binary->plain_binary_len = 0; + return base64_binary; +} + +AXIS2_EXTERN axutil_base64_binary_t *AXIS2_CALL +axutil_base64_binary_create_with_plain_binary( + const axutil_env_t * env, + const unsigned char *plain_binary, + int plain_binary_len) +{ + axutil_base64_binary_t *base64_binary = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, plain_binary, NULL); + + base64_binary = (axutil_base64_binary_t *)axutil_base64_binary_create(env); + if(!base64_binary) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + base64_binary->plain_binary = AXIS2_MALLOC(env->allocator, sizeof(unsigned char) + * plain_binary_len); + + if(!base64_binary->plain_binary) + { + axutil_base64_binary_free(base64_binary, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + memcpy(base64_binary->plain_binary, plain_binary, plain_binary_len); + base64_binary->plain_binary_len = plain_binary_len; + + return base64_binary; +} + +AXIS2_EXTERN axutil_base64_binary_t *AXIS2_CALL +axutil_base64_binary_create_with_encoded_binary( + const axutil_env_t * env, + const char *encoded_binary) +{ + axutil_base64_binary_t *base64_binary = NULL; + int plain_binary_len = 0; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, encoded_binary, NULL); + + base64_binary = (axutil_base64_binary_t *)axutil_base64_binary_create(env); + if(!base64_binary) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + plain_binary_len = axutil_base64_decode_len(encoded_binary); + base64_binary->plain_binary = AXIS2_MALLOC(env->allocator, sizeof(unsigned char) + * plain_binary_len); + + if(!base64_binary->plain_binary) + { + axutil_base64_binary_free(base64_binary, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + axutil_base64_decode_binary(base64_binary->plain_binary, encoded_binary); + base64_binary->plain_binary_len = plain_binary_len; + + return base64_binary; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_base64_binary_free( + axutil_base64_binary_t *base64_binary, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!base64_binary) + { + return; + } + + if(base64_binary->plain_binary) + { + AXIS2_FREE(env->allocator, base64_binary->plain_binary); + } + + if(base64_binary) + { + AXIS2_FREE(env->allocator, base64_binary); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_base64_binary_set_plain_binary( + axutil_base64_binary_t *base64_binary, + const axutil_env_t *env, + const unsigned char *plain_binary, + int plain_binary_len) +{ + + AXIS2_PARAM_CHECK(env->error, plain_binary, AXIS2_FAILURE); + + base64_binary->plain_binary = AXIS2_MALLOC(env->allocator, sizeof(unsigned char) + * plain_binary_len); + if(!base64_binary->plain_binary) + { + axutil_base64_binary_free(base64_binary, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return AXIS2_FAILURE; + } + memcpy(base64_binary->plain_binary, plain_binary, plain_binary_len); + base64_binary->plain_binary_len = plain_binary_len; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN unsigned char *AXIS2_CALL +axutil_base64_binary_get_plain_binary( + axutil_base64_binary_t *base64_binary, + const axutil_env_t *env, + int *plain_binary_len) +{ + AXIS2_PARAM_CHECK(env->error, base64_binary, NULL); + *plain_binary_len = base64_binary->plain_binary_len; + return base64_binary->plain_binary; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_base64_binary_set_encoded_binary( + axutil_base64_binary_t *base64_binary, + const axutil_env_t *env, + const char *encoded_binary) +{ + int plain_binary_len = 0; + + AXIS2_PARAM_CHECK(env->error, base64_binary, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, encoded_binary, AXIS2_FAILURE); + + plain_binary_len = axutil_base64_decode_len(encoded_binary); + base64_binary->plain_binary = AXIS2_MALLOC(env->allocator, sizeof(unsigned char) + * plain_binary_len); + + if(!base64_binary->plain_binary) + { + axutil_base64_binary_free(base64_binary, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return AXIS2_FAILURE; + } + axutil_base64_decode_binary(base64_binary->plain_binary, encoded_binary); + base64_binary->plain_binary_len = plain_binary_len; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN char *AXIS2_CALL +axutil_base64_binary_get_encoded_binary( + axutil_base64_binary_t *base64_binary, + const axutil_env_t *env) +{ + char *encoded_binary = NULL; + int encoded_binary_len = 0; + AXIS2_PARAM_CHECK(env->error, base64_binary, NULL); + + encoded_binary_len = axutil_base64_encode_len(base64_binary->plain_binary_len); + encoded_binary = AXIS2_MALLOC(env->allocator, sizeof(char) * encoded_binary_len); + + if(!encoded_binary) + { + axutil_base64_binary_free(base64_binary, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + axutil_base64_encode_binary(encoded_binary, base64_binary->plain_binary, + base64_binary->plain_binary_len); + return encoded_binary; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_base64_binary_get_encoded_binary_len( + axutil_base64_binary_t *base64_binary, + const axutil_env_t *env) +{ + int encoded_binary_len = 0; + if(!base64_binary) + { + return 0; + } + + encoded_binary_len = axutil_base64_encode_len(base64_binary->plain_binary_len); + return encoded_binary_len; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_base64_binary_get_decoded_binary_len( + axutil_base64_binary_t *base64_binary, + const axutil_env_t *env) +{ + if(!base64_binary) + { + return 0; + } + return base64_binary->plain_binary_len; +} diff --git a/util/src/class_loader.c b/util/src/class_loader.c new file mode 100644 index 0000000..ea3be7d --- /dev/null +++ b/util/src/class_loader.c @@ -0,0 +1,189 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_class_loader.h> + +axis2_status_t +axutil_class_loader_load_lib( + const axutil_env_t *env, + axutil_dll_desc_t *dll_desc); + +axis2_status_t +axutil_class_loader_unload_lib( + const axutil_env_t *env, + axutil_dll_desc_t *dll_desc); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_class_loader_init( + const axutil_env_t *env) +{ + AXIS2_PLATFORM_LOADLIBINIT(); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_class_loader_delete_dll( + const axutil_env_t *env, + axutil_dll_desc_t *dll_desc) +{ + if(!dll_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DLL_CREATE_FAILED, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + axutil_class_loader_unload_lib(env, dll_desc); + AXIS2_PLATFORM_LOADLIBEXIT(); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_class_loader_create_dll( + const axutil_env_t *env, + axutil_param_t *impl_info_param) +{ + void *obj = NULL; + CREATE_FUNCT create_funct = NULL; + DELETE_FUNCT delete_funct = NULL; + AXIS2_DLHANDLER dl_handler = NULL; + axutil_dll_desc_t *dll_desc = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_error_codes_t error_code = AXIS2_ERROR_NONE; + + dll_desc = axutil_param_get_value(impl_info_param, env); + if(!dll_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DLL_CREATE_FAILED, AXIS2_FAILURE); + return NULL; + } + dl_handler = axutil_dll_desc_get_dl_handler(dll_desc, env); + if(!dl_handler) + { + status = axutil_class_loader_load_lib(env, dll_desc); + if(AXIS2_SUCCESS != status) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DLL_CREATE_FAILED, AXIS2_FAILURE); + return NULL; + } + dl_handler = axutil_dll_desc_get_dl_handler(dll_desc, env); + if(!dl_handler) + { + return NULL; + } + + create_funct = (CREATE_FUNCT)AXIS2_PLATFORM_GETPROCADDR(dl_handler, AXIS2_CREATE_FUNCTION); + if(!create_funct) + { + return NULL; + } + status = axutil_dll_desc_set_create_funct(dll_desc, env, create_funct); + if(AXIS2_FAILURE == status) + { + axutil_class_loader_unload_lib(env, dll_desc); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DLL_CREATE_FAILED, AXIS2_FAILURE); + return NULL; + } + + delete_funct = (DELETE_FUNCT)AXIS2_PLATFORM_GETPROCADDR(dl_handler, AXIS2_DELETE_FUNCTION); + if(!delete_funct) + { + return NULL; + } + status = axutil_dll_desc_set_delete_funct(dll_desc, env, delete_funct); + if(AXIS2_FAILURE == status) + { + axutil_class_loader_unload_lib(env, dll_desc); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DLL_CREATE_FAILED, AXIS2_FAILURE); + return NULL; + } + } + create_funct = axutil_dll_desc_get_create_funct(dll_desc, env); + if(!create_funct) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_DLL_DESC, AXIS2_FAILURE); + return NULL; + } + error_code = axutil_dll_desc_get_error_code(dll_desc, env); + + create_funct(&obj, env); + if(!obj) + { + axutil_class_loader_unload_lib(env, dll_desc); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Object create function returned NULL"); + AXIS2_ERROR_SET(env->error, error_code, AXIS2_FAILURE); + return NULL; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s shared lib loaded successfully", + axutil_dll_desc_get_name(dll_desc, env)); + } + + return obj; +} + +axis2_status_t +axutil_class_loader_load_lib( + const axutil_env_t * env, + axutil_dll_desc_t * dll_desc) +{ + axis2_char_t *dll_name = NULL; + AXIS2_DLHANDLER dl_handler = NULL; + axis2_status_t status = AXIS2_FAILURE; + + dll_name = axutil_dll_desc_get_name(dll_desc, env); + dl_handler = AXIS2_PLATFORM_LOADLIB(dll_name); + if(!dl_handler) + { +#ifndef WIN32 + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Loading shared library %s Failed. DLERROR IS %s", + dll_name, AXIS2_PLATFORM_LOADLIB_ERROR); +#else + axis2_char_t buff[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_error(buff, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Loading shared library %s Failed. DLERROR IS %s", + dll_name, buff); +#endif + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DLL_LOADING_FAILED, AXIS2_FAILURE); + + return AXIS2_FAILURE; + } + status = axutil_dll_desc_set_dl_handler(dll_desc, env, dl_handler); + + if(AXIS2_SUCCESS != status) + { + AXIS2_PLATFORM_UNLOADLIB(dl_handler); + dl_handler = NULL; + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DLL_LOADING_FAILED, AXIS2_FAILURE); + return status; + } + + return AXIS2_SUCCESS; +} + +axis2_status_t +axutil_class_loader_unload_lib( + const axutil_env_t * env, + axutil_dll_desc_t * dll_desc) +{ + AXIS2_DLHANDLER dl_handler = axutil_dll_desc_get_dl_handler(dll_desc, env); + if(dl_handler) + { + AXIS2_PLATFORM_UNLOADLIB(dl_handler); + } + + return AXIS2_SUCCESS; +} diff --git a/util/src/date_time.c b/util/src/date_time.c new file mode 100644 index 0000000..ad15774 --- /dev/null +++ b/util/src/date_time.c @@ -0,0 +1,1034 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_date_time.h> +#include <stdio.h> +#include <time.h> +#include <stdlib.h> +#include <axutil_error.h> +#include <axutil_utils.h> +#include <axutil_date_time_util.h> + +struct axutil_date_time +{ + int year; + int mon; + int day; + int hour; + int min; + float sec; + axis2_bool_t tz_pos; + int tz_hour; + int tz_min; +}; + +AXIS2_EXTERN axutil_date_time_t *AXIS2_CALL +axutil_date_time_create_with_offset( + const axutil_env_t *env, + int offset) +{ + axutil_date_time_t *date_time = NULL; + time_t t; + struct tm *utc_time = NULL; + AXIS2_ENV_CHECK(env, NULL); + + date_time = (axutil_date_time_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_date_time_t)); + + if(!date_time) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + t = time(NULL) + offset; + + utc_time = gmtime(&t); + + date_time->year = utc_time->tm_year; + date_time->mon = utc_time->tm_mon; + date_time->day = utc_time->tm_mday; + date_time->hour = utc_time->tm_hour; + date_time->min = utc_time->tm_min; + date_time->sec = (float)utc_time->tm_sec; + date_time->sec += (float)axutil_get_milliseconds(env) / 1000; + date_time->tz_hour = 0; + date_time->tz_min = 0; + date_time->tz_pos = AXIS2_TRUE; + + return date_time; +} + +AXIS2_EXTERN axutil_date_time_t *AXIS2_CALL +axutil_date_time_create( + const axutil_env_t *env) +{ + return axutil_date_time_create_with_offset(env, 0); +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_date_time_free( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(date_time) + { + AXIS2_FREE(env->allocator, date_time); + } + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_date_time_deserialize_time( + axutil_date_time_t *date_time, + const axutil_env_t *env, + const axis2_char_t *time_str) +{ + int hour; + int min; + float sec; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + sscanf(time_str, "%d:%d:%fZ", &hour, &min, &sec); + if(hour < 0 || hour > 23) + { + return AXIS2_FAILURE; + } + if(min < 0 || min > 59) + { + return AXIS2_FAILURE; + } + if(sec < 0 || sec >= 60) + { + return AXIS2_FAILURE; + } + date_time->hour = hour; + date_time->min = min; + date_time->sec = sec; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_date_time_deserialize_time_with_time_zone( + axutil_date_time_t *date_time, + const axutil_env_t *env, + const axis2_char_t *time_str) +{ + int hour; + int min; + float sec; + int tz_hour; + int tz_min; + + axis2_bool_t tz_pos = AXIS2_TRUE; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(strchr(time_str, 'Z')) + { + return AXIS2_FAILURE; + } + else if(!strchr(time_str, '+')) + { + tz_pos = AXIS2_FALSE; + } + + if(tz_pos) + { + sscanf(time_str, "%d:%d:%f+%d:%d", &hour, &min, &sec, &tz_hour, &tz_min); + } + else + { + sscanf(time_str, "%d:%d:%f-%d:%d", &hour, &min, &sec, &tz_hour, &tz_min); + } + if(hour < 0 || hour > 23) + { + return AXIS2_FAILURE; + } + if(min < 0 || min > 59) + { + return AXIS2_FAILURE; + } + if(sec < 0 || sec >= 60) + { + return AXIS2_FAILURE; + } + if(tz_hour < 0 || tz_hour > 14) + { + return AXIS2_FAILURE; + } + if(tz_min < 0 || tz_min > 59) + { + return AXIS2_FAILURE; + } + if(tz_hour == 14 && tz_min != 0) + { + return AXIS2_FAILURE; + } + date_time->hour = hour; + date_time->min = min; + date_time->sec = sec; + date_time->tz_pos = tz_pos; + date_time->tz_hour = tz_hour; + date_time->tz_min = tz_min; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_date_time_deserialize_date( + axutil_date_time_t *date_time, + const axutil_env_t *env, + const axis2_char_t *date_str) +{ + int year; + int mon; + int day; + int is_year_neg = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!date_str || *date_str == '+') + { + return AXIS2_FAILURE; + } + if(strchr(date_str,'T')) + { + return AXIS2_FAILURE; + } + if(*date_str == '-') + { + is_year_neg++; + } + sscanf(date_str + is_year_neg, "%d-%d-%d", &year, &mon, &day); + if(is_year_neg) + { + year *= -1; + } + if(mon < 1 || mon > 12) + { + return AXIS2_FAILURE; + } + if(day < 1 || day > 31) + { + return AXIS2_FAILURE; + } + if(day == 31 && (mon == 2 || mon == 4 || mon == 6 || mon == 9 || mon == 11)) + { + return AXIS2_FAILURE; + } + if(day == 30 && mon == 2) + { + return AXIS2_FAILURE; + } + if(day == 29 && mon == 2) + { + if(year % 4 != 0 || year % 400 == 0) + { + return AXIS2_FAILURE; + } + } + date_time->year = year - 1900; + date_time->mon = mon - 1; + date_time->day = day; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_date_time_deserialize_date_time( + axutil_date_time_t *date_time, + const axutil_env_t *env, + const axis2_char_t *date_time_str) +{ + int year; + int mon; + int day; + int hour; + int min; + float sec; + int is_year_neg = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!date_time_str || *date_time_str == '+') + { + return AXIS2_FAILURE; + } + if(*date_time_str == '-') + { + is_year_neg++; + } + sscanf(date_time_str + is_year_neg, "%d-%d-%dT%d:%d:%fZ", &year, &mon, &day, &hour, &min, &sec); + + if(is_year_neg) + { + year *= -1; + } + if(mon < 1 || mon > 12) + { + return AXIS2_FAILURE; + } + if(day < 1 || day > 31) + { + return AXIS2_FAILURE; + } + if(day == 31 && (mon == 2 || mon == 4 || mon == 6 || mon == 9 || mon == 11)) + { + return AXIS2_FAILURE; + } + if(day == 30 && mon == 2) + { + return AXIS2_FAILURE; + } + if(day == 29 && mon == 2) + { + if(year % 4 != 0 || year % 400 == 0) + { + return AXIS2_FAILURE; + } + } + if(hour < 0 || hour > 23) + { + return AXIS2_FAILURE; + } + if(min < 0 || min > 59) + { + return AXIS2_FAILURE; + } + if(sec < 0 || sec >= 60) + { + return AXIS2_FAILURE; + } + date_time->year = year - 1900; + date_time->mon = mon - 1; + date_time->day = day; + date_time->hour = hour; + date_time->min = min; + date_time->sec = sec; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_date_time_deserialize_date_time_with_time_zone( + axutil_date_time_t *date_time, + const axutil_env_t *env, + const axis2_char_t *date_time_str) +{ + int year; + int mon; + int day; + int hour; + int min; + float sec; + int tz_hour; + int tz_min; + int is_year_neg = 0; + axis2_bool_t tz_pos = AXIS2_FALSE; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!date_time_str || *date_time_str == '+') + { + return AXIS2_FAILURE; + } + if(*date_time_str == '-') + { + is_year_neg++; + } + + if(strchr(date_time_str, 'Z')) + { + return AXIS2_FAILURE; + } + else if(strchr(date_time_str, '+')) + { + tz_pos = AXIS2_TRUE; + } + + if(tz_pos) + { + sscanf(date_time_str + is_year_neg, "%d-%d-%dT%d:%d:%f+%d:%d", &year, &mon, &day, &hour, + &min, &sec, &tz_hour, &tz_min); + } + else + { + sscanf(date_time_str + is_year_neg, "%d-%d-%dT%d:%d:%f-%d:%d", &year, &mon, &day, &hour, + &min, &sec, &tz_hour, &tz_min); + } + + if(is_year_neg) + { + year *= -1; + } + if(mon < 1 || mon > 12) + { + return AXIS2_FAILURE; + } + if(day < 1 || day > 31) + { + return AXIS2_FAILURE; + } + if(day == 31 && (mon == 2 || mon == 4 || mon == 6 || mon == 9 || mon == 11)) + { + return AXIS2_FAILURE; + } + if(day == 30 && mon == 2) + { + return AXIS2_FAILURE; + } + if(day == 29 && mon == 2) + { + if(year % 4 != 0 || year % 400 == 0) + { + return AXIS2_FAILURE; + } + } + if(hour < 0 || hour > 23) + { + return AXIS2_FAILURE; + } + if(min < 0 || min > 59) + { + return AXIS2_FAILURE; + } + if(sec < 0 || sec >= 60) + { + return AXIS2_FAILURE; + } + if(tz_hour < 0 || tz_hour > 14) + { + return AXIS2_FAILURE; + } + if(tz_min < 0 || tz_min > 59) + { + return AXIS2_FAILURE; + } + if(tz_hour == 14 && tz_min != 0) + { + return AXIS2_FAILURE; + } + date_time->year = year - 1900; + date_time->mon = mon - 1; + date_time->day = day; + date_time->hour = hour; + date_time->min = min; + date_time->sec = sec; + date_time->tz_pos = tz_pos; + date_time->tz_hour = tz_hour; + date_time->tz_min = tz_min; + return AXIS2_SUCCESS; +} + +/*Check if the @data_time is not expired, compared to @ref*/ +AXIS2_EXTERN axutil_date_time_comp_result_t AXIS2_CALL +axutil_date_time_compare( + axutil_date_time_t *date_time, + const axutil_env_t *env, + axutil_date_time_t *ref) +{ + int dt_min; + int ref_min; + int dt_hour; + int ref_hour; + AXIS2_ENV_CHECK(env, AXIS2_DATE_TIME_COMP_RES_FAILURE); + + if(date_time->year < ref->year) + { + return AXIS2_DATE_TIME_COMP_RES_NOT_EXPIRED; + } + else if(date_time->year > ref->year) + { + return AXIS2_DATE_TIME_COMP_RES_EXPIRED; + } + + if(date_time->mon < ref->mon) + { + return AXIS2_DATE_TIME_COMP_RES_NOT_EXPIRED; + } + else if(date_time->mon > ref->mon) + { + return AXIS2_DATE_TIME_COMP_RES_EXPIRED; + } + + if(date_time->day < ref->day) + { + return AXIS2_DATE_TIME_COMP_RES_NOT_EXPIRED; + } + else if(date_time->day > ref->day) + { + return AXIS2_DATE_TIME_COMP_RES_EXPIRED; + } + + dt_min = date_time->tz_min; + dt_hour = date_time->tz_hour; + ref_min = ref->tz_min; + ref_hour = ref->tz_hour; + if(date_time->tz_pos) + { + dt_min *= -1; + dt_hour *= -1; + } + if(ref->tz_pos) + { + ref_min *= -1; + ref_hour *= -1; + } + + dt_min += date_time->min; + dt_hour += date_time->hour; + ref_min += ref->min; + ref_hour += ref->hour; + + if(dt_hour < ref_hour) + { + return AXIS2_DATE_TIME_COMP_RES_NOT_EXPIRED; + } + else if(dt_hour > ref_hour) + { + return AXIS2_DATE_TIME_COMP_RES_EXPIRED; + } + + if(dt_min < ref_min) + { + return AXIS2_DATE_TIME_COMP_RES_NOT_EXPIRED; + } + else if(dt_min > ref_min) + { + return AXIS2_DATE_TIME_COMP_RES_EXPIRED; + } + + if(date_time->sec < ref->sec) + { + return AXIS2_DATE_TIME_COMP_RES_NOT_EXPIRED; + } + else if(date_time->sec > ref->sec) + { + return AXIS2_DATE_TIME_COMP_RES_EXPIRED; + } + + return AXIS2_DATE_TIME_COMP_RES_EQUAL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_date_time_set_time_zone( + axutil_date_time_t *date_time, + const axutil_env_t *env, + axis2_bool_t is_positive, + int hour, + int min) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(hour < 0 || hour > 14) + { + return AXIS2_FAILURE; + } + if(min < 0 || min > 59) + { + return AXIS2_FAILURE; + } + if(hour == 14 && min != 0) + { + return AXIS2_FAILURE; + } + date_time->tz_pos = is_positive; + date_time->tz_hour = hour; + date_time->tz_min = min; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_date_time_set_date_time( + axutil_date_time_t *date_time, + const axutil_env_t *env, + int year, + int mon, + int day, + int hour, + int min, + int sec, + int msec) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(mon < 1 || mon > 12) + { + return AXIS2_FAILURE; + } + if(day < 1 || day > 31) + { + return AXIS2_FAILURE; + } + if(day == 31 && (mon == 2 || mon == 4 || mon == 6 || mon == 9 || mon == 11)) + { + return AXIS2_FAILURE; + } + if(day == 30 && mon == 2) + { + return AXIS2_FAILURE; + } + if(day == 29 && mon == 2) + { + if(year % 4 != 0 || year % 400 == 0) + { + return AXIS2_FAILURE; + } + } + if(hour < 0 || hour > 23) + { + return AXIS2_FAILURE; + } + if(min < 0 || min > 59) + { + return AXIS2_FAILURE; + } + if(sec < 0 || sec > 59) + { + return AXIS2_FAILURE; + } + if(msec < 0 || msec > 999) + { + return AXIS2_FAILURE; + } + + date_time->year = year - 1900; + date_time->mon = mon - 1; + date_time->day = day; + date_time->hour = hour; + date_time->min = min; + date_time->sec = (float)sec; + date_time->sec += (float)msec / 1000; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_date_time_serialize_time( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + axis2_char_t *time_str = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + time_str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 32); + sprintf(time_str, "%02d:%02d:%06.3fZ", date_time->hour, date_time->min, date_time->sec); + return time_str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_date_time_serialize_time_with_time_zone( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + axis2_char_t *time_str = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + if(!date_time->tz_hour && !date_time->tz_min) + { + return axutil_date_time_serialize_time(date_time, env); + } + + time_str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 37); + sprintf(time_str, "%02d:%02d:%06.3f%c%02d:%02d", date_time->hour, date_time->min, + date_time->sec, date_time->tz_pos ? '+' : '-', date_time->tz_hour, date_time->tz_min); + return time_str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_date_time_serialize_date( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + axis2_char_t *date_str = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + date_str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 32); + + sprintf(date_str, "%d-%02d-%02d", date_time->year + 1900, date_time->mon + 1, date_time->day); + return date_str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_date_time_serialize_date_time( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + axis2_char_t *date_time_str = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + date_time_str = AXIS2_MALLOC(env->allocator, sizeof(char) * 32); + sprintf(date_time_str, "%d-%02d-%02dT%02d:%02d:%06.3fZ", date_time->year + 1900, date_time->mon + + 1, date_time->day, date_time->hour, date_time->min, date_time->sec); + return date_time_str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_date_time_serialize_date_time_without_millisecond( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + axis2_char_t *date_time_str = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + date_time_str = AXIS2_MALLOC(env->allocator, sizeof(char) * 32); + sprintf(date_time_str, "%d-%02d-%02dT%02d:%02d:%02.0fZ", date_time->year + 1900, date_time->mon + + 1, date_time->day, date_time->hour, date_time->min, date_time->sec); + return date_time_str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_date_time_serialize_date_time_with_time_zone( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + axis2_char_t *date_time_str = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + if(!date_time->tz_hour && !date_time->tz_min) + { + return axutil_date_time_serialize_date_time(date_time, env); + } + + date_time_str = AXIS2_MALLOC(env->allocator, sizeof(char) * 37); + sprintf(date_time_str, "%d-%02d-%02dT%02d:%02d:%06.3f%c%02d:%02d", date_time->year + 1900, + date_time->mon + 1, date_time->day, date_time->hour, date_time->min, date_time->sec, + date_time->tz_pos ? '+' : '-', date_time->tz_hour, date_time->tz_min); + return date_time_str; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_year( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return (date_time->year + 1900); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_month( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + return (date_time->mon + 1); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_date( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + return (date_time->day); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_hour( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + return (date_time->hour); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_minute( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + return (date_time->min); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_second( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + return (int)(date_time->sec); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_msec( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + /* Precision is 1/100 of a millisecond */ + float ret = (float)((date_time->sec - (float)((int)date_time->sec)) * 1000.0); + return (int)((ret * 100.0 + 0.5) / 100.0); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_time_zone_hour( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + return (date_time->tz_hour); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_get_time_zone_minute( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + return (date_time->tz_min); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_date_time_is_time_zone_positive( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + return (date_time->tz_pos); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_date_time_is_utc( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + axis2_bool_t is_utc = AXIS2_TRUE; + if(date_time->tz_hour || date_time->tz_min) + { + is_utc = AXIS2_FALSE; + } + return is_utc; +} + +AXIS2_EXTERN axutil_date_time_t *AXIS2_CALL +axutil_date_time_local_to_utc( + axutil_date_time_t *date_time, + const axutil_env_t *env) +{ + int year; + int mon; + int day; + int hour; + int min; + float sec; + int tz_hour; + int tz_min; + axis2_bool_t tz_pos = AXIS2_FALSE; + + axutil_date_time_t *ret = NULL; + + year = date_time->year; + mon = date_time->mon; + day = date_time->day; + hour = date_time->hour; + min = date_time->min; + sec = date_time->sec; + tz_pos = date_time->tz_pos; + tz_hour = date_time->tz_hour; + tz_min = date_time->tz_min; + + if(tz_pos) + { + tz_hour *= -1; + tz_min *= -1; + } + hour += tz_hour; + min += tz_min; + + if(min > 59) + { + hour += min / 60; + min %= 60; + } + while(min < 0) + { + hour--; + min += 60; + } + + if(hour > 23) + { + day += hour / 24; + hour %= 24; + } + while(hour < 0) + { + day--; + hour += 24; + } + + mon--; + while(mon < 0) + { + mon += 12; + year--; + } + while(mon > 11) + { + mon -= 12; + year++; + } + mon++; + + day--; + while(day > 27) + { + if(mon == 2) + { + if(year % 4 != 0 || year % 400 == 0) + { + day -= 28; + mon++; + } + else if(day > 28) + { + day -= 29; + mon++; + } + else + { + break; + } + } + else if(day > 29) + { + if(mon == 4 || mon == 6 || mon == 9 || mon == 11) + { + day -= 30; + } + else if(day > 30) + { + day -= 31; + } + else + { + break; + } + mon++; + } + else + { + break; + } + if(mon > 12) + { + mon = 1; + year++; + } + } + while(day < 0) + { + if(mon == 3) + { + day += 28; + if(year % 4 == 0 || year % 400 != 0) + { + day++; + } + } + if(mon == 5 || mon == 7 || mon == 10 || mon == 12) + { + day += 30; + } + else + { + day += 31; + } + mon--; + if(mon < 1) + { + mon = 12; + year--; + } + } + day++; + + if(mon < 1 || mon > 12) + { + return NULL; + } + if(day < 1 || day > 31) + { + return NULL; + } + if(day == 31 && (mon == 2 || mon == 4 || mon == 6 || mon == 9 || mon == 11)) + { + return NULL; + } + if(day == 30 && mon == 2) + { + return NULL; + } + if(day == 29 && mon == 2) + { + if(year % 4 != 0 || year % 400 == 0) + { + return NULL; + } + } + if(hour < 0 || hour > 23) + { + return NULL; + } + if(min < 0 || min > 59) + { + return NULL; + } + if(sec < 0 || sec >= 60) + { + return NULL; + } + + ret = axutil_date_time_create(env); + ret->year = year - 1900; + ret->mon = mon - 1; + ret->day = day; + ret->hour = hour; + ret->min = min; + ret->sec = sec; + return ret; +} + +AXIS2_EXTERN axutil_date_time_t *AXIS2_CALL +axutil_date_time_utc_to_local( + axutil_date_time_t *date_time_in, + const axutil_env_t *env, + axis2_bool_t is_positive, + int hour, + int min) +{ + axutil_date_time_t *date_time = NULL; + axutil_date_time_t *ret = NULL; + if(date_time_in->tz_hour && date_time_in->tz_min) + { + return NULL; + } + date_time->year = date_time_in->year; + date_time->mon = date_time_in->mon; + date_time->day = date_time_in->day; + date_time->hour = date_time_in->hour; + date_time->min = date_time_in->min; + date_time->sec = date_time_in->sec; + date_time->tz_hour = hour; + date_time->tz_min = min; + + date_time->tz_pos = is_positive ? AXIS2_FALSE : AXIS2_TRUE; + ret = axutil_date_time_local_to_utc(date_time, env); + ret->tz_hour = hour; + ret->tz_min = min; + + ret->tz_pos = is_positive; + + axutil_date_time_free(date_time, env); + return ret; +} diff --git a/util/src/date_time_util.c b/util/src/date_time_util.c new file mode 100644 index 0000000..ec1149c --- /dev/null +++ b/util/src/date_time_util.c @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_date_time_util.h> + +AXIS2_EXTERN int AXIS2_CALL +axutil_get_milliseconds( + const axutil_env_t *env) +{ + return axis2_platform_get_milliseconds(); +} diff --git a/util/src/digest_calc.c b/util/src/digest_calc.c new file mode 100644 index 0000000..f89a902 --- /dev/null +++ b/util/src/digest_calc.c @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_string.h> +#include <axutil_md5.h> +#include <axutil_digest_calc.h> + +void AXIS2_CALL convert_to_hex( + axutil_digest_hash_t bin, + axutil_digest_hash_hex_t hex); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_digest_calc_get_h_a1( + const axutil_env_t *env, + char *algorithm, + char *user_name, + char *realm, + char *password, + char *nonce, + char *cnonce, + axutil_digest_hash_hex_t session_key) +{ + axutil_md5_ctx_t *ctx; + axutil_digest_hash_t ha1; + + ctx = axutil_md5_ctx_create(env); + if(!ctx) + return AXIS2_FAILURE; + axutil_md5_update(ctx, env, user_name, strlen(user_name)); + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, realm, strlen(realm)); + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, password, strlen(password)); + axutil_md5_final(ctx, env, ha1); + axutil_md5_ctx_free(ctx, env); + if(!axutil_strcasecmp(algorithm, "md5-sess")) + { + ctx = axutil_md5_ctx_create(env); + if(!ctx) + return AXIS2_FAILURE; + axutil_md5_update(ctx, env, ha1, AXIS2_DIGEST_HASH_LEN); + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, nonce, strlen(nonce)); + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, cnonce, strlen(cnonce)); + axutil_md5_final(ctx, env, ha1); + axutil_md5_ctx_free(ctx, env); + } + convert_to_hex(ha1, session_key); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_digest_calc_get_response( + const axutil_env_t *env, + axutil_digest_hash_hex_t h_a1, + char *nonce, + char *nonce_count, + char *cnonce, + char *qop, + char *method, + char *digest_uri, + axutil_digest_hash_hex_t h_entity, + axutil_digest_hash_hex_t response) +{ + axutil_md5_ctx_t *ctx; + axutil_digest_hash_t ha2; + axutil_digest_hash_t resp_hash; + axutil_digest_hash_hex_t ha2_hex; + + ctx = axutil_md5_ctx_create(env); + if(!ctx) + return AXIS2_FAILURE; + axutil_md5_update(ctx, env, method, strlen(method)); + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, digest_uri, strlen(digest_uri)); + if(!axutil_strcasecmp(qop, "auth-int")) + { + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, h_entity, AXIS2_DIGEST_HASH_HEX_LEN); + }; + axutil_md5_final(ctx, env, ha2); + axutil_md5_ctx_free(ctx, env); + convert_to_hex(ha2, ha2_hex); + + ctx = axutil_md5_ctx_create(env); + if(!ctx) + return AXIS2_FAILURE; + axutil_md5_update(ctx, env, h_a1, AXIS2_DIGEST_HASH_HEX_LEN); + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, nonce, strlen(nonce)); + axutil_md5_update(ctx, env, ":", 1); + if(*qop) + { + axutil_md5_update(ctx, env, nonce_count, strlen(nonce_count)); + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, cnonce, strlen(cnonce)); + axutil_md5_update(ctx, env, ":", 1); + axutil_md5_update(ctx, env, qop, strlen(qop)); + axutil_md5_update(ctx, env, ":", 1); + }; + axutil_md5_update(ctx, env, ha2_hex, AXIS2_DIGEST_HASH_HEX_LEN); + axutil_md5_final(ctx, env, resp_hash); + axutil_md5_ctx_free(ctx, env); + convert_to_hex(resp_hash, response); + return AXIS2_SUCCESS; +} + +void AXIS2_CALL convert_to_hex( + axutil_digest_hash_t bin, + axutil_digest_hash_hex_t hex) +{ + unsigned short i; + unsigned char j; + + for (i = 0; i < AXIS2_DIGEST_HASH_LEN; i++) + { + j = (bin[i] >> 4) & 0xf; + if (j <= 9) + hex[i*2] = (j + '0'); + else + hex[i*2] = (j + 'a' - 10); + j = bin[i] & 0xf; + if (j <= 9) + hex[i*2+1] = (j + '0'); + else + hex[i*2+1] = (j + 'a' - 10); + } + hex[AXIS2_DIGEST_HASH_HEX_LEN] = '\0'; +} diff --git a/util/src/dir_handler.c b/util/src/dir_handler.c new file mode 100644 index 0000000..4a5e51e --- /dev/null +++ b/util/src/dir_handler.c @@ -0,0 +1,371 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_dir_handler.h> +#include <axutil_file.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <axutil_string.h> +#ifndef S_ISDIR +# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) +#endif + +#ifdef AXIS2_ARCHIVE_ENABLED +#include <minizip/axis2_archive_extract.h> +#endif + + +extern int AXIS2_ALPHASORT( + ); +#ifdef IS_MACOSX +int dir_select( + struct dirent *entry); +int file_select( + struct dirent *entry); +#else +int dir_select( + const struct dirent *entry); +int file_select( + const struct dirent *entry); +#endif + +/** + * List the dll files in the given service or module folder path + * @param pathname path to your service or module directory + * @return array list of dll file names + */ +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axutil_dir_handler_list_services_or_modules_in_dir( + const axutil_env_t *env, + const axis2_char_t *pathname) +{ + axutil_array_list_t *file_list = NULL; + struct stat *buf = NULL; + int count = 1; + int i = 0; + struct dirent **files = NULL; + /*int file_select( + );*/ + /* Removed un-wanted redefinition leading to warnings on + * Windows. If this is the desired behaviour, please look + * into the file_select function definition below and comment + * out the code if neccessary. + */ + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_ENV_CHECK(env, NULL); + file_list = axutil_array_list_create(env, 100); + count = AXIS2_SCANDIR(pathname, &files, file_select, AXIS2_ALPHASORT); + /* If no files found, make a non-selectable menu item */ + if(count <= 0) + { + axutil_array_list_free(file_list, env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "No files in the path %s.", pathname); + return NULL; + } + + for(i = 1; i < (count + 1); ++i) + { + axis2_char_t *fname = NULL; + axutil_file_t *arch_file = NULL; + axis2_char_t *path = NULL; + axis2_char_t *temp_path = NULL; + + fname = files[i - 1]->d_name; + arch_file = (axutil_file_t *)axutil_file_create(env); + if(!arch_file) + { + int size = 0; + int j = 0; + axutil_file_t *del_file = NULL; + + size = axutil_array_list_size(file_list, env); + for(j = 0; j < size; j++) + { + del_file = axutil_array_list_get(file_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(file_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + axutil_file_set_name(arch_file, env, fname); + temp_path = axutil_stracat(env, pathname, AXIS2_PATH_SEP_STR); + path = axutil_stracat(env, temp_path, fname); + AXIS2_FREE(env->allocator, temp_path); + if(!path) + { + int size = 0; + int j = 0; + axutil_file_t *del_file = NULL; + + axutil_file_free(arch_file, env); + size = axutil_array_list_size(file_list, env); + for(j = 0; j < size; j++) + { + del_file = axutil_array_list_get(file_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(file_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + axutil_file_set_path(arch_file, env, path); + buf = AXIS2_MALLOC(env->allocator, sizeof(struct stat)); + if(!buf) + { + int size = 0; + int j = 0; + axutil_file_t *del_file = NULL; + + AXIS2_FREE(env->allocator, path); + axutil_file_free(arch_file, env); + size = axutil_array_list_size(file_list, env); + for(j = 0; j < size; j++) + { + del_file = axutil_array_list_get(file_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(file_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + stat(path, buf); + axutil_file_set_timestamp(arch_file, env, (time_t)buf->st_ctime); + status = axutil_array_list_add(file_list, env, arch_file); + if(AXIS2_SUCCESS != status) + { + int size = 0; + int j = 0; + axutil_file_t *del_file = NULL; + + axutil_file_free(arch_file, env); + AXIS2_FREE(env->allocator, path); + AXIS2_FREE(env->allocator, buf); + size = axutil_array_list_size(file_list, env); + for(j = 0; j < size; j++) + { + del_file = axutil_array_list_get(file_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(file_list, env); + return NULL; + } + AXIS2_FREE(env->allocator, path); + AXIS2_FREE(env->allocator, buf); + + } + return file_list; +} + +/** + * List services or modules directories in the services or modules folder + * respectively + * @param pathname path your modules or services folder + * @return array list of contents of services or modules folder + */ +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axutil_dir_handler_list_service_or_module_dirs( + const axutil_env_t *env, + const axis2_char_t *pathname) +{ + axutil_array_list_t *file_list = NULL; + struct stat *buf = NULL; + int count = 1; + int i = 0; + struct dirent **files = NULL; + char cwd[500]; + int chdir_result = 0; + + /**FIXME: + * This magic number 500 was selected as a temporary solution. It has to be + * replaced with dynamic memory allocation. This will be done once the use of + * errno after getwcd() on Windows is figured out. + */ + + axis2_status_t status = AXIS2_FAILURE; + AXIS2_ENV_CHECK(env, NULL); + file_list = axutil_array_list_create(env, 0); + if(!AXIS2_GETCWD(cwd, 500)) + exit(1); + + /* pathname is path of services directory or modules directory. */ + chdir_result = AXIS2_CHDIR(pathname); +#ifdef AXIS2_ARCHIVE_ENABLED + axis2_archive_extract(); +#endif + + count = AXIS2_SCANDIR(pathname, &files, dir_select, AXIS2_ALPHASORT); + chdir_result = AXIS2_CHDIR(cwd); + + /* If no files found, make a non-selectable menu item */ + if(count <= 0) + { + axutil_array_list_free(file_list, env); + AXIS2_LOG_INFO(env->log, "No files in the path %s.", pathname); + return NULL; + } + + for(i = 1; i < (count + 1); ++i) + { + axis2_char_t *fname = NULL; + axutil_file_t *arch_file = NULL; + axis2_char_t *path = NULL; + axis2_char_t *temp_path = NULL; + + fname = files[i - 1]->d_name; + arch_file = (axutil_file_t *)axutil_file_create(env); + if(!arch_file) + { + int size = 0; + int j = 0; + axutil_file_t *del_file = NULL; + + size = axutil_array_list_size(file_list, env); + for(j = 0; j < size; j++) + { + del_file = axutil_array_list_get(file_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(file_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + axutil_file_set_name(arch_file, env, fname); + temp_path = axutil_stracat(env, pathname, AXIS2_PATH_SEP_STR); + path = axutil_stracat(env, temp_path, fname); + if(!path) + { + int size = 0; + int j = 0; + axutil_file_t *del_file = NULL; + + axutil_file_free(arch_file, env); + size = axutil_array_list_size(file_list, env); + for(j = 0; j < size; j++) + { + del_file = axutil_array_list_get(file_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(file_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + axutil_file_set_path(arch_file, env, path); + AXIS2_FREE(env->allocator, temp_path); + buf = AXIS2_MALLOC(env->allocator, sizeof(struct stat)); + if(!buf) + { + int size = 0; + int j = 0; + axutil_file_t *del_file = NULL; + + axutil_file_free(arch_file, env); + AXIS2_FREE(env->allocator, path); + size = axutil_array_list_size(file_list, env); + for(j = 0; j < size; j++) + { + del_file = axutil_array_list_get(file_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(file_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + stat(path, buf); + axutil_file_set_timestamp(arch_file, env, (time_t)buf->st_ctime); + status = axutil_array_list_add(file_list, env, arch_file); + if(AXIS2_SUCCESS != status) + { + int size = 0; + int j = 0; + axutil_file_t *del_file = NULL; + + axutil_file_free(arch_file, env); + AXIS2_FREE(env->allocator, path); + AXIS2_FREE(env->allocator, buf); + size = axutil_array_list_size(file_list, env); + for(j = 0; j < size; j++) + { + del_file = axutil_array_list_get(file_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(file_list, env); + return NULL; + } + AXIS2_FREE(env->allocator, path); + AXIS2_FREE(env->allocator, buf); + } + + for(i = 0; i < count; i++) + { + free(files[i]); + } + free(files); + return file_list; +} + +#ifdef IS_MACOSX + int file_select(struct dirent *entry) +{ +#else + int file_select(const struct dirent *entry) +{ +#endif + /** FIXME: + * This block of code has been sitting here doing nothing. + * I have made the existing logic use this code portion. + * Have no idea about the side-effects of this modification. + * If this code block is not required, we might as well remove + * it. + */ + axis2_char_t *ptr; + + if((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) + return (AXIS2_FALSE); + + /* Check for filename extensions */ + ptr = axutil_rindex(entry->d_name, '.'); + if((ptr) && ((strcmp(ptr, AXIS2_LIB_SUFFIX) == 0))) + { + return (AXIS2_TRUE); + } + else + return (AXIS2_FALSE); +} + +#ifdef IS_MACOSX +int +dir_select( + struct dirent *entry) +#else +int +dir_select( + const struct dirent *entry) +#endif +{ + struct stat stat_p; + + if(-1 == stat(entry->d_name, &stat_p)) + return (AXIS2_FALSE); + + if((entry->d_name[0] == '.') || (!S_ISDIR(stat_p.st_mode))) + { + return (AXIS2_FALSE); + } + + return AXIS2_TRUE; +} diff --git a/util/src/dll_desc.c b/util/src/dll_desc.c new file mode 100644 index 0000000..697caf3 --- /dev/null +++ b/util/src/dll_desc.c @@ -0,0 +1,298 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_dll_desc.h> +#include <axutil_class_loader.h> + +struct axutil_dll_desc +{ + axis2_char_t *dll_name; + axis2_char_t *path_qualified_dll_name; + axis2_dll_type_t dll_type; + int load_options; + AXIS2_DLHANDLER dl_handler; + CREATE_FUNCT create_funct; + DELETE_FUNCT delete_funct; + AXIS2_TIME_T timestamp; + axutil_error_codes_t error_code; + +}; + +AXIS2_EXTERN axutil_dll_desc_t *AXIS2_CALL +axutil_dll_desc_create( + const axutil_env_t *env) +{ + axutil_dll_desc_t *dll_desc = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + dll_desc = (axutil_dll_desc_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_dll_desc_t)); + + if(!dll_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + dll_desc->dll_name = NULL; + dll_desc->path_qualified_dll_name = NULL; + dll_desc->dll_type = 0; + dll_desc->load_options = 0; + dll_desc->dl_handler = NULL; + dll_desc->create_funct = NULL; + dll_desc->delete_funct = NULL; + dll_desc->timestamp = 0; + dll_desc->error_code = AXIS2_ERROR_NONE; + + return dll_desc; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_dll_desc_free( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(dll_desc->dl_handler) + { + axutil_class_loader_delete_dll(env, dll_desc); + } + + if(dll_desc->dll_name) + { + AXIS2_FREE(env->allocator, dll_desc->dll_name); + dll_desc->dll_name = NULL; + } + + if(dll_desc->path_qualified_dll_name) + { + AXIS2_FREE(env->allocator, dll_desc->path_qualified_dll_name); + dll_desc->path_qualified_dll_name = NULL; + } + + if(dll_desc) + { + AXIS2_FREE(env->allocator, dll_desc); + } + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_dll_desc_free_void_arg( + void *dll_desc, + const axutil_env_t *env) +{ + axutil_dll_desc_t *dll_desc_l = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + dll_desc_l = (axutil_dll_desc_t *)dll_desc; + axutil_dll_desc_free(dll_desc_l, env); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_dll_desc_set_name( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + axis2_char_t *name) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); + + if(dll_desc->path_qualified_dll_name) + { + AXIS2_FREE(env->allocator, dll_desc->path_qualified_dll_name); + dll_desc->path_qualified_dll_name = NULL; + } + + dll_desc->path_qualified_dll_name = axutil_strdup(env, name); + if(!dll_desc->path_qualified_dll_name) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_dll_desc_get_name( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + return dll_desc->path_qualified_dll_name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_dll_desc_set_load_options( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + int options) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + dll_desc->load_options = options; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_dll_desc_set_type( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + axis2_dll_type_t type) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + dll_desc->dll_type = type; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_dll_type_t AXIS2_CALL +axutil_dll_desc_get_type( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + return dll_desc->dll_type; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_dll_desc_get_load_options( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + return dll_desc->load_options; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_dll_desc_set_dl_handler( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + AXIS2_DLHANDLER dl_handler) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dl_handler, AXIS2_FAILURE); + + if(dll_desc->dl_handler) + { + AXIS2_FREE(env->allocator, dll_desc->dl_handler); + } + dll_desc->dl_handler = dl_handler; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN AXIS2_DLHANDLER AXIS2_CALL +axutil_dll_desc_get_dl_handler( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + return dll_desc->dl_handler; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_dll_desc_set_create_funct( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + CREATE_FUNCT funct) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + dll_desc->create_funct = funct; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN CREATE_FUNCT AXIS2_CALL +axutil_dll_desc_get_create_funct( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + return dll_desc->create_funct; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_dll_desc_set_delete_funct( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + DELETE_FUNCT funct) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + dll_desc->delete_funct = funct; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN DELETE_FUNCT AXIS2_CALL +axutil_dll_desc_get_delete_funct( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + return dll_desc->delete_funct; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_dll_desc_set_timestamp( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + AXIS2_TIME_T timestamp) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + dll_desc->timestamp = timestamp; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN AXIS2_TIME_T AXIS2_CALL +axutil_dll_desc_get_timestamp( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + return dll_desc->timestamp; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_dll_desc_set_error_code( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + axutil_error_codes_t error_code) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + dll_desc->error_code = error_code; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_error_codes_t AXIS2_CALL +axutil_dll_desc_get_error_code( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env) +{ + return dll_desc->error_code; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_dll_desc_create_platform_specific_dll_name( + axutil_dll_desc_t *dll_desc, + const axutil_env_t *env, + const axis2_char_t *class_name) +{ + axis2_char_t *temp_name = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + temp_name = axutil_stracat(env, AXIS2_LIB_PREFIX, class_name); + dll_desc->dll_name = axutil_stracat(env, temp_name, AXIS2_LIB_SUFFIX); + AXIS2_FREE(env->allocator, temp_name); + return dll_desc->dll_name; +} diff --git a/util/src/duration.c b/util/src/duration.c new file mode 100644 index 0000000..381f025 --- /dev/null +++ b/util/src/duration.c @@ -0,0 +1,576 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <axutil_duration.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <axutil_error.h> +#include <axutil_utils.h> + +struct axutil_duration +{ + axis2_bool_t is_negative; + int years; + int months; + int days; + int hours; + int mins; + double secs; +}; + +AXIS2_EXTERN axutil_duration_t *AXIS2_CALL +axutil_duration_create( + axutil_env_t *env) +{ + return axutil_duration_create_from_values(env, 0, 0, 0, 0, 0, 0, 0.0); +} + +AXIS2_EXTERN axutil_duration_t *AXIS2_CALL +axutil_duration_create_from_values( + const axutil_env_t *env, + axis2_bool_t negative, + int years, + int months, + int days, + int hours, + int minutes, + double seconds) +{ + axutil_duration_t *duration = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + duration = (axutil_duration_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_duration_t)); + if(!duration) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + duration->is_negative = negative; + if(years > -1) + { + duration->years = years; + } + else + { + duration->years = 0; + } + if(months > -1) + { + duration->months = months; + } + else + { + duration->months = 0; + } + if(days > -1) + { + duration->days = days; + } + else + { + duration->days = 0; + } + if(hours > -1) + { + duration->hours = hours; + } + else + { + duration->hours = 0; + } + if(minutes > -1) + { + duration->mins = minutes; + } + else + { + duration->mins = 0; + } + if(seconds >= 0) + { + duration->secs = seconds; + } + else + { + duration->secs = 0.0; + } + return duration; +} + +AXIS2_EXTERN axutil_duration_t *AXIS2_CALL +axutil_duration_create_from_string( + const axutil_env_t *env, + const axis2_char_t *duration_str) +{ + axutil_duration_t *duration = NULL; + + duration = (axutil_duration_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_duration_t)); + if(!duration) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + axutil_duration_deserialize_duration(duration, env, duration_str); + return duration; +} + +/***************************Function implementation****************************/ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_free( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(duration) + { + AXIS2_FREE(env->allocator, duration); + duration = NULL; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_deserialize_duration( + axutil_duration_t *duration, + const axutil_env_t *env, + const axis2_char_t *duration_str) +{ + const axis2_char_t *cur = duration_str; + double num; + int num_type = 0; + unsigned int seq = 0; + const char desig[] = { 'Y', 'M', 'D', 'H', 'M', 'S' }; + + AXIS2_PARAM_CHECK(env->error, duration, AXIS2_FAILURE); + + duration->is_negative = AXIS2_FALSE; + duration->years = duration->months = duration->days = duration->hours = duration->mins = 0; + duration->secs = 0; + + if(!duration_str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + if(*cur == '-') + { + duration->is_negative = 1; + cur++; + } + + if(*cur++ != 'P') + { + duration->is_negative = AXIS2_FALSE; + duration->years = duration->months = duration->days = duration->hours = duration->mins = 0; + duration->secs = 0; + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + if(!*cur) + { + duration->is_negative = AXIS2_FALSE; + duration->years = duration->months = duration->days = duration->hours = duration->mins = 0; + duration->secs = 0; + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + while(*cur) + { + if(seq >= sizeof(desig)) + { + duration->is_negative = AXIS2_FALSE; + duration->years = duration->months = duration->days = duration->hours = duration->mins + = 0; + duration->secs = 0; + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + if(*cur == 'T') + { + if(!(seq > 3)) + { + seq = 3; + cur++; + } + else + { + duration->is_negative = AXIS2_FALSE; + duration->years = duration->months = duration->days = duration->hours + = duration->mins = 0; + duration->secs = 0; + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + num = 0; + + if((*cur < '0') || (*cur > '9')) + num_type = -1; + else + { + num_type = 0; + while((*cur >= '0') && (*cur <= '9')) + { + num = num * 10 + (*cur - '0'); + cur++; + } + } + + if(!num_type && (*cur == '.')) + { + double mult = 1; + cur++; + if((*cur < '0') || (*cur > '9')) + num_type = -1; + else + num_type = 1; + while((*cur >= '0') && (*cur <= '9')) + { + mult /= 10; + num += (*cur - '0') * mult; + cur++; + } + } + + if((num_type == -1) || (*cur == 0)) + { + duration->is_negative = AXIS2_FALSE; + duration->years = duration->months = duration->days = duration->hours = duration->mins + = 0; + duration->secs = 0; + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + while(seq < sizeof(desig)) + { + if(*cur == desig[seq]) + { + num_type = 0; + /*if (seq < (sizeof(desig) - 1)) + { + duration->is_negative = AXIS2_FALSE; + duration->years = duration->months = duration->days = duration->hours = duration->mins = 0; + duration->secs = 0; + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, + AXIS2_FAILURE); + return AXIS2_FAILURE; + }*/ + + switch(seq) + { + case 0: + duration->years = (int)num; + seq++; + break; + case 1: + duration->months = (int)num; + seq++; + break; + case 2: + duration->days = (int)num; + seq++; + break; + case 3: + duration->hours = (int)num; + seq++; + break; + case 4: + duration->mins = (int)num; + seq++; + break; + case 5: + duration->secs = num; + seq++; + break; + } + break; + } + if((++seq == 3) || (seq == 6)) + return AXIS2_SUCCESS; + } + cur++; + } + return AXIS2_SUCCESS; + +} + +AXIS2_EXTERN char *AXIS2_CALL +axutil_duration_serialize_duration( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + axis2_char_t *duration_str = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + duration_str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 64); + + if(duration->is_negative == 0) + sprintf(duration_str, "P%dY%dM%dDT%dH%dM%fS", duration->years, duration->months, + duration->days, duration->hours, duration->mins, duration->secs); + else + sprintf(duration_str, "-P%dY%dM%dDT%dH%dM%fS", duration->years, duration->months, + duration->days, duration->hours, duration->mins, duration->secs); + + return duration_str; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_set_duration( + axutil_duration_t *duration, + const axutil_env_t *env, + axis2_bool_t negative, + int years, + int months, + int days, + int hours, + int mins, + double seconds) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(years > -1) + duration->years = years; + if(months > -1) + duration->months = months; + if(days > -1) + duration->days = days; + if(hours > -1) + duration->hours = hours; + if(mins > -1) + duration->mins = mins; + if(seconds >= 0) + duration->secs = seconds; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_duration_get_years( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return duration->years; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_set_years( + axutil_duration_t *duration, + const axutil_env_t *env, + int years) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(years > -1) + { + duration->years = years; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_duration_get_months( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return duration->months; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_set_months( + axutil_duration_t *duration, + const axutil_env_t *env, + int months) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(months > -1) + { + duration->months = months; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_duration_get_days( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return duration->days; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_set_days( + axutil_duration_t *duration, + const axutil_env_t *env, + int days) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(days > -1) + { + duration->days = days; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_duration_get_hours( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return duration->hours; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_set_hours( + axutil_duration_t *duration, + const axutil_env_t *env, + int hours) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(hours > -1) + { + duration->hours = hours; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_duration_get_mins( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return duration->mins; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_set_mins( + axutil_duration_t *duration, + const axutil_env_t *env, + int mins) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(mins > -1) + { + duration->mins = mins; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN double AXIS2_CALL +axutil_duration_get_seconds( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return duration->secs; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_set_seconds( + axutil_duration_t *duration, + const axutil_env_t *env, + double seconds) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(seconds >= 0) + { + duration->secs = seconds; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_duration_get_is_negative( + axutil_duration_t *duration, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return duration->is_negative; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_duration_set_is_negative( + axutil_duration_t *duration, + const axutil_env_t *env, + axis2_bool_t is_negative) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + duration->is_negative = is_negative; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_duration_compare( + axutil_duration_t *duration_one, + axutil_duration_t *duration_two, + axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + + if(!duration_one || !duration_two) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + return AXIS2_FALSE; + } + + if(duration_one->is_negative != duration_two->is_negative) + return AXIS2_FALSE; + if(duration_one->years != duration_two->years) + return AXIS2_FALSE; + if(duration_one->months != duration_two->months) + return AXIS2_FALSE; + if(duration_one->days != duration_two->days) + return AXIS2_FALSE; + if(duration_one->hours != duration_two->hours) + return AXIS2_FALSE; + if(duration_one->mins != duration_two->mins) + return AXIS2_FALSE; + if(duration_one->secs != duration_two->secs) + return AXIS2_FALSE; + return AXIS2_SUCCESS; +} + diff --git a/util/src/env.c b/util/src/env.c new file mode 100644 index 0000000..38b89d3 --- /dev/null +++ b/util/src/env.c @@ -0,0 +1,305 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <string.h> +#include <axutil_env.h> +#include <axutil_error_default.h> +#include <axutil_log_default.h> +#include <axutil_string.h> + +AXIS2_EXTERN axutil_env_t *AXIS2_CALL +axutil_env_create( + axutil_allocator_t *allocator) +{ + axutil_env_t *env; + + if(!allocator) + return NULL; + + env = (axutil_env_t *)AXIS2_MALLOC(allocator, sizeof(axutil_env_t)); + + if(!env) + return NULL; + + memset(env, 0, sizeof(axutil_env_t)); + + env->allocator = allocator; + + env->log = axutil_log_create_default(allocator); + env->log->level = AXIS2_LOG_LEVEL_DEBUG; /* default log level is debug */ + env->log_enabled = AXIS2_TRUE; + + /* Create default error struct */ + env->error = axutil_error_create(allocator); + if(!env->error) + { + AXIS2_FREE(allocator, env); + return NULL; + } + + /* Call error init to fill in the axutil_error_messages array. + This array holds the error messages with respect to error codes */ + axutil_error_init(); + + env->ref = 1; + env->get_session_fn = NULL; + env->set_session_fn = NULL; + + return env; +} + +AXIS2_EXTERN axutil_env_t *AXIS2_CALL +axutil_env_create_with_error_log( + axutil_allocator_t *allocator, + axutil_error_t *error, + axutil_log_t *log) +{ + axutil_env_t *env; + if(!allocator || !error) + return NULL; + + env = (axutil_env_t *)AXIS2_MALLOC(allocator, sizeof(axutil_env_t)); + + if(!env) + return NULL; + + memset(env, 0, sizeof(axutil_env_t)); + + env->allocator = allocator; + env->error = error; + env->log = log; + + if(env->log) + env->log_enabled = AXIS2_TRUE; + else + env->log_enabled = AXIS2_FALSE; + + axutil_error_init(); + + env->ref = 1; + env->get_session_fn = NULL; + env->set_session_fn = NULL; + + return env; +} + +AXIS2_EXTERN axutil_env_t *AXIS2_CALL +axutil_env_create_with_error( + axutil_allocator_t *allocator, + axutil_error_t *error) +{ + return axutil_env_create_with_error_log(allocator, error, NULL); +} + +AXIS2_EXTERN axutil_env_t *AXIS2_CALL +axutil_env_create_with_error_log_thread_pool( + axutil_allocator_t *allocator, + axutil_error_t *error, + axutil_log_t *log, + axutil_thread_pool_t *pool) +{ + axutil_env_t *env; + if(!allocator || !error || !pool) + return NULL; + + env = (axutil_env_t *)AXIS2_MALLOC(allocator, sizeof(axutil_env_t)); + + if(!env) + return NULL; + + memset(env, 0, sizeof(axutil_env_t)); + + env->allocator = allocator; + env->error = error; + env->log = log; + + env->thread_pool = pool; + + if(env->log) + env->log_enabled = AXIS2_TRUE; + else + env->log_enabled = AXIS2_FALSE; + + axutil_error_init(); + + env->ref = 1; + env->get_session_fn = NULL; + env->set_session_fn = NULL; + + return env; +} + +AXIS2_EXTERN axutil_env_t *AXIS2_CALL +axutil_env_create_all( + const axis2_char_t *log_file, + const axutil_log_levels_t log_level) +{ + axutil_env_t *env = NULL; + axutil_error_t *error = NULL; + axutil_log_t *log = NULL; + axutil_allocator_t *allocator = NULL; + axutil_thread_pool_t *thread_pool = NULL; + + allocator = axutil_allocator_init(NULL); + error = axutil_error_create(allocator); + + if(log_file) + { + log = axutil_log_create(allocator, NULL, log_file); + } + + /* if log file name was not given or the log could not be create with + given name, create default log */ + if(!log) + { + log = axutil_log_create_default(allocator); + } + + thread_pool = axutil_thread_pool_init(allocator); + + env = axutil_env_create_with_error_log_thread_pool(allocator, error, log, thread_pool); + if(env->log) + { + if(AXIS2_LOG_LEVEL_CRITICAL <= log_level && log_level <= AXIS2_LOG_LEVEL_TRACE) + { + env->log->level = log_level; + } + else + { + env->log->level = AXIS2_LOG_LEVEL_DEBUG; /* default log level is debug */ + } + } + + env->ref = 1; + env->get_session_fn = NULL; + env->set_session_fn = NULL; + + return env; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_env_check_status( + const axutil_env_t *env) +{ + if(env && env->error) + return AXIS2_ERROR_GET_STATUS_CODE(env->error); + + return AXIS2_CRITICAL_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_env_enable_log( + axutil_env_t *env, + axis2_bool_t enable) +{ + if(env) + { + env->log_enabled = enable; + return AXIS2_SUCCESS; + } + + return AXIS2_CRITICAL_FAILURE; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_env_free( + axutil_env_t *env) +{ + axutil_allocator_t *allocator = NULL; + + if(!env) + return; + + if(--(env->ref) > 0) + { + return; + } + + allocator = env->allocator; + + if(env->log) + { + AXIS2_LOG_FREE(env->allocator, env->log); + } + + if(env->error) + { + AXIS2_ERROR_FREE(env->error); + } + + if(env->thread_pool) + { + axutil_thread_pool_free(env->thread_pool); + } + + if(env->allocator) + { + AXIS2_FREE(env->allocator, env); + } + + if(allocator) + { + AXIS2_FREE(allocator, allocator); + } + + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_env_free_masked( + axutil_env_t *env, + char mask) +{ + if(!env) + return; + + if(--(env->ref) > 0) + { + return; + } + + if(mask & AXIS_ENV_FREE_LOG) + { + AXIS2_LOG_FREE(env->allocator, env->log); + } + + if(mask & AXIS_ENV_FREE_ERROR) + { + AXIS2_ERROR_FREE(env->error); + } + + if(mask & AXIS_ENV_FREE_THREADPOOL) + { + axutil_thread_pool_free(env->thread_pool); + } + + if(env) + AXIS2_FREE(env->allocator, env); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_env_increment_ref( + axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + env->ref++; + return AXIS2_SUCCESS; +} + diff --git a/util/src/error.c b/util/src/error.c new file mode 100644 index 0000000..bb35d96 --- /dev/null +++ b/util/src/error.c @@ -0,0 +1,565 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <string.h> +#include "axutil_error_default.h" + +#define AXIS2_ERROR_MESSAGE_ARRAY_SIZE AXUTIL_ERROR_MAX + +/** + * Array to hold error messages corresponding to the pre-defined error codes. + * Note that array has capacity for additional error messages. These are + * reserved for modules. + * + * TODO: We have to review and change the following definition and also + * need to come up with a reserve strategy for module error code blocks. + * + * In writing a module following steps must be followed in extending Axis2/C + * errors + * 1. Declare and register the start of error messages for the new + * module. + * 2. New module can use up to 1000 messages for its errors. + * 3. In axis2c documentation an entry about new modules error range must + * be inserted so that another new module can know about the already + * occupied spaces. + */ + +AXIS2_EXPORT const axis2_char_t* axutil_error_messages[AXIS2_ERROR_MESSAGE_ARRAY_SIZE]; + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_error_init() +{ + int i = 0; + for(i = 0; i < AXIS2_ERROR_MESSAGE_ARRAY_SIZE; i++) + { + axutil_error_messages[i] = "Unknown Error :("; + } + + /* Common Errors */ + axutil_error_messages[AXIS2_ERROR_NONE] = "No Error"; + axutil_error_messages[AXIS2_ERROR_NO_MEMORY] = "Out of memory"; + axutil_error_messages[AXIS2_ERROR_INVALID_NULL_PARAM] + = "NULL parameter was passed when a non NULL parameter was expected"; + /* core:addr */ + + /* core:clientapi */ + axutil_error_messages[AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE] + = "Blocking invocation expects response"; + axutil_error_messages[AXIS2_ERROR_CANNOT_INFER_TRANSPORT] = "Cannot infer transport from URL"; + axutil_error_messages[AXIS2_ERROR_CLIENT_SIDE_SUPPORT_ONLY_ONE_CONF_CTX] + = "Client side support only one configuration context"; + axutil_error_messages[AXIS2_ERROR_MEP_CANNOT_BE_NULL_IN_MEP_CLIENT] + = "MEP cannot be NULL in MEP client"; + axutil_error_messages[AXIS2_ERROR_MEP_MISMATCH_IN_MEP_CLIENT] = "MEP mismatch"; + axutil_error_messages[AXIS2_ERROR_TWO_WAY_CHANNEL_NEEDS_ADDRESSING] + = "Two way channel needs addressing module to be engaged"; + axutil_error_messages[AXIS2_ERROR_UNKNOWN_TRANSPORT] = "Unknown transport"; + axutil_error_messages[AXIS2_ERROR_UNSUPPORTED_TYPE] = "Type is not supported"; + axutil_error_messages[AXIS2_ERROR_OPTIONS_OBJECT_IS_NOT_SET] = "Options object is not set"; + axutil_error_messages[AXIS2_ERROR_SESSION_TIMEOUT] = "Session Timeout"; + /* core:clientapi:diclient */ + + /* core:context */ + axutil_error_messages[AXIS2_ERROR_INVALID_SOAP_ENVELOPE_STATE] = "Invalid SOAP envelope state"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_MSG_CTX] = "Invalid message context state"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_SVC] = "Service accessed has invalid state"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_SVC_GRP] + = "Service group accessed has invalid state"; + axutil_error_messages[AXIS2_ERROR_SERVICE_NOT_YET_FOUND] = "Service not yet found"; + /* core:deployment */ + axutil_error_messages[AXI2_ERROR_INVALID_PHASE] = "Invalid phase found in phase validation*"; + axutil_error_messages[AXIS2_ERROR_CONFIG_NOT_FOUND] = "Configuration file cannot be found"; + axutil_error_messages[AXIS2_ERROR_DATA_ELEMENT_IS_NULL] = "Data element of the OM Node is NULL"; + axutil_error_messages[AXIS2_ERROR_IN_FLOW_NOT_ALLOWED_IN_TRS_OUT] + = "In transport sender, Inflow is not allowed"; + axutil_error_messages[AXIS2_ERROR_INVALID_HANDLER_STATE] = "Invalid handler state"; + axutil_error_messages[AXIS2_ERROR_INVALID_MODUELE_REF] = "Invalid module reference encountered"; + axutil_error_messages[AXIS2_ERROR_INVALID_MODUELE_REF_BY_OP] + = "Invalid module referenced by operation"; + axutil_error_messages[AXIS2_ERROR_INVALID_MODULE_CONF] = "Invalid module configuration"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_DESC_BUILDER] + = "Description builder is found to be in invalid state"; + axutil_error_messages[AXIS2_ERROR_MODULE_NOT_FOUND] = "Module not found"; + axutil_error_messages[AXIS2_ERROR_MODULE_VALIDATION_FAILED] = "Module validation failed"; + axutil_error_messages[AXIS2_ERROR_MODULE_XML_NOT_FOUND_FOR_THE_MODULE] + = "Module XML file is not found in the given path"; + axutil_error_messages[AXIS2_ERROR_NO_DISPATCHER_FOUND] = "No dispatcher found"; + axutil_error_messages[AXIS2_ERROR_OP_NAME_MISSING] = "Operation name is missing"; + axutil_error_messages[AXIS2_ERROR_OUT_FLOW_NOT_ALLOWED_IN_TRS_IN] + = "In transport receiver, outflow is not allowed"; + axutil_error_messages[AXIS2_ERROR_REPO_CAN_NOT_BE_NULL] = "Repository name cannot be NULL"; + axutil_error_messages[AXIS2_ERROR_REPOSITORY_NOT_EXIST] = "Repository in path does not exist"; + axutil_error_messages[AXIS2_ERROR_REPOS_LISTENER_INIT_FAILED] + = "Repository listener initialization failed"; + axutil_error_messages[AXIS2_ERROR_SERVICE_XML_NOT_FOUND] + = "Service XML file is not found in the given path"; + axutil_error_messages[AXIS2_ERROR_SVC_NAME_ERROR] = "Service name error"; + axutil_error_messages[AXIS2_ERROR_TRANSPORT_SENDER_ERROR] = "Transport sender error"; + axutil_error_messages[AXIS2_PATH_TO_CONFIG_CAN_NOT_BE_NULL] + = "Path to configuration file can not be NULL"; + axutil_error_messages[AXIS2_ERROR_INVALID_SVC] = "Invalid service"; + /* core:description */ + axutil_error_messages[AXIS2_ERROR_CANNOT_CORRELATE_MSG] = "Cannot correlate message"; + axutil_error_messages[AXIS2_ERROR_COULD_NOT_MAP_MEP_URI_TO_MEP_CONSTANT] + = "Could not map the MEP URI to an Axis2/C MEP constant value"; + axutil_error_messages[AXIS2_ERROR_INVALID_MESSAGE_ADDITION] + = "Invalid message addition operation context completed"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_MODULE_DESC] + = "Module description accessed has invalid state"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_PARAM_CONTAINER] + = "Parameter container not set"; + axutil_error_messages[AXIS2_ERROR_MODULE_ALREADY_ENGAGED_TO_OP] + = "Module has already been engaged to the operation"; + axutil_error_messages[AXIS2_ERROR_MODULE_ALREADY_ENGAGED_TO_SVC] + = "Module has already been engaged on the service."; + axutil_error_messages[AXIS2_ERROR_MODULE_ALREADY_ENGAGED_TO_SVC_GRP] + = "Module has already been engaged on the service."; + axutil_error_messages[AXIS2_ERROR_PARAMETER_LOCKED_CANNOT_OVERRIDE] + = "Parameter locked, cannot override"; + axutil_error_messages[AXIS2_ERROR_EMPTY_SCHEMA_LIST] + = "Schema list is empty or NULL in service"; + /* core:engine */ + axutil_error_messages[AXIS2_ERROR_BEFORE_AFTER_HANDLERS_SAME] + = "Both before and after handlers cannot be the same"; + axutil_error_messages[AXIS2_ERROR_INVALID_HANDLER_RULES] = "Invalid handler rules"; + axutil_error_messages[AXIS2_ERROR_INVALID_MODULE] = "Invalid module"; + axutil_error_messages[AXIS2_ERROR_INVALID_PHASE_FIRST_HANDLER] + = "Invalid first handler for phase"; + axutil_error_messages[AXIS2_ERROR_INVALID_PHASE_LAST_HANDLER] + = "Invalid last handler for phase"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_CONF] = "Invalid engine configuration state"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_PROCESSING_FAULT_ALREADY] + = "Message context processing a fault already"; + axutil_error_messages[AXIS2_ERROR_NOWHERE_TO_SEND_FAULT] + = "fault to field not specified in message context"; + axutil_error_messages[AXIS2_ERROR_PHASE_ADD_HANDLER_INVALID] + = "Only one handler allowed for phase, adding another handler is not allowed"; + axutil_error_messages[AXIS2_ERROR_PHASE_FIRST_HANDLER_ALREADY_SET] + = "First handler of phase already set"; + axutil_error_messages[AXIS2_ERROR_PHASE_LAST_HANDLER_ALREADY_SET] + = "Last handler of phase already set"; + axutil_error_messages[AXIS2_ERROR_TWO_SVCS_CANNOT_HAVE_SAME_NAME] + = "Two service can not have same name, a service with same name already"; + /* core:phaseresolver */ + axutil_error_messages[AXIS2_ERROR_INVALID_MODULE_REF] = "Invalid module reference"; + axutil_error_messages[AXIS2_ERROR_INVALID_PHASE] = "Invalid Phase"; + axutil_error_messages[AXIS2_ERROR_NO_TRANSPORT_IN_CONFIGURED] + = "There are no in transport chains configured"; + axutil_error_messages[AXIS2_ERROR_NO_TRANSPORT_OUT_CONFIGURED] + = "There are no out transport chains configured"; + axutil_error_messages[AXIS2_ERROR_PHASE_IS_NOT_SPECIFED] = "Phase is not specified"; + axutil_error_messages[AXIS2_ERROR_SERVICE_MODULE_CAN_NOT_REFER_GLOBAL_PHASE] + = "Service module can not refer global phase"; + /* core:wsdl */ + axutil_error_messages[AXIS2_ERROR_WSDL_SCHEMA_IS_NULL] = "Schema is NULL"; + /* core:receivers */ + axutil_error_messages[AXIS2_ERROR_OM_ELEMENT_INVALID_STATE] = "AXIOM element has invalid state"; + axutil_error_messages[AXIS2_ERROR_OM_ELEMENT_MISMATCH] = "AXIOM elements do not match"; + axutil_error_messages[AXIS2_ERROR_RPC_NEED_MATCHING_CHILD] + = "RPC style SOAP body don't have a child element"; + axutil_error_messages[AXIS2_ERROR_UNKNOWN_STYLE] + = "Operation description has unknown operation style"; + axutil_error_messages[AXIS2_ERROR_STRING_DOES_NOT_REPRESENT_A_VALID_NC_NAME] + = "String does not represent a valid NCName"; + /* core:transport */ + + /* core:transport:http */ + axutil_error_messages[AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR] = "Error occurred in transport"; + axutil_error_messages[AXIS2_ERROR_HTTP_REQUEST_NOT_SENT] + = "A read attempt(HTTP) for the reply without sending the request"; + axutil_error_messages[AXIS2_ERROR_INVALID_HEADER] = "Invalid string passed as a HTTP header"; + axutil_error_messages[AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE] + = "Invalid status line or invalid request line"; + axutil_error_messages[AXIS2_ERROR_INVALID_TRANSPORT_PROTOCOL] + = "Transport protocol is unsupported by axis2"; + axutil_error_messages[AXIS2_ERROR_NULL_BODY] = "No body present in the request or the response"; + axutil_error_messages[AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT] + = "A valid configuration context is required for the HTTP worker"; + axutil_error_messages[AXIS2_ERROR_NULL_HTTP_VERSION] + = "HTTP version cannot be NULL in the status/request line"; + axutil_error_messages[AXIS2_ERROR_NULL_IN_STREAM_IN_MSG_CTX] + = "Input stream is NULL in message context"; + axutil_error_messages[AXIS2_ERROR_NULL_OM_OUTPUT] = "OM output is NULL"; + axutil_error_messages[AXIS2_ERROR_NULL_SOAP_ENVELOPE_IN_MSG_CTX] + = "NULL SOAP envelope in message context"; + axutil_error_messages[AXIS2_ERROR_NULL_STREAM_IN_CHUNKED_STREAM] + = "NULL stream in the HTTP chucked stream"; + axutil_error_messages[AXIS2_ERROR_NULL_STREAM_IN_RESPONSE_BODY] + = "NULL stream in the response body"; + axutil_error_messages[AXIS2_ERROR_NULL_URL] = "URL NULL in HTTP client"; + axutil_error_messages[AXIS2_ERROR_OUT_TRNSPORT_INFO_NULL] + = "Transport information must be set in message context"; + axutil_error_messages[AXIS2_ERROR_RESPONSE_CONTENT_TYPE_MISSING] + = "Content-Type header missing in HTTP response"; + axutil_error_messages[AXIS2_ERROR_RESPONSE_TIMED_OUT] = "Response timed out"; + axutil_error_messages[AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL] + = "SOAP envelope or SOAP body NULL"; + axutil_error_messages[AXIS2_ERROR_SSL_ENGINE] = "Error occurred in SSL engine"; + axutil_error_messages[AXIS2_ERROR_SSL_NO_CA_FILE] = "Cannot find certificates"; + axutil_error_messages[AXIS2_ERROR_WRITING_RESPONSE] + = "Error in writing the response in response writer"; + axutil_error_messages[AXIS2_ERROR_REQD_PARAM_MISSING] + = "Required parameter is missing in URL encoded request"; + axutil_error_messages[AXIS2_ERROR_UNSUPPORTED_SCHEMA_TYPE] = " Unsupported schema type in REST"; + axutil_error_messages[AXIS2_ERROR_SVC_OR_OP_NOT_FOUND] = "Service or operation not found"; + /* mod_addr */ + axutil_error_messages[AXIS2_ERROR_NO_MSG_INFO_HEADERS] = "No messgae info headers"; + /* platforms */ + + /* utils */ + axutil_error_messages[AXIS2_ERROR_COULD_NOT_OPEN_FILE] = "Could not open the file"; + axutil_error_messages[AXIS2_ERROR_DLL_CREATE_FAILED] = "Failed in creating DLL"; + axutil_error_messages[AXIS2_ERROR_DLL_LOADING_FAILED] = "DLL loading failed"; + axutil_error_messages[AXIS2_ERROR_ENVIRONMENT_IS_NULL] = "Environment passed is NULL"; + axutil_error_messages[AXIS2_ERROR_FILE_NAME_NOT_SET] = "Axis2 File does not have a file name"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_DLL_DESC] + = "DLL description has invalid state of not having valid DLL create function, \ + of valid delete function or valid dll_handler"; + axutil_error_messages[AXIS2_ERROR_HANDLER_CREATION_FAILED] = "Failed in creating Handler"; + axutil_error_messages[AXIS2_ERROR_INDEX_OUT_OF_BOUNDS] = "Array list index out of bounds"; + axutil_error_messages[AXIS2_ERROR_INVALID_ADDRESS] = "Invalid IP or hostname"; + axutil_error_messages[AXIS2_ERROR_INVALID_FD] + = "Trying to do operation on invalid file descriptor"; + axutil_error_messages[AXIS2_ERROR_INVALID_SOCKET] + = "Trying to do operation on closed/not opened socket"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_PARAM] = "Parameter not set"; + axutil_error_messages[AXIS2_ERROR_MODULE_CREATION_FAILED] = "Module create failed"; + axutil_error_messages[AXIS2_ERROR_MSG_RECV_CREATION_FAILED] + = "Failed in creating Message Receiver"; + axutil_error_messages[AXIS2_ERROR_NO_SUCH_ELEMENT] = "No such element"; + axutil_error_messages[AXIS2_ERROR_SOCKET_BIND_FAILED] + = "Socket bind failed. Another process may be already using this port"; + axutil_error_messages[AXIS2_ERROR_SOCKET_ERROR] + = "Error creating a socket. Most probably error returned by OS"; + axutil_error_messages[AXIS2_ERROR_SOCKET_LISTEN_FAILED] = "Listen failed for the server socket"; + axutil_error_messages[AXIS2_ERROR_SVC_SKELETON_CREATION_FAILED] + = "Failed in creating Service Skeleton"; + axutil_error_messages[AXIS2_ERROR_TRANSPORT_RECV_CREATION_FAILED] + = "Failed in creating Transport Receiver"; + axutil_error_messages[AXIS2_ERROR_TRANSPORT_SENDER_CREATION_FAILED] + = "Failed in creating Transport Sender"; + axutil_error_messages[AXIS2_ERROR_UUID_GEN_FAILED] + = "Generation of platform dependent UUID failed"; + axutil_error_messages[AXIS2_ERROR_POSSIBLE_DEADLOCK] = "Possible deadlock"; + /* WSDL */ + axutil_error_messages[AXIS2_ERROR_INTERFACE_OR_PORT_TYPE_NOT_FOUND_FOR_THE_BINDING] + = "Interface or Port Type not found for the binding"; + axutil_error_messages[AXIS2_ERROR_INTERFACES_OR_PORTS_NOT_FOUND_FOR_PARTIALLY_BUILT_WOM] + = "Interfaces or Ports not found for the partially built WOM"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_WSDL_OP] + = "WSDL operation accessed has invalid state"; + axutil_error_messages[AXIS2_ERROR_INVALID_STATE_WSDL_SVC] + = "WSDL Service accessed has invalid state"; + axutil_error_messages[AXIS2_ERROR_MEP_CANNOT_DETERMINE_MEP] = "Cannot determine MEP"; + axutil_error_messages[AXIS2_ERROR_WSDL_BINDING_NAME_IS_REQUIRED] + = "WSDL binding name is cannot be NULL"; + axutil_error_messages[AXIS2_ERROR_WSDL_INTERFACE_NAME_IS_REQUIRED] + = "PortType/Interface name cannot be NULL"; + axutil_error_messages[AXIS2_ERROR_WSDL_PARSER_INVALID_STATE] + = "WSDL parsing has resulted in an invalid state"; + axutil_error_messages[AXIS2_ERROR_WSDL_SVC_NAME_IS_REQUIRED] + = "WSDL service name cannot be NULL"; + /* XML */ + + /* XML:attachments */ + axutil_error_messages[AXIS2_ERROR_ATTACHMENT_MISSING] = "Attachment is missing"; + /* XML:om */ + axutil_error_messages[AXIS2_ERROR_BUILDER_DONE_CANNOT_PULL] + = "XML builder done with pulling. Pull parser cannot pull any more"; + axutil_error_messages[AXIS2_ERROR_INVALID_BUILDER_STATE_CANNOT_DISCARD] + = "Discard failed because the builder state is invalid"; + axutil_error_messages[AXIS2_ERROR_INVALID_BUILDER_STATE_LAST_NODE_NULL] + = "Invalid builder state; Builder's last node is NULL"; + axutil_error_messages[AXIS2_ERROR_INVALID_DOCUMENT_STATE_ROOT_NULL] + = "Invalid document state; Document root is NULL"; + axutil_error_messages[AXIS2_ERROR_INVALID_DOCUMENT_STATE_UNDEFINED_NAMESPACE] + = "Undefined namespace used"; + axutil_error_messages[AXIS2_ERROR_INVALID_EMPTY_NAMESPACE_URI] + = "Namespace should have a valid URI"; + axutil_error_messages[AXIS2_ERROR_ITERATOR_NEXT_METHOD_HAS_NOT_YET_BEEN_CALLED] + = "Next method has not been called so cannot remove" + "an element before calling next valid for any om iterator"; + axutil_error_messages[AXIS2_ERROR_ITERATOR_REMOVE_HAS_ALREADY_BEING_CALLED] + = "Document root is NULL, when it is not supposed to be NULL"; + axutil_error_messages[AXIS2_ERROR_XML_READER_ELEMENT_NULL] + = "AXIOM XML reader returned NULL element"; + axutil_error_messages[AXIS2_ERROR_XML_READER_VALUE_NULL] + = "AXIOM XML reader returned NULL value"; + /* XML:parser */ + axutil_error_messages[AXIS2_ERROR_CREATING_XML_STREAM_READER] + = "Error occurred creating XML stream reader"; + axutil_error_messages[AXIS2_ERROR_CREATING_XML_STREAM_WRITER] + = "Error occurred creating XML stream writer"; + axutil_error_messages[AXIS2_ERROR_WRITING_ATTRIBUTE] = "Error in writing attribute"; + axutil_error_messages[AXIS2_ERROR_WRITING_ATTRIBUTE_WITH_NAMESPACE] + = "Error in writing attribute with namespace"; + axutil_error_messages[AXIS2_ERROR_WRITING_ATTRIBUTE_WITH_NAMESPACE_PREFIX] + = "Error in writing attribute with namespace prefix"; + axutil_error_messages[AXIS2_ERROR_WRITING_COMMENT] = "Error in writing comment"; + axutil_error_messages[AXIS2_ERROR_WRITING_DATA_SOURCE] = "Error in writing data source"; + axutil_error_messages[AXIS2_ERROR_WRITING_DEFAULT_NAMESPACE] + = "Error in writing default namespace"; + axutil_error_messages[AXIS2_ERROR_WRITING_DTD] = "Error in writing DDT"; + axutil_error_messages[AXIS2_ERROR_WRITING_EMPTY_ELEMENT] + = "Error occurred in writing empty element"; + axutil_error_messages[AXIS2_ERROR_WRITING_EMPTY_ELEMENT_WITH_NAMESPACE] + = "Error occurred in writing empty element with namespace"; + axutil_error_messages[AXIS2_ERROR_WRITING_EMPTY_ELEMENT_WITH_NAMESPACE_PREFIX] + = "Error in writing empty element with namespace prefix"; + axutil_error_messages[AXIS2_ERROR_WRITING_END_DOCUMENT] + = "Error occurred in writing end document in XML writer"; + axutil_error_messages[AXIS2_ERROR_WRITING_END_ELEMENT] + = "Error occurred in writing end element in XML writer"; + axutil_error_messages[AXIS2_ERROR_WRITING_PROCESSING_INSTRUCTION] + = "Error in writing processing instruction"; + axutil_error_messages[AXIS2_ERROR_WRITING_START_DOCUMENT] + = "Error occurred in writing start element in start document in XML writer"; + axutil_error_messages[AXIS2_ERROR_WRITING_START_ELEMENT] + = "Error occurred in writing start element in XML writer"; + axutil_error_messages[AXIS2_ERROR_WRITING_START_ELEMENT_WITH_NAMESPACE] + = "Error occurred in writing start element with namespace in XML writer"; + axutil_error_messages[AXIS2_ERROR_WRITING_START_ELEMENT_WITH_NAMESPACE_PREFIX] + = "Error occurred in writing start element with namespace prefix"; + axutil_error_messages[AXIS2_ERROR_WRITING_CDATA] = "Error in writing CDATA section"; + axutil_error_messages[AXIS2_ERROR_XML_PARSER_INVALID_MEM_TYPE] + = "AXIS2_XML_PARSER_TYPE_BUFFER or AXIS2_XML_PARSER_TYPE_DOC is expected"; + + /* invalid type passed */ + axutil_error_messages[AXIS2_ERROR_INVALID_BASE_TYPE] = "Invalid base type passed"; + axutil_error_messages[AXIS2_ERROR_INVALID_SOAP_NAMESPACE_URI] + = "Invalid SOAP namespace URI found"; + axutil_error_messages[AXIS2_ERROR_INVALID_SOAP_VERSION] = "Invalid SOAP version"; + axutil_error_messages[AXIS2_ERROR_INVALID_VALUE_FOUND_IN_MUST_UNDERSTAND] + = "Invalid value found in must understand"; + axutil_error_messages[AXIS2_ERROR_MULTIPLE_CODE_ELEMENTS_ENCOUNTERED] + = "Multiple fault code elements encountered in SOAP fault"; + axutil_error_messages[AXIS2_ERROR_MULTIPLE_DETAIL_ELEMENTS_ENCOUNTERED] + = "Multiple fault detail elements encountered in SOAP fault"; + axutil_error_messages[AXIS2_ERROR_MULTIPLE_NODE_ELEMENTS_ENCOUNTERED] + = "Multiple fault node elements encountered in SOAP fault"; + axutil_error_messages[AXIS2_ERROR_MULTIPLE_REASON_ELEMENTS_ENCOUNTERED] + = "Multiple fault reason elements encountered in SOAP fault"; + axutil_error_messages[AXIS2_ERROR_MULTIPLE_ROLE_ELEMENTS_ENCOUNTERED] + = "Multiple fault role elements encountered in SOAP fault "; + axutil_error_messages[AXIS2_ERROR_MULTIPLE_SUB_CODE_VALUES_ENCOUNTERED] + = "Multiple fault sub-code value elements encountered"; + axutil_error_messages[AXIS2_ERROR_MULTIPLE_VALUE_ENCOUNTERED_IN_CODE_ELEMENT] + = "Multiple fault value elements encountered"; + axutil_error_messages[AXIS2_ERROR_MUST_UNDERSTAND_SHOULD_BE_1_0_TRUE_FALSE] + = "Must understand attribute should have a value of either true or false"; + axutil_error_messages[AXIS2_ERROR_OM_ELEMENT_EXPECTED] = "AXIOM element is expected"; + axutil_error_messages[AXIS2_ERROR_ONLY_CHARACTERS_ARE_ALLOWED_HERE] + = "Processing SOAP 1.1 fault value element should have only" + "text as its children"; + axutil_error_messages[AXIS2_ERROR_ONLY_ONE_SOAP_FAULT_ALLOWED_IN_BODY] + = "Only one SOAP fault is allowed in SOAP body"; + axutil_error_messages[AXIS2_ERROR_SOAP11_FAULT_ACTOR_SHOULD_NOT_HAVE_CHILD_ELEMENTS] + = "SOAP 1.1 fault actor should not have any child elements"; + axutil_error_messages[AXIS2_ERROR_SOAP_BUILDER_ENVELOPE_CAN_HAVE_ONLY_HEADER_AND_BODY] + = "SOAP builder found a child element other than header or body in envelope" + "element"; + axutil_error_messages[AXIS2_ERROR_SOAP_BUILDER_HEADER_BODY_WRONG_ORDER] + = "SOAP builder encountered body element first and header next"; + axutil_error_messages[AXIS2_ERROR_SOAP_BUILDER_MULTIPLE_BODY_ELEMENTS_ENCOUNTERED] + = "SOAP builder multiple body elements encountered"; + axutil_error_messages[AXIS2_ERROR_SOAP_BUILDER_MULTIPLE_HEADERS_ENCOUNTERED] + = "SOAP builder encountered multiple headers"; + axutil_error_messages[AXIS2_ERROR_SOAP_FAULT_CODE_DOES_NOT_HAVE_A_VALUE] + = "SOAP fault code does not have a value"; + axutil_error_messages[AXIS2_ERROR_SOAP_FAULT_REASON_ELEMENT_SHOULD_HAVE_A_TEXT] + = "SOAP fault reason element should have a text value"; + axutil_error_messages[AXIS2_ERROR_SOAP_FAULT_ROLE_ELEMENT_SHOULD_HAVE_A_TEXT] + = "SOAP fault role element should have a text value"; + axutil_error_messages[AXIS2_ERROR_SOAP_FAULT_VALUE_SHOULD_BE_PRESENT_BEFORE_SUB_CODE] + = "SOAP fault value should be present before sub-code element in SOAP fault code"; + axutil_error_messages[AXIS2_ERROR_SOAP_MESSAGE_DOES_NOT_CONTAIN_AN_ENVELOPE] + = "SOAP message does not contain a SOAP envelope element"; + axutil_error_messages[AXIS2_ERROR_SOAP_MESSAGE_FIRST_ELEMENT_MUST_CONTAIN_LOCAL_NAME] + = "SOAP message's first element should have a localname"; + axutil_error_messages[AXIS2_ERROR_THIS_LOCALNAME_IS_NOT_SUPPORTED_INSIDE_THE_REASON_ELEMENT] + = "Localname not supported inside a reason element"; + axutil_error_messages[AXIS2_ERROR_THIS_LOCALNAME_IS_NOT_SUPPORTED_INSIDE_THE_SUB_CODE_ELEMENT] + = "Localname not supported inside the sub-code element"; + axutil_error_messages[AXIS2_ERROR_THIS_LOCALNAME_NOT_SUPPORTED_INSIDE_THE_CODE_ELEMENT] + = "Localname not supported inside the code element"; + axutil_error_messages[AXIS2_ERROR_TRANSPORT_LEVEL_INFORMATION_DOES_NOT_MATCH_WITH_SOAP] + = "Transport identified SOAP version does not match with SOAP message version"; + axutil_error_messages[AXIS2_ERROR_UNSUPPORTED_ELEMENT_IN_SOAP_FAULT_ELEMENT] + = "Unsupported element found in SOAP fault element"; + axutil_error_messages[AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED] + = "Wrong element order encountered "; + /* services */ + axutil_error_messages[AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST] + = "Invalid XML format in request"; + axutil_error_messages[AXIS2_ERROR_SVC_SKEL_INPUT_OM_NODE_NULL] + = "Input OM node NULL, Probably error in SOAP request"; + axutil_error_messages[AXIS2_ERROR_SVC_SKEL_INVALID_OPERATION_PARAMETERS_IN_SOAP_REQUEST] + = "Invalid parameters for service operation in SOAP request"; + + axutil_error_messages[AXIS2_ERROR_WSDL_SCHEMA_IS_NULL] = "Schema is NULL"; + + /* repos */ + axutil_error_messages[AXIS2_ERROR_REPOS_NOT_AUTHENTICATED] = "Not authenticated"; + axutil_error_messages[AXIS2_ERROR_REPOS_UNSUPPORTED_MODE] = "Unsupported mode"; + axutil_error_messages[AXIS2_ERROR_REPOS_EXPIRED] = "Expired"; + axutil_error_messages[AXIS2_ERROR_REPOS_NOT_IMPLEMENTED] = "Not implemented"; + axutil_error_messages[AXIS2_ERROR_REPOS_NOT_FOUND] = "Not found"; + axutil_error_messages[AXIS2_ERROR_REPOS_BAD_SEARCH_TEXT] = "Bad search text"; + + /* neethi */ + axutil_error_messages[AXIS2_ERROR_NEETHI_ELEMENT_WITH_NO_NAMESPACE] + = "Element with no namespace"; + axutil_error_messages[AXIS2_ERROR_NEETHI_POLICY_CREATION_FAILED_FROM_ELEMENT] + = "Policy creation failed from element"; + axutil_error_messages[AXIS2_ERROR_NEETHI_ALL_CREATION_FAILED_FROM_ELEMENT] + = "All creation failed from element"; + axutil_error_messages[AXIS2_ERROR_NEETHI_EXACTLYONE_CREATION_FAILED_FROM_ELEMENT] + = "Exactly one creation failed from element"; + axutil_error_messages[AXIS2_ERROR_NEETHI_REFERENCE_CREATION_FAILED_FROM_ELEMENT] + = "Reference creation failed from element"; + axutil_error_messages[AXIS2_ERROR_NEETHI_ASSERTION_CREATION_FAILED_FROM_ELEMENT] + = "Assertion creation failed from element"; + axutil_error_messages[AXIS2_ERROR_NEETHI_ALL_CREATION_FAILED] = "All creation failed"; + axutil_error_messages[AXIS2_ERROR_NEETHI_EXACTLYONE_CREATION_FAILED] + = "Exactly one creation failed"; + axutil_error_messages[AXIS2_ERROR_NEETHI_POLICY_CREATION_FAILED] = "Policy creation failed"; + axutil_error_messages[AXIS2_ERROR_NEETHI_NORMALIZATION_FAILED] = "Normalization failed"; + axutil_error_messages[AXIS2_ERROR_NEETHI_WRONG_INPUT_FOR_MERGE] = "Wrong input for merge"; + axutil_error_messages[AXIS2_ERROR_NEETHI_CROSS_PRODUCT_FAILED] = "Cross product failed"; + axutil_error_messages[AXIS2_ERROR_NEETHI_NO_CHILDREN_POLICY_COMPONENTS] + = "No children policy components"; + axutil_error_messages[AXIS2_ERROR_NEETHI_URI_NOT_SPECIFIED] = "Reference URI not specified"; + axutil_error_messages[AXIS2_ERROR_NEETHI_NO_ENTRY_FOR_THE_GIVEN_URI] + = "No entry for the given URI"; + axutil_error_messages[AXIS2_ERROR_NEETHI_EXACTLYONE_NOT_FOUND_IN_NORMALIZED_POLICY] + = "Exactly one not found in normalized policy"; + axutil_error_messages[AXIS2_ERROR_NEETHI_EXACTLYONE_IS_EMPTY] = "Exactly one is empty"; + axutil_error_messages[AXIS2_ERROR_NEETHI_ALL_NOT_FOUND_WHILE_GETTING_CROSS_PRODUCT] + = "All not found while getting cross product"; + axutil_error_messages[AXIS2_ERROR_NEETHI_UNKNOWN_ASSERTION] = "Unknown Assertion"; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_error_t *AXIS2_CALL +axutil_error_create( + axutil_allocator_t * allocator) +{ + axutil_error_t *error; + if(!allocator) + return NULL; + + error = (axutil_error_t *)AXIS2_MALLOC(allocator, sizeof(axutil_error_t)); + memset(error, 0, sizeof(axutil_error_t)); + + if(!error) + return NULL; + + error->allocator = allocator; + error->status_code = AXIS2_SUCCESS; + + return error; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axutil_error_get_message( + const axutil_error_t * error) +{ + const axis2_char_t *message = NULL; + if(error) + { + if(error->error_number > AXIS2_ERROR_NONE && error->error_number < AXUTIL_ERROR_MAX) /* TODO; This needs to be + fixed to include module defined and user defined errors */ + message = axutil_error_messages[error->error_number]; + else + { + if(error->message) + { + message = error->message; + } + else if(error->error_number == AXIS2_ERROR_NONE) + { + message = axutil_error_messages[AXIS2_ERROR_NONE]; + } + else + { + message = "Undefined error returned by business logic implementation"; + } + } + } + + return message; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_error_set_error_number( + axutil_error_t * error, + axutil_error_codes_t error_number) +{ + if(!error) + return AXIS2_FAILURE; + error->error_number = error_number; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_error_set_status_code( + axutil_error_t * error, + axis2_status_codes_t status_code) +{ + if(!error) + return AXIS2_FAILURE; + error->status_code = status_code; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_error_get_status_code( + axutil_error_t * error) +{ + if(error) + return error->status_code; + else + return AXIS2_CRITICAL_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_error_set_error_message( + axutil_error_t * error, + axis2_char_t * message) +{ + if(message && error) + { + error->message = message; + return AXIS2_SUCCESS; + } + + return AXIS2_FAILURE; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_error_free( + axutil_error_t * error) +{ + if(error) + { + AXIS2_FREE(error->allocator, error); + } + return; +} + diff --git a/util/src/file.c b/util/src/file.c new file mode 100644 index 0000000..2ecd2d4 --- /dev/null +++ b/util/src/file.c @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_file.h> +#include <axutil_string.h> + +struct axutil_file +{ + axis2_char_t *name; + axis2_char_t *path; + AXIS2_TIME_T timestamp; +}; + +AXIS2_EXTERN axutil_file_t *AXIS2_CALL +axutil_file_create( + const axutil_env_t *env) +{ + axutil_file_t *file = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + file = (axutil_file_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_file_t)); + + if(!file) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + file->name = NULL; + file->path = NULL; + file->timestamp = 0; + + return file; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_file_free( + axutil_file_t *file, + const axutil_env_t *env) +{ + if(file->name) + { + AXIS2_FREE(env->allocator, file->name); + } + + if(file->path) + { + AXIS2_FREE(env->allocator, file->path); + } + + if(file) + { + AXIS2_FREE(env->allocator, file); + } + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_file_set_name( + axutil_file_t *file, + const axutil_env_t *env, + axis2_char_t *name) +{ + AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); + + if(file->name) + { + AXIS2_FREE(env->allocator, file->name); + file->name = NULL; + } + file->name = axutil_strdup(env, name); + if(!file->name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_file_get_name( + axutil_file_t *file, + const axutil_env_t *env) +{ + if(!file->name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_FILE_NAME_NOT_SET, AXIS2_FAILURE); + return NULL; + } + return (file->name); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_file_set_path( + axutil_file_t *file, + const axutil_env_t *env, + axis2_char_t *path) +{ + if(!path) + { + return AXIS2_SUCCESS; + } + + if(file->path) + { + AXIS2_FREE(env->allocator, file->path); + file->path = NULL; + } + file->path = axutil_strdup(env, path); + if(!(file->path)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_file_get_path( + axutil_file_t *file, + const axutil_env_t *env) +{ + if(!(file->path)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_FILE_NAME_NOT_SET, AXIS2_FAILURE); + return NULL; + } + + return (file->path); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_file_set_timestamp( + axutil_file_t *file, + const axutil_env_t *env, + AXIS2_TIME_T timestamp) +{ + file->timestamp = timestamp; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN AXIS2_TIME_T AXIS2_CALL +axutil_file_get_timestamp( + axutil_file_t *file, + const axutil_env_t *env) +{ + return file->timestamp; +} + +AXIS2_EXTERN axutil_file_t *AXIS2_CALL +axutil_file_clone( + axutil_file_t *file, + const axutil_env_t *env) +{ + axutil_file_t *new_file = NULL; + axis2_status_t status = AXIS2_FAILURE; + new_file = axutil_file_create(env); + status = axutil_file_set_name(new_file, env, file->name); + if(AXIS2_SUCCESS != status) + { + return NULL; + } + status = axutil_file_set_path(new_file, env, file->path); + if(AXIS2_SUCCESS != status) + { + return NULL; + } + axutil_file_set_timestamp(new_file, env, file->timestamp); + return new_file; +} + diff --git a/util/src/file_handler.c b/util/src/file_handler.c new file mode 100644 index 0000000..61064c1 --- /dev/null +++ b/util/src/file_handler.c @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <sys/stat.h> + +#include <axutil_file_handler.h> + +AXIS2_EXTERN void *AXIS2_CALL +axutil_file_handler_open( + const axis2_char_t *file_name, + const axis2_char_t *options) +{ + FILE *file_ptr; + + if(!file_name) + return NULL; + + if(!options) + return NULL; + + file_ptr = fopen(file_name, options); + return file_ptr; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_file_handler_close( + void *file_ptr) +{ + int status = 0; + + if(!file_ptr) + return AXIS2_FAILURE; + + status = fclose(file_ptr); + + /*if successfully closed, it will return 0. otherwise EOF is returned */ + if(status != 0) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_file_handler_access( + const axis2_char_t *path, + int mode) +{ + int i = 0; + axis2_status_t status = AXIS2_FAILURE; + i = AXIS2_ACCESS(path, mode); + if(0 == i) + { + status = AXIS2_SUCCESS; + } + else if(-1 == i) + { + status = AXIS2_FAILURE; + } + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_file_handler_copy( + FILE *from, + FILE *to) +{ + axis2_char_t ch; + + /* It is assumed that source and destination files are accessible and open*/ + while(!feof(from)) + { + ch = (axis2_char_t)fgetc(from); + /* We are sure that the conversion is safe */ + if(ferror(from)) + { + /* Error reading source file */ + return AXIS2_FAILURE; + } + if(!feof(from)) + fputc(ch, to); + if(ferror(to)) + { + /* Error writing destination file */ + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN long AXIS2_CALL +axutil_file_handler_size( + const axis2_char_t * const name) +{ + struct stat stbuf; + if(stat(name, &stbuf) == -1) + { + /* The file could not be accessed */ + return AXIS2_FAILURE; + } + return stbuf.st_size; +} + diff --git a/util/src/generic_obj.c b/util/src/generic_obj.c new file mode 100644 index 0000000..883fcb1 --- /dev/null +++ b/util/src/generic_obj.c @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_generic_obj.h> + +struct axutil_generic_obj +{ + AXIS2_FREE_VOID_ARG free_func; + int type; + void *value; +}; + +AXIS2_EXTERN axutil_generic_obj_t *AXIS2_CALL +axutil_generic_obj_create( + const axutil_env_t *env) +{ + axutil_generic_obj_t *generic_obj = NULL; + AXIS2_ENV_CHECK(env, NULL); + + generic_obj + = (axutil_generic_obj_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_generic_obj_t)); + + if(!generic_obj) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + generic_obj->value = NULL; + generic_obj->free_func = 0; + + return generic_obj; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_generic_obj_free( + axutil_generic_obj_t *generic_obj, + const axutil_env_t *env) +{ + if(generic_obj->value) + { + if(generic_obj->free_func) + { + generic_obj->free_func(generic_obj->value, env); + } + else + { + AXIS2_FREE(env->allocator, generic_obj->value); + } + + } + + if(generic_obj) + { + AXIS2_FREE(env->allocator, generic_obj); + } + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_generic_obj_set_free_func( + axutil_generic_obj_t *generic_obj, + const axutil_env_t *env, + AXIS2_FREE_VOID_ARG free_func) +{ + generic_obj->free_func = free_func; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_generic_obj_set_value( + axutil_generic_obj_t *generic_obj, + const axutil_env_t *env, + void *value) +{ + generic_obj->value = value; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_generic_obj_get_value( + axutil_generic_obj_t *generic_obj, + const axutil_env_t *env) +{ + return generic_obj->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_generic_obj_set_type( + axutil_generic_obj_t *generic_obj, + const axutil_env_t *env, + int type) +{ + generic_obj->type = type; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_generic_obj_get_type( + axutil_generic_obj_t *generic_obj, + const axutil_env_t *env) +{ + return generic_obj->type; +} + diff --git a/util/src/hash.c b/util/src/hash.c new file mode 100644 index 0000000..77cea73 --- /dev/null +++ b/util/src/hash.c @@ -0,0 +1,671 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "axutil_hash.h" + +#include <axutil_string.h> +#include <axutil_utils.h> + +/* + * The internal form of a hash table. + * + * The table is an array indexed by the hash of the key; collisions + * are resolved by hanging a linked list of hash entries off each + * element of the array. Although this is a really simple design it + * isn't too bad given that environments have a low allocation overhead. + */ + +typedef struct axutil_hash_entry_t axutil_hash_entry_t; + +struct axutil_hash_entry_t +{ + axutil_hash_entry_t *next; + unsigned int hash; + const void *key; + axis2_ssize_t klen; + const void *val; +}; + +/* + * Data structure for iterating through a hash table. + * We keep a pointer to the next hash entry here to allow the current + * hash entry to be freed or otherwise mangled between calls to + * axutil_hash_next(). + */ +struct axutil_hash_index_t +{ + axutil_hash_t *ht; + axutil_hash_entry_t *this, *next; + unsigned int index; +}; + +/* + * The size of the array is always a power of two. We use the maximum + * index rather than the size so that we can use bitwise-AND for + * modular arithmetic. + * The count of hash entries may be greater depending on the chosen + * collision rate. + */ +struct axutil_hash_t +{ + const axutil_env_t *env; + axutil_hash_entry_t **array; + axutil_hash_index_t iterator; /* For axutil_hash_first(NULL, ...) */ + unsigned int count; + unsigned int max; + axutil_hashfunc_t hash_func; + axutil_hash_entry_t *free; /* List of recycled entries */ +}; + +#define INITIAL_MAX 15 /* tunable == 2^n - 1 */ + +/* + * Hash creation functions. + */ + +static axutil_hash_entry_t ** +axutil_hash_alloc_array( + axutil_hash_t *ht, + unsigned int max) +{ + return memset(AXIS2_MALLOC(ht->env->allocator, sizeof(*ht->array) * (max + 1)), 0, + sizeof(*ht->array) * (max + 1)); +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axutil_hash_make( + const axutil_env_t *env) +{ + axutil_hash_t *ht; + AXIS2_ENV_CHECK(env, NULL); + + ht = AXIS2_MALLOC(env->allocator, sizeof(axutil_hash_t)); + if(!ht) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + axutil_env_increment_ref((axutil_env_t*)env); + ht->env = env; + ht->free = NULL; + ht->count = 0; + ht->max = INITIAL_MAX; + ht->array = axutil_hash_alloc_array(ht, ht->max); + ht->hash_func = axutil_hashfunc_default; + return ht; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axutil_hash_make_custom( + const axutil_env_t *env, + axutil_hashfunc_t hash_func) +{ + axutil_hash_t *ht; + AXIS2_ENV_CHECK(env, NULL); + ht = axutil_hash_make(env); + if(ht) + { + ht->hash_func = hash_func; + } + return ht; +} + +/* + * Hash iteration functions. + */ + +AXIS2_EXTERN axutil_hash_index_t *AXIS2_CALL +axutil_hash_next( + const axutil_env_t *env, + axutil_hash_index_t *hi) +{ + hi->this = hi->next; + while(!hi->this) + { + if(hi->index > hi->ht->max) + { + if(env) + AXIS2_FREE(env->allocator, hi); + return NULL; + } + + hi->this = hi->ht->array[hi->index++]; + } + hi->next = hi->this->next; + return hi; +} + +AXIS2_EXTERN axutil_hash_index_t *AXIS2_CALL +axutil_hash_first( + axutil_hash_t *ht, + const axutil_env_t *env) +{ + axutil_hash_index_t *hi; + if(env) + hi = AXIS2_MALLOC(env->allocator, sizeof(*hi)); + else + hi = &ht->iterator; + + hi->ht = ht; + hi->index = 0; + hi->this = NULL; + hi->next = NULL; + return axutil_hash_next(env, hi); +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_hash_this( + axutil_hash_index_t *hi, + const void **key, + axis2_ssize_t *klen, + void **val) +{ + if(key) + *key = hi->this->key; + if(klen) + *klen = hi->this->klen; + if(val) + *val = (void *)hi->this->val; +} + +/* + * Expanding a hash table + */ + +static void +axutil_hash_expand_array( + axutil_hash_t *ht) +{ + axutil_hash_index_t *hi; + + axutil_hash_entry_t **new_array; + unsigned int new_max; + + new_max = ht->max * 2 + 1; + new_array = axutil_hash_alloc_array(ht, new_max); + for(hi = axutil_hash_first(ht, NULL); hi; hi = axutil_hash_next(NULL, hi)) + { + unsigned int i = hi->this->hash & new_max; + hi->this->next = new_array[i]; + new_array[i] = hi->this; + } + AXIS2_FREE(ht->env->allocator, ht->array); + ht->array = new_array; + ht->max = new_max; +} + +unsigned int +axutil_hashfunc_default( + const char *char_key, + axis2_ssize_t *klen) +{ + unsigned int hash = 0; + const unsigned char *key = (const unsigned char *)char_key; + const unsigned char *p; + axis2_ssize_t i; + + /* + * This is the popular `times 33' hash algorithm which is used by + * perl and also appears in Berkeley DB. This is one of the best + * known hash functions for strings because it is both computed + * very fast and distributes very well. + * + * The originator may be Dan Bernstein but the code in Berkeley DB + * cites Chris Torek as the source. The best citation I have found + * is "Chris Torek, Hash function for text in C, Usenet message + * <27038@mimsy.umd.edu> in comp.lang.c , October, 1990." in Rich + * Salz's USENIX 1992 paper about INN which can be found at + * <http://citeseer.nj.nec.com/salz92internetnews.html>. + * + * The magic of number 33, i.e. why it works better than many other + * constants, prime or not, has never been adequately explained by + * anyone. So I try an explanation: if one experimentally tests all + * multipliers between 1 and 256 (as I did while writing a low-level + * data structure library some time ago) one detects that even + * numbers are not useable at all. The remaining 128 odd numbers + * (except for the number 1) work more or less all equally well. + * They all distribute in an acceptable way and this way fill a hash + * table with an average percent of approx. 86%. + * + * If one compares the chi^2 values of the variants (see + * Bob Jenkins ``Hashing Frequently Asked Questions'' at + * http://burtleburtle.net/bob/hash/hashfaq.html for a description + * of chi^2), the number 33 not even has the best value. But the + * number 33 and a few other equally good numbers like 17, 31, 63, + * 127 and 129 have nevertheless a great advantage to the remaining + * numbers in the large set of possible multipliers: their multiply + * op can be replaced by a faster op based on just one + * shift plus either a single addition or subtraction op. And + * because a hash function has to both distribute good _and_ has to + * be very fast to compute, those few numbers should be preferred. + * + * -- Ralf S. Engelschall <rse@engelschall.com> + */ + + if(*klen == AXIS2_HASH_KEY_STRING) + { + for(p = key; *p; p++) + { + hash = hash * 33 + *p; + } + *klen = (axis2_ssize_t)(p - key); + /* We are sure that the difference lies within the axis2_ssize_t range */ + } + else + { + for(p = key, i = *klen; i; i--, p++) + { + hash = hash * 33 + *p; + } + } + + return hash; +} + +/* + * This is where we keep the details of the hash function and control + * the maximum collision rate. + * + * If val is non-NULL it creates and initializes a new hash entry if + * there isn't already one there; it returns an updatable pointer so + * that hash entries can be removed. + */ + +static axutil_hash_entry_t ** +axutil_hash_find_entry( + axutil_hash_t *ht, + const void *key, + axis2_ssize_t klen, + const void *val) +{ + axutil_hash_entry_t **hep, *he; + unsigned int hash; + + hash = ht->hash_func(key, &klen); + + /* scan linked list */ + for(hep = &ht->array[hash & ht->max], he = *hep; he; hep = &he->next, he = *hep) + { + if(he->hash == hash && he->klen == klen && memcmp(he->key, key, klen) == 0) + break; + } + + if(he || !val) + return hep; + + /* add a new entry for non-NULL values */ + he = ht->free; + if(he) + ht->free = he->next; + else + he = AXIS2_MALLOC(ht->env->allocator, sizeof(*he)); + he->next = NULL; + he->hash = hash; + he->key = key; + he->klen = klen; + he->val = val; + *hep = he; + ht->count++; + return hep; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axutil_hash_copy( + const axutil_hash_t *orig, + const axutil_env_t *env) +{ + axutil_hash_t *ht; + axutil_hash_entry_t *new_vals; + unsigned int i, j; + + ht = AXIS2_MALLOC(env->allocator, sizeof(axutil_hash_t) + sizeof(*ht->array) * (orig->max + 1) + + sizeof(axutil_hash_entry_t) * orig->count); + ht->env = env; + axutil_env_increment_ref((axutil_env_t*)env); + ht->free = NULL; + ht->count = orig->count; + ht->max = orig->max; + ht->hash_func = orig->hash_func; + ht->array = (axutil_hash_entry_t **)((char *)ht + sizeof(axutil_hash_t)); + + new_vals = (axutil_hash_entry_t *)((char *)(ht) + sizeof(axutil_hash_t) + sizeof(*ht->array) + * (orig->max + 1)); + j = 0; + for(i = 0; i <= ht->max; i++) + { + axutil_hash_entry_t **new_entry = &(ht->array[i]); + axutil_hash_entry_t *orig_entry = orig->array[i]; + while(orig_entry) + { + *new_entry = &new_vals[j++]; + (*new_entry)->hash = orig_entry->hash; + (*new_entry)->key = orig_entry->key; + (*new_entry)->klen = orig_entry->klen; + (*new_entry)->val = orig_entry->val; + new_entry = &((*new_entry)->next); + orig_entry = orig_entry->next; + } + *new_entry = NULL; + } + return ht; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_hash_get( + axutil_hash_t *ht, + const void *key, + axis2_ssize_t klen) +{ + axutil_hash_entry_t *he; + he = *axutil_hash_find_entry(ht, key, klen, NULL); + if(he) + return (void *)he->val; + else + return NULL; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_hash_set( + axutil_hash_t *ht, + const void *key, + axis2_ssize_t klen, + const void *val) +{ + axutil_hash_entry_t **hep; + hep = axutil_hash_find_entry(ht, key, klen, val); + if(*hep) + { + if(!val) + { + /* delete entry */ + axutil_hash_entry_t *old = *hep; + *hep = (*hep)->next; + old->next = ht->free; + ht->free = old; + --ht->count; + } + else + { + /* replace entry */ + (*hep)->val = val; + /* check that the collision rate isn't too high */ + if(ht->count > ht->max) + { + axutil_hash_expand_array(ht); + } + } + } + /* else key not present and val==NULL */ +} + +AXIS2_EXTERN unsigned int AXIS2_CALL +axutil_hash_count( + axutil_hash_t *ht) +{ + return ht->count; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axutil_hash_overlay( + const axutil_hash_t *overlay, + const axutil_env_t *env, + const axutil_hash_t *base) +{ + return axutil_hash_merge(overlay, env, base, NULL, NULL); +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axutil_hash_merge( + const axutil_hash_t *overlay, + const axutil_env_t *env, + const axutil_hash_t *base, + void * + (*merger)( + const axutil_env_t *env, + const void *key, + axis2_ssize_t klen, + const void *h1_val, + const void *h2_val, + const void *data), + const void *data) +{ + axutil_hash_t *res; + axutil_hash_entry_t *new_vals = NULL; + axutil_hash_entry_t *iter; + axutil_hash_entry_t *ent; + unsigned int i, k; + +#if AXIS2_POOL_DEBUG + /* we don't copy keys and values, so it's necessary that + * overlay->a.env and base->a.env have a life span at least + * as long as p + */ + if (!axutil_env_is_ancestor(overlay->env, p)) + { + fprintf(stderr, + "axutil_hash_merge: overlay's env is not an ancestor of p\n"); + abort(); + } + if (!axutil_env_is_ancestor(base->env, p)) + { + fprintf(stderr, + "axutil_hash_merge: base's env is not an ancestor of p\n"); + abort(); + } +#endif + + res = AXIS2_MALLOC(env->allocator, sizeof(axutil_hash_t)); + res->env = env; + axutil_env_increment_ref((axutil_env_t*)env); + res->free = NULL; + res->hash_func = base->hash_func; + res->count = base->count; + res->max = (overlay->max > base->max) ? overlay->max : base->max; + if(base->count + overlay->count > res->max) + { + res->max = res->max * 2 + 1; + } + res->array = axutil_hash_alloc_array(res, res->max); + for(k = 0; k <= base->max; k++) + { + for(iter = base->array[k]; iter; iter = iter->next) + { + i = iter->hash & res->max; + new_vals = AXIS2_MALLOC(env->allocator, sizeof(axutil_hash_entry_t)); + new_vals->klen = iter->klen; + new_vals->key = iter->key; + new_vals->val = iter->val; + new_vals->hash = iter->hash; + new_vals->next = res->array[i]; + res->array[i] = new_vals; + } + } + + for(k = 0; k <= overlay->max; k++) + { + for(iter = overlay->array[k]; iter; iter = iter->next) + { + i = iter->hash & res->max; + for(ent = res->array[i]; ent; ent = ent->next) + { + if((ent->klen == iter->klen) && (memcmp(ent->key, iter->key, iter->klen) == 0)) + { + if(merger) + { + ent->val = (*merger)(env, iter->key, iter->klen, iter->val, ent->val, data); + } + else + { + ent->val = iter->val; + } + break; + } + } + if(!ent) + { + new_vals = AXIS2_MALLOC(env->allocator, sizeof(axutil_hash_entry_t)); + new_vals->klen = iter->klen; + new_vals->key = iter->key; + new_vals->val = iter->val; + new_vals->hash = iter->hash; + new_vals->next = res->array[i]; + res->array[i] = new_vals; + res->count++; + } + } + } + return res; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_hash_contains_key( + axutil_hash_t *ht, + const axutil_env_t *env, + const axis2_char_t *key) +{ + axutil_hash_index_t *i = NULL; + + for(i = axutil_hash_first(ht, env); i; i = axutil_hash_next(env, i)) + { + const void *v = NULL; + const axis2_char_t *key_l = NULL; + + axutil_hash_this(i, &v, NULL, NULL); + key_l = (const axis2_char_t *)v; + if(0 == axutil_strcmp(key, key_l)) + return AXIS2_TRUE; + } + + return AXIS2_FALSE; +} + +/* + void + axutil_hash_entry_free( + const axutil_env_t *env, + axutil_hash_entry_t *hash_entry) + { + if (!hash_entry) + return; + if (hash_entry->next) + { + axutil_hash_entry_free(env, hash_entry->next); + } + AXIS2_FREE(env->allocator, hash_entry); + return; + } + */ + +AXIS2_EXTERN void AXIS2_CALL +axutil_hash_free( + axutil_hash_t *ht, + const axutil_env_t *env) +{ + unsigned int i = 0; + if(ht) + { + for(i = 0; i <= ht->max; i++) + { + axutil_hash_entry_t *next = NULL; + axutil_hash_entry_t *current = ht->array[i]; + while(current) + { + next = current->next; + AXIS2_FREE(env->allocator, current); + current = NULL; + current = next; + } + } + if(ht->free) + { + axutil_hash_entry_t *next = NULL; + axutil_hash_entry_t *current = ht->free; + while(current) + { + next = current->next; + AXIS2_FREE(env->allocator, current); + current = NULL; + current = next; + } + } + + if(ht->env) + { + /*since we now keep a ref count in env and incrementing it + *inside hash_make we need to free the env.Depending on the + situation the env struct is freed or ref count will be + decremented.*/ + + axutil_free_thread_env((axutil_env_t*)(ht->env)); + ht->env = NULL; + } + + AXIS2_FREE(env->allocator, (ht->array)); + AXIS2_FREE(env->allocator, ht); + } + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_hash_free_void_arg( + void *ht_void, + const axutil_env_t *env) +{ + unsigned int i = 0; + axutil_hash_t *ht = (axutil_hash_t *)ht_void; + if(ht) + { + for(i = 0; i < ht->max; i++) + { + axutil_hash_entry_t *next = NULL; + axutil_hash_entry_t *current = ht->array[i]; + while(current) + { + next = current->next; + AXIS2_FREE(env->allocator, current); + current = next; + } + } + AXIS2_FREE(env->allocator, (ht->array)); + AXIS2_FREE(env->allocator, ht); + } + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_hash_set_env( + axutil_hash_t * ht, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(ht) + { + if(ht->env) + { + /*since we now keep a ref count in env and incrementing it + *inside hash_make we need to free the env.Depending on the + situation the env struct is freed or ref count will be + decremented.*/ + + axutil_free_thread_env((axutil_env_t*)(ht->env)); + ht->env = NULL; + } + ht->env = env; + axutil_env_increment_ref((axutil_env_t*)env); + } +} + diff --git a/util/src/http_chunked_stream.c b/util/src/http_chunked_stream.c new file mode 100644 index 0000000..3a04ca2 --- /dev/null +++ b/util/src/http_chunked_stream.c @@ -0,0 +1,232 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_http_chunked_stream.h> +#include <axutil_string.h> +#include <string.h> +#include <stdlib.h> + +#define AXIS2_HTTP_CRLF "\r\n" + +struct axutil_http_chunked_stream +{ + axutil_stream_t *stream; + int current_chunk_size; + int unread_len; + axis2_bool_t end_of_chunks; + axis2_bool_t chunk_started; +}; + +static axis2_status_t +axutil_http_chunked_stream_start_chunk( + axutil_http_chunked_stream_t * chunked_stream, + const axutil_env_t *env); + +AXIS2_EXTERN axutil_http_chunked_stream_t *AXIS2_CALL +axutil_http_chunked_stream_create( + const axutil_env_t *env, + axutil_stream_t *stream) +{ + axutil_http_chunked_stream_t *chunked_stream = NULL; + AXIS2_PARAM_CHECK(env->error, stream, NULL); + + chunked_stream = (axutil_http_chunked_stream_t *)AXIS2_MALLOC(env->allocator, + sizeof(axutil_http_chunked_stream_t)); + if(!chunked_stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + chunked_stream->stream = stream; + chunked_stream->current_chunk_size = -1; + chunked_stream->unread_len = -1; + chunked_stream->end_of_chunks = AXIS2_FALSE; + chunked_stream->chunk_started = AXIS2_FALSE; + + return chunked_stream; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_http_chunked_stream_free( + axutil_http_chunked_stream_t *chunked_stream, + const axutil_env_t *env) +{ + AXIS2_FREE(env->allocator, chunked_stream); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_http_chunked_stream_read( + axutil_http_chunked_stream_t *chunked_stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + int len = -1; + int yet_to_read = 0; + axutil_stream_t *stream = chunked_stream->stream; + + if(!buffer) + { + return -1; + } + if(!stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_STREAM_IN_CHUNKED_STREAM, AXIS2_FAILURE); + return -1; + } + if(AXIS2_TRUE == chunked_stream->end_of_chunks) + { + return 0; + } + if(AXIS2_FALSE == chunked_stream->chunk_started) + { + axutil_http_chunked_stream_start_chunk(chunked_stream, env); + } + yet_to_read = (int)count; + /* We are sure that the difference lies within the int range */ + while(AXIS2_FALSE == chunked_stream->end_of_chunks && yet_to_read > 0) + { + if(chunked_stream->unread_len < yet_to_read) + { + len = axutil_stream_read(chunked_stream->stream, env, (axis2_char_t *)buffer + count + - yet_to_read, chunked_stream->unread_len); + yet_to_read -= len; + chunked_stream->unread_len -= len; + if(chunked_stream->unread_len <= 0) + { + axutil_http_chunked_stream_start_chunk(chunked_stream, env); + } + } + else + { + len = axutil_stream_read(chunked_stream->stream, env, (axis2_char_t *)buffer + count + - yet_to_read, yet_to_read); + yet_to_read -= len; + chunked_stream->unread_len -= len; + } + } + return ((int)count - yet_to_read); + /* We are sure that the difference lies within the int range */ +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_http_chunked_stream_write( + axutil_http_chunked_stream_t *chunked_stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + axutil_stream_t *stream = chunked_stream->stream; + int len = -1; + axis2_char_t tmp_buf[10]; + + if(!buffer) + { + return -1; + } + if(!stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_STREAM_IN_CHUNKED_STREAM, AXIS2_FAILURE); + return -1; + } + sprintf(tmp_buf, "%x%s", (unsigned int)count, AXIS2_HTTP_CRLF); + axutil_stream_write(stream, env, tmp_buf, axutil_strlen(tmp_buf)); + len = axutil_stream_write(stream, env, buffer, count); + axutil_stream_write(stream, env, AXIS2_HTTP_CRLF, 2); + return len; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_http_chunked_stream_get_current_chunk_size( + const axutil_http_chunked_stream_t *chunked_stream, + const axutil_env_t *env) +{ + return chunked_stream->current_chunk_size; +} + +static axis2_status_t +axutil_http_chunked_stream_start_chunk( + axutil_http_chunked_stream_t *chunked_stream, + const axutil_env_t *env) +{ + axis2_char_t tmp_buf[3] = ""; + axis2_char_t str_chunk_len[512] = ""; + axis2_char_t *tmp = NULL; + int read = -1; + + /* remove the last CRLF of the previous chunk if any */ + if(AXIS2_TRUE == chunked_stream->chunk_started) + { + read = axutil_stream_read(chunked_stream->stream, env, tmp_buf, 2); + chunked_stream->chunk_started = AXIS2_FALSE; + } + /* read the len and chunk extension */ + while((read = axutil_stream_read(chunked_stream->stream, env, tmp_buf, 1)) > 0) + { + tmp_buf[read] = '\0'; + strcat(str_chunk_len, tmp_buf); + if(0 != strstr(str_chunk_len, AXIS2_HTTP_CRLF)) + { + break; + } + } + /* check whether we have extensions */ + tmp = strchr(str_chunk_len, ';'); + if(tmp) + { + /* we don't use extensions right now */ + *tmp = '\0'; + } + chunked_stream->current_chunk_size = strtol(str_chunk_len, NULL, 16); + if(0 == chunked_stream->current_chunk_size) + { + /* Read the last CRLF */ + read = axutil_stream_read(chunked_stream->stream, env, tmp_buf, 2); + chunked_stream->end_of_chunks = AXIS2_TRUE; + } + else + { + chunked_stream->chunk_started = AXIS2_TRUE; + chunked_stream->unread_len = chunked_stream->current_chunk_size; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_http_chunked_stream_write_last_chunk( + axutil_http_chunked_stream_t *chunked_stream, + const axutil_env_t *env) +{ + axutil_stream_t *stream = NULL; + + stream = chunked_stream->stream; + if(axutil_stream_write(stream, env, "0\r\n\r\n", 5) == 5) + { + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_http_chunked_stream_get_end_of_chunks( + axutil_http_chunked_stream_t *chunked_stream, + const axutil_env_t *env) +{ + return chunked_stream->end_of_chunks; +} + diff --git a/util/src/linked_list.c b/util/src/linked_list.c new file mode 100644 index 0000000..7ba83f8 --- /dev/null +++ b/util/src/linked_list.c @@ -0,0 +1,573 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_linked_list.h> +#include <axutil_utils.h> + +struct axutil_linked_list +{ + + /**The number of elements in this list. */ + int size; + + /** + * The first element in the list. + */ + entry_t *first; + + /** + * The last element in the list. + */ + entry_t *last; + + /** + * A count of the number of structural modifications that have been made to + * the list (that is, insertions and removals). Structural modifications + * are ones which change the list size or affect how iterations would + * behave. This field is available for use by Iterator and ListIterator, + * in order to set an error code in response + * to the next op on the iterator. This <i>fail-fast</i> behavior + * saves the user from many subtle bugs otherwise possible from concurrent + * modification during iteration. + * <p> + * + * To make lists fail-fast, increment this field by just 1 in the + * <code>add(int, Object)</code> and <code>remove(int)</code> methods. + * Otherwise, this field may be ignored. + */ + int mod_count; +}; + +AXIS2_EXTERN axutil_linked_list_t *AXIS2_CALL +axutil_linked_list_create( + const axutil_env_t *env) +{ + axutil_linked_list_t *linked_list = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + linked_list = AXIS2_MALLOC(env->allocator, sizeof(axutil_linked_list_t)); + if(!linked_list) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + linked_list->size = 0; + linked_list->mod_count = 0; + linked_list->first = NULL; + linked_list->last = NULL; + + return linked_list; +} + +static entry_t * +axutil_linked_list_create_entry( + const axutil_env_t *env, + void *data) +{ + entry_t *entry = (entry_t *)AXIS2_MALLOC(env->allocator, sizeof(entry_t)); + if(!entry) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + entry->data = data; + entry->previous = NULL; + entry->next = NULL; + return entry; +} + +static axis2_status_t +axutil_linked_list_add_last_entry( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + entry_t * e) +{ + AXIS2_PARAM_CHECK(env->error, e, AXIS2_FAILURE); + + linked_list->mod_count++; + if(linked_list->size == 0) + { + linked_list->first = linked_list->last = e; + } + else + { + e->previous = linked_list->last; + linked_list->last->next = e; + linked_list->last = e; + } + linked_list->size++; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_linked_list_free( + axutil_linked_list_t *linked_list, + const axutil_env_t *env) +{ + entry_t *current = NULL, *next = NULL; + + current = linked_list->first; + while(current) + { + next = current->next; + AXIS2_FREE(env->allocator, current); + current = next; + } + AXIS2_FREE(env->allocator, linked_list); + linked_list = NULL; +} + +AXIS2_EXTERN entry_t *AXIS2_CALL +axutil_linked_list_get_entry( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + int n) +{ + entry_t *e = NULL; + if(n < linked_list->size / 2) + { + e = linked_list->first; + /* n less than size/2, iterate from start */ + while(n > 0) + { + e = e->next; + n = n - 1; + } + } + else + { + e = linked_list->last; + /* n greater than size/2, iterate from end */ + while((n = n + 1) < linked_list->size) + { + e = e->previous; + } + } + + return e; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_linked_list_remove_entry( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + entry_t *e) +{ + AXIS2_PARAM_CHECK(env->error, e, AXIS2_FAILURE); + linked_list->mod_count++; + linked_list->size--; + if(linked_list->size == 0) + { + linked_list->first = linked_list->last = NULL; + } + else + { + if(e == linked_list->first) + { + linked_list->first = e->next; + e->next->previous = NULL; + } + else if(e == linked_list->last) + { + linked_list->last = e->previous; + e->previous->next = NULL; + } + else + { + e->next->previous = e->previous; + e->previous->next = e->next; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_linked_list_check_bounds_inclusive( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + int index) +{ + if(index < 0 || index > linked_list->size) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INDEX_OUT_OF_BOUNDS, AXIS2_FAILURE); + return AXIS2_FALSE; + } + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_linked_list_check_bounds_exclusive( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + int index) +{ + if(index < 0 || index >= linked_list->size) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INDEX_OUT_OF_BOUNDS, AXIS2_FAILURE); + return AXIS2_FALSE; + } + return AXIS2_TRUE; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_linked_list_get_first( + axutil_linked_list_t *linked_list, + const axutil_env_t *env) +{ + if(linked_list->size == 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_SUCH_ELEMENT, AXIS2_FAILURE); + return NULL; + } + + return linked_list->first->data; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_linked_list_get_last( + axutil_linked_list_t *linked_list, + const axutil_env_t *env) +{ + if(linked_list->size == 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_SUCH_ELEMENT, AXIS2_FAILURE); + return NULL; + } + + return linked_list->last->data; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_linked_list_remove_first( + axutil_linked_list_t *linked_list, + const axutil_env_t *env) +{ + void *r; + + if(linked_list->size == 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_SUCH_ELEMENT, AXIS2_FAILURE); + return NULL; + } + + linked_list->mod_count++; + linked_list->size--; + r = linked_list->first->data; + + if(linked_list->first->next) + { + linked_list->first->next->previous = NULL; + } + else + { + linked_list->last = NULL; + } + + linked_list->first = linked_list->first->next; + + return r; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_linked_list_remove_last( + axutil_linked_list_t *linked_list, + const axutil_env_t *env) +{ + void *r = NULL; + + if(linked_list->size == 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_SUCH_ELEMENT, AXIS2_FAILURE); + return NULL; + } + + linked_list->mod_count++; + linked_list->size--; + r = linked_list->last->data; + + if(linked_list->last->previous) + { + linked_list->last->previous->next = NULL; + } + else + { + linked_list->first = NULL; + } + + linked_list->last = linked_list->last->previous; + + return r; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_linked_list_add_first( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + void *o) +{ + entry_t *e; + AXIS2_PARAM_CHECK(env->error, o, AXIS2_FAILURE); + + e = axutil_linked_list_create_entry(env, o); + + linked_list->mod_count++; + if(linked_list->size == 0) + { + linked_list->first = linked_list->last = e; + } + else + { + e->next = linked_list->first; + linked_list->first->previous = e; + linked_list->first = e; + } + linked_list->size++; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_linked_list_add_last( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + void *o) +{ + entry_t *e; + AXIS2_PARAM_CHECK(env->error, o, AXIS2_FAILURE); + + e = axutil_linked_list_create_entry(env, o); + return axutil_linked_list_add_last_entry(linked_list, env, e); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_linked_list_contains( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + void *o) +{ + entry_t *e; + AXIS2_PARAM_CHECK(env->error, o, AXIS2_FALSE); + + e = linked_list->first; + while(e) + { + if(o == e->data) + return AXIS2_TRUE; + e = e->next; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_linked_list_size( + axutil_linked_list_t *linked_list, + const axutil_env_t *env) +{ + return linked_list->size; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_linked_list_add( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + void *o) +{ + entry_t *e; + AXIS2_PARAM_CHECK(env->error, o, AXIS2_FALSE); + e = axutil_linked_list_create_entry(env, o); + return axutil_linked_list_add_last_entry(linked_list, env, e); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_linked_list_remove( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + void *o) +{ + entry_t *e; + AXIS2_PARAM_CHECK(env->error, o, AXIS2_FALSE); + + e = linked_list->first; + while(e) + { + if(o == e->data) + { + return axutil_linked_list_remove_entry(linked_list, env, e); + } + e = e->next; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_linked_list_clear( + axutil_linked_list_t *linked_list, + const axutil_env_t *env) +{ + if(linked_list->size > 0) + { + linked_list->mod_count++; + linked_list->first = NULL; + linked_list->last = NULL; + linked_list->size = 0; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_linked_list_get( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + int index) +{ + axutil_linked_list_check_bounds_exclusive(linked_list, env, index); + return axutil_linked_list_get_entry(linked_list, env, index)->data; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_linked_list_set( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + int index, + void *o) +{ + entry_t *e; + void *old; + AXIS2_PARAM_CHECK(env->error, o, NULL); + axutil_linked_list_check_bounds_exclusive(linked_list, env, index); + e = axutil_linked_list_get_entry(linked_list, env, index); + old = e->data; + e->data = o; + return old; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_linked_list_add_at_index( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + int index, + void *o) +{ + entry_t *after = NULL; + entry_t *e; + AXIS2_PARAM_CHECK(env->error, o, AXIS2_FAILURE); + + axutil_linked_list_check_bounds_inclusive(linked_list, env, index); + e = axutil_linked_list_create_entry(env, o); + + if(index < linked_list->size) + { + linked_list->mod_count++; + after = axutil_linked_list_get_entry(linked_list, env, index); + e->next = after; + e->previous = after->previous; + if(after->previous == NULL) + linked_list->first = e; + else + after->previous->next = e; + after->previous = e; + linked_list->size++; + } + else + { + axutil_linked_list_add_last_entry(linked_list, env, e); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_linked_list_remove_at_index( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + int index) +{ + entry_t *e; + axutil_linked_list_check_bounds_exclusive(linked_list, env, index); + e = axutil_linked_list_get_entry(linked_list, env, index); + axutil_linked_list_remove_entry(linked_list, env, e); + return e->data; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_linked_list_index_of( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + void *o) +{ + int index = 0; + entry_t *e; + AXIS2_PARAM_CHECK(env->error, o, AXIS2_FAILURE); + + e = linked_list->first; + while(e) + { + if(o == e->data) + return index; + index++; + e = e->next; + } + return -1; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_linked_list_last_index_of( + axutil_linked_list_t *linked_list, + const axutil_env_t *env, + void *o) +{ + int index; + entry_t *e; + AXIS2_PARAM_CHECK(env->error, o, AXIS2_FAILURE); + + index = linked_list->size - 1; + e = linked_list->last; + while(e) + { + if(o == e->data) + return index; + index--; + e = e->previous; + } + return -1; +} + +AXIS2_EXTERN void **AXIS2_CALL +axutil_linked_list_to_array( + axutil_linked_list_t *linked_list, + const axutil_env_t *env) +{ + int i = 0; + void **array; + entry_t *e; + array = (void **)AXIS2_MALLOC(env->allocator, linked_list->size * sizeof(void *)); + e = linked_list->first; + for(i = 0; i < linked_list->size; i++) + { + array[i] = e->data; + e = e->next; + } + return array; +} + diff --git a/util/src/log.c b/util/src/log.c new file mode 100644 index 0000000..72a2508 --- /dev/null +++ b/util/src/log.c @@ -0,0 +1,576 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <axutil_log_default.h> +#include <axutil_file_handler.h> +#include <axutil_thread.h> +#include <signal.h> + +typedef struct axutil_log_impl axutil_log_impl_t; + +static axis2_status_t +axutil_log_impl_rotate( + axutil_log_t *log); + +static void AXIS2_CALL axutil_log_impl_write( + axutil_log_t *log, + const axis2_char_t *buffer, + axutil_log_levels_t level, + const axis2_char_t *file, + const int line); + +AXIS2_EXTERN void AXIS2_CALL axutil_log_impl_write_to_file( + axutil_log_t *log, + axutil_thread_mutex_t *mutex, + axutil_log_levels_t level, + const axis2_char_t *file, + const int line, + const axis2_char_t *value); + +static void AXIS2_CALL axutil_log_impl_free( + axutil_allocator_t *allocator, + axutil_log_t *log); + +struct axutil_log_impl +{ + axutil_log_t log; + void *stream; + axis2_char_t *file_name; + axutil_thread_mutex_t *mutex; +}; + +#define AXUTIL_INTF_TO_IMPL(log) ((axutil_log_impl_t*)(log)) + +static const axutil_log_ops_t axutil_log_ops_var = { axutil_log_impl_free, axutil_log_impl_write }; + +static void AXIS2_CALL +axutil_log_impl_free( + axutil_allocator_t *allocator, + axutil_log_t *log) +{ + axutil_log_impl_t *log_impl = NULL; + + if(log) + { + log_impl = AXUTIL_INTF_TO_IMPL(log); + + if(log_impl->mutex) + { + axutil_thread_mutex_destroy(log_impl->mutex); + } + if(log_impl->stream) + { + axutil_file_handler_close(log_impl->stream); + } + if(log_impl->file_name) + { + AXIS2_FREE(allocator, log_impl->file_name); + } + AXIS2_FREE(allocator, log_impl); + } +} + +AXIS2_EXTERN axutil_log_t *AXIS2_CALL +axutil_log_create( + axutil_allocator_t *allocator, + axutil_log_ops_t *ops, + const axis2_char_t *stream_name) +{ + axutil_log_impl_t *log_impl; + axis2_char_t *path_home; + axis2_char_t log_file_name[AXUTIL_LOG_FILE_NAME_SIZE]; + axis2_char_t log_dir[AXUTIL_LOG_FILE_NAME_SIZE]; + axis2_char_t tmp_filename[AXUTIL_LOG_FILE_NAME_SIZE]; + + if(!allocator) + return NULL; + + log_impl = (axutil_log_impl_t *)AXIS2_MALLOC(allocator, sizeof(axutil_log_impl_t)); + + if(!log_impl) + return NULL; + + log_impl->mutex = axutil_thread_mutex_create(allocator, AXIS2_THREAD_MUTEX_DEFAULT); + + if(!log_impl->mutex) + { + fprintf(stderr, "cannot create log mutex \n"); + return NULL; + } + +#ifndef WIN32 + signal(SIGXFSZ, SIG_IGN); +#endif + + /* default log file is axis2.log */ + if(stream_name) + AXIS2_SNPRINTF(tmp_filename, AXUTIL_LOG_FILE_NAME_SIZE, "%s", stream_name); + else + AXIS2_SNPRINTF(tmp_filename, AXUTIL_LOG_FILE_NAME_SIZE, "%s", "axis2.log"); + + /* we write all logs to AXIS2C_HOME/logs if it is set otherwise + * to the working dir + */ + if(stream_name && !(axutil_rindex(stream_name, AXIS2_PATH_SEP_CHAR))) + { + path_home = AXIS2_GETENV("AXIS2C_HOME"); + if(path_home) + { + AXIS2_SNPRINTF(log_dir, AXUTIL_LOG_FILE_NAME_SIZE, "%s%c%s", path_home, + AXIS2_PATH_SEP_CHAR, "logs"); + if(AXIS2_SUCCESS == axutil_file_handler_access(log_dir, AXIS2_F_OK)) + { + AXIS2_SNPRINTF(log_file_name, AXUTIL_LOG_FILE_NAME_SIZE, "%s%c%s", log_dir, + AXIS2_PATH_SEP_CHAR, tmp_filename); + } + else + { + fprintf(stderr, "log folder %s does not exist - log file %s " + "is written to . dir\n", log_dir, tmp_filename); + AXIS2_SNPRINTF(log_file_name, AXUTIL_LOG_FILE_NAME_SIZE, "%s", tmp_filename); + } + } + else + { + fprintf(stderr, "AXIS2C_HOME is not set - log is written to . dir\n"); + AXIS2_SNPRINTF(log_file_name, AXUTIL_LOG_FILE_NAME_SIZE, "%s", tmp_filename); + } + } + else + { + AXIS2_SNPRINTF(log_file_name, AXUTIL_LOG_FILE_NAME_SIZE, "%s", tmp_filename); + } + log_impl->file_name = AXIS2_MALLOC(allocator, AXUTIL_LOG_FILE_NAME_SIZE); + log_impl->log.size = AXUTIL_LOG_FILE_SIZE; + sprintf(log_impl->file_name, "%s", log_file_name); + + axutil_thread_mutex_lock(log_impl->mutex); + + log_impl->stream = axutil_file_handler_open(log_file_name, "a+"); + axutil_log_impl_rotate((axutil_log_t *)log_impl); + + axutil_thread_mutex_unlock(log_impl->mutex); + + if(!log_impl->stream) + log_impl->stream = stderr; + + /* by default, log is enabled */ + log_impl->log.enabled = 1; + log_impl->log.level = AXIS2_LOG_LEVEL_DEBUG; + + if(ops) + { + log_impl->log.ops = ops; + } + else + { + log_impl->log.ops = &axutil_log_ops_var; + } + + return &(log_impl->log); +} + +static void AXIS2_CALL +axutil_log_impl_write( + axutil_log_t *log, + const axis2_char_t *buffer, + axutil_log_levels_t level, + const axis2_char_t *file, + const int line) +{ + if(log && log->enabled && buffer) + { + axutil_log_impl_t *l = AXUTIL_INTF_TO_IMPL(log); + if(!l->mutex) + fprintf(stderr, "Log mutex is not found\n"); + if(!l->stream) + fprintf(stderr, "Stream is not found\n"); + if(level <= log->level || level == AXIS2_LOG_LEVEL_CRITICAL) + { + axutil_log_impl_write_to_file(log, l->mutex, level, file, line, buffer); + } + } +#ifndef AXIS2_NO_LOG_FILE + else if(buffer) + fprintf(stderr, "please check your log and buffer"); +#endif + else + fprintf(stderr, "please check your log and buffer"); +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_write_to_file( + axutil_log_t *log, + axutil_thread_mutex_t *mutex, + axutil_log_levels_t level, + const axis2_char_t *file, + const int line, + const axis2_char_t *value) +{ + const char *level_str = ""; + axutil_log_impl_t *log_impl = AXUTIL_INTF_TO_IMPL(log); + FILE *fd = NULL; + + /** + * print all critical and error logs irrespective of log->level setting + */ + + switch(level) + { + case AXIS2_LOG_LEVEL_CRITICAL: + level_str = "[critical] "; + break; + case AXIS2_LOG_LEVEL_ERROR: + level_str = "[error] "; + break; + case AXIS2_LOG_LEVEL_WARNING: + level_str = "[warning] "; + break; + case AXIS2_LOG_LEVEL_INFO: + level_str = "[info] "; + break; + case AXIS2_LOG_LEVEL_DEBUG: + level_str = "[debug] "; + break; + case AXIS2_LOG_LEVEL_TRACE: + level_str = "[...TRACE...] "; + break; + case AXIS2_LOG_LEVEL_USER: + break; + } + axutil_thread_mutex_lock(mutex); + + axutil_log_impl_rotate(log); + fd = log_impl->stream; + + if(fd) + { + if(file) + fprintf(fd, "[%s] %s%s(%d) %s\n", axutil_log_impl_get_time_str(), level_str, file, + line, value); + else + fprintf(fd, "[%s] %s %s\n", axutil_log_impl_get_time_str(), level_str, value); + fflush(fd); + } + axutil_thread_mutex_unlock(mutex); +} + +static axis2_status_t +axutil_log_impl_rotate( + axutil_log_t *log) +{ + long size = -1; + FILE *old_log_fd = NULL; + axis2_char_t old_log_file_name[AXUTIL_LOG_FILE_NAME_SIZE]; + axutil_log_impl_t *log_impl = AXUTIL_INTF_TO_IMPL(log); + if(log_impl->file_name) + size = axutil_file_handler_size(log_impl->file_name); + + if(size >= log->size) + { + AXIS2_SNPRINTF(old_log_file_name, AXUTIL_LOG_FILE_NAME_SIZE, "%s%s", log_impl->file_name, + ".old"); + axutil_file_handler_close(log_impl->stream); + old_log_fd = axutil_file_handler_open(old_log_file_name, "w+"); + log_impl->stream = axutil_file_handler_open(log_impl->file_name, "r"); + if(old_log_fd && log_impl->stream) + { + axutil_file_handler_copy(log_impl->stream, old_log_fd); + axutil_file_handler_close(old_log_fd); + axutil_file_handler_close(log_impl->stream); + old_log_fd = NULL; + log_impl->stream = NULL; + } + if(old_log_fd) + { + axutil_file_handler_close(old_log_fd); + } + if(log_impl->stream) + { + axutil_file_handler_close(log_impl->stream); + } + log_impl->stream = axutil_file_handler_open(log_impl->file_name, "w+"); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_log_user( + axutil_log_t *log, + const axis2_char_t *file, + const int line, + const axis2_char_t *format, + ...) +{ + if(log && log->ops && log->ops->write && format && log->enabled) + { + if(AXIS2_LOG_LEVEL_DEBUG <= log->level) + { + char value[AXIS2_LEN_VALUE + 1]; + va_list ap; + va_start(ap, format); + AXIS2_VSNPRINTF(value, AXIS2_LEN_VALUE, format, ap); + va_end(ap); + log->ops->write(log, value, AXIS2_LOG_LEVEL_DEBUG, file, line); + } + } +#ifndef AXIS2_NO_LOG_FILE + else + fprintf(stderr, "please check your log and buffer"); +#endif +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_log_debug( + axutil_log_t *log, + const axis2_char_t *file, + const int line, + const axis2_char_t *format, + ...) +{ + if(log && log->ops && log->ops->write && format && log->enabled) + { + if(AXIS2_LOG_LEVEL_DEBUG <= log->level && log->level != AXIS2_LOG_LEVEL_USER) + { + char value[AXIS2_LEN_VALUE + 1]; + va_list ap; + va_start(ap, format); + AXIS2_VSNPRINTF(value, AXIS2_LEN_VALUE, format, ap); + va_end(ap); + log->ops->write(log, value, AXIS2_LOG_LEVEL_DEBUG, file, line); + } + } +#ifndef AXIS2_NO_LOG_FILE + else + fprintf(stderr, "please check your log and buffer"); +#endif +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_log_info( + axutil_log_t *log, + const axis2_char_t *format, + ...) +{ + if(log && log->ops && log->ops->write && format && log->enabled) + { + if(AXIS2_LOG_LEVEL_INFO <= log->level && log->level != AXIS2_LOG_LEVEL_USER) + { + char value[AXIS2_LEN_VALUE + 1]; + va_list ap; + va_start(ap, format); + AXIS2_VSNPRINTF(value, AXIS2_LEN_VALUE, format, ap); + va_end(ap); + log->ops->write(log, value, AXIS2_LOG_LEVEL_INFO, NULL, -1); + } + } +#ifndef AXIS2_NO_LOG_FILE + else + fprintf(stderr, "please check your log and buffer"); +#endif +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_log_warning( + axutil_log_t *log, + const axis2_char_t *file, + const int line, + const axis2_char_t *format, + ...) +{ + if(log && log->ops && log->ops->write && format && log->enabled) + { + if(AXIS2_LOG_LEVEL_WARNING <= log->level && log->level != AXIS2_LOG_LEVEL_USER) + { + char value[AXIS2_LEN_VALUE + 1]; + va_list ap; + va_start(ap, format); + AXIS2_VSNPRINTF(value, AXIS2_LEN_VALUE, format, ap); + va_end(ap); + log->ops->write(log, value, AXIS2_LOG_LEVEL_WARNING, file, line); + } + } +#ifndef AXIS2_NO_LOG_FILE + else + fprintf(stderr, "please check your log and buffer"); +#endif +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_log_error( + axutil_log_t *log, + const axis2_char_t *file, + const int line, + const axis2_char_t *format, + ...) +{ + if(log && log->ops && log->ops->write && format && log->enabled) + { + char value[AXIS2_LEN_VALUE + 1]; + va_list ap; + va_start(ap, format); + AXIS2_VSNPRINTF(value, AXIS2_LEN_VALUE, format, ap); + va_end(ap); + log->ops->write(log, value, AXIS2_LOG_LEVEL_ERROR, file, line); + } +#ifndef AXIS2_NO_LOG_FILE + else + fprintf(stderr, "please check your log and buffer"); +#endif +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_log_critical( + axutil_log_t *log, + const axis2_char_t *file, + const int line, + const axis2_char_t *format, + ...) +{ + if(log && log->ops && log->ops->write && format && log->enabled) + { + char value[AXIS2_LEN_VALUE + 1]; + va_list ap; + va_start(ap, format); + AXIS2_VSNPRINTF(value, AXIS2_LEN_VALUE, format, ap); + va_end(ap); + log->ops->write(log, value, AXIS2_LOG_LEVEL_CRITICAL, file, line); + } +#ifndef AXIS2_NO_LOG_FILE + else + fprintf(stderr, "please check your log and buffer"); +#endif +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_log_impl_get_time_str( + void) +{ + time_t tp; + char *time_str; + tp = time(&tp); + time_str = ctime(&tp); + if(!time_str) + { + return NULL; + } + if('\n' == time_str[strlen(time_str) - 1]) + { + time_str[strlen(time_str) - 1] = '\0'; + } + return time_str; +} + +AXIS2_EXTERN axutil_log_t *AXIS2_CALL +axutil_log_create_default( + axutil_allocator_t *allocator) +{ + axutil_log_impl_t *log_impl; + + if(!allocator) + return NULL; + + log_impl = (axutil_log_impl_t *)AXIS2_MALLOC(allocator, sizeof(axutil_log_impl_t)); + + if(!log_impl) + return NULL; + + log_impl->mutex = axutil_thread_mutex_create(allocator, AXIS2_THREAD_MUTEX_DEFAULT); + + if(!log_impl->mutex) + { + fprintf(stderr, "cannot create log mutex \n"); + return NULL; + } + + axutil_thread_mutex_lock(log_impl->mutex); + log_impl->file_name = NULL; + log_impl->log.size = AXUTIL_LOG_FILE_SIZE; + log_impl->stream = stderr; + axutil_thread_mutex_unlock(log_impl->mutex); + /* by default, log is enabled */ + log_impl->log.enabled = 1; + log_impl->log.level = AXIS2_LOG_LEVEL_DEBUG; + + log_impl->log.ops = &axutil_log_ops_var; + + return &(log_impl->log); +} + +#ifdef AXIS2_TRACE +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_log_trace( + axutil_log_t *log, + const axis2_char_t *file, + const int line, + const axis2_char_t *format, + ...) +{ + if (log && log->ops && log->ops->write && + format && log->enabled) + { + if(AXIS2_LOG_LEVEL_TRACE <= log->level && log->level != AXIS2_LOG_LEVEL_USER) + { + char value[AXIS2_LEN_VALUE + 1]; + va_list ap; + va_start(ap, format); + AXIS2_VSNPRINTF(value, AXIS2_LEN_VALUE, format, ap); + va_end(ap); + log->ops->write(log, value, AXIS2_LOG_LEVEL_TRACE, file, line); + } + } +#ifndef AXIS2_NO_LOG_FILE + else + fprintf(stderr, "please check your log and buffer"); +#endif +} + +#else +AXIS2_EXTERN void AXIS2_CALL +axutil_log_impl_log_trace( + axutil_log_t *log, + const axis2_char_t *filename, + const int linenumber, + const axis2_char_t *format, + ...) +{ +} +#endif + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_free( + axutil_allocator_t *allocator, + struct axutil_log *log) +{ + log->ops->free(allocator, log); +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_log_write( + axutil_log_t *log, + const axis2_char_t *buffer, + axutil_log_levels_t level, + const axis2_char_t *file, + const int line) +{ + log->ops->write(log, buffer, level, file, line); +} + diff --git a/util/src/md5.c b/util/src/md5.c new file mode 100644 index 0000000..0768df3 --- /dev/null +++ b/util/src/md5.c @@ -0,0 +1,350 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <string.h> +#include <axutil_md5.h> +#include <axutil_error_default.h> +#include <axutil_string.h> + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void AXIS2_CALL md5_transform( + unsigned int state[4], + const unsigned char block[64]); + +static void AXIS2_CALL encode( + unsigned char *output, + const unsigned int *input, + unsigned int len); + +static void AXIS2_CALL decode( + unsigned int *output, + const unsigned char *input, + unsigned int len); + +static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + * Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (unsigned int)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (unsigned int)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (unsigned int)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (unsigned int)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +AXIS2_EXTERN axutil_md5_ctx_t *AXIS2_CALL +axutil_md5_ctx_create( + const axutil_env_t *env) +{ + axutil_md5_ctx_t *context; + AXIS2_ENV_CHECK(env, NULL); + + context = (axutil_md5_ctx_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_md5_ctx_t)); + if(!context) + { + return NULL; + } + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; + return context; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_md5_ctx_free( + axutil_md5_ctx_t *md5_ctx, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(md5_ctx) + { + AXIS2_FREE(env->allocator, md5_ctx); + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_md5_update( + axutil_md5_ctx_t *context, + const axutil_env_t *env, + const void *input_str, + size_t inputLen) +{ + const unsigned char *input = input_str; + unsigned int i, idx, partLen; + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + + /* Compute number of bytes mod 64 */ + idx = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if((context->count[0] += ((unsigned int)inputLen << 3)) < ((unsigned int)inputLen << 3)) + context->count[1]++; + context->count[1] += (unsigned int)inputLen >> 29; + + partLen = 64 - idx; + + /* Transform as many times as possible. */ + if(inputLen >= partLen) + { + memcpy(&context->buffer[idx], input, partLen); + md5_transform(context->state, context->buffer); + + for(i = partLen; i + 63 < inputLen; i += 64) + md5_transform(context->state, &input[i]); + + idx = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy(&context->buffer[idx], &input[i], inputLen - i); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_md5_final( + axutil_md5_ctx_t *context, + const axutil_env_t *env, + unsigned char digest[AXIS2_MD5_DIGESTSIZE]) +{ + unsigned char bits[8]; + unsigned int idx, padLen; + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + + /* Save number of bits */ + encode(bits, context->count, 8); + + /* Pad out to 56 mod 64. */ + idx = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (idx < 56) ? (56 - idx) : (120 - idx); + axutil_md5_update(context, env, PADDING, padLen); + + /* Append length (before padding) */ + axutil_md5_update(context, env, bits, 8); + + /* Store state in digest */ + encode(digest, context->state, AXIS2_MD5_DIGESTSIZE); + + /* Zeroize sensitive information. */ + memset(context, 0, sizeof(*context)); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_md5( + const axutil_env_t *env, + unsigned char digest[AXIS2_MD5_DIGESTSIZE], + const void *input_str, + size_t inputLen) +{ + const unsigned char *input = input_str; + axutil_md5_ctx_t *ctx; + axis2_status_t rv; + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + + ctx = axutil_md5_ctx_create(env); + if(!ctx) + return AXIS2_FAILURE; + + rv = axutil_md5_update(ctx, env, input, inputLen); + if(rv != AXIS2_SUCCESS) + return rv; + + rv = axutil_md5_final(ctx, env, digest); + axutil_md5_ctx_free(ctx, env); + return rv; +} + +/* MD5 basic transformation. Transforms state based on block. */ +static void AXIS2_CALL md5_transform( + unsigned int state[4], + const unsigned char block[64]) +{ + unsigned int a = state[0], b = state[1], c = state[2], d = state[3], + x[AXIS2_MD5_DIGESTSIZE]; + + decode(x, block, 64); + + /* Round 1 */ + FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ + FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ + FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ + FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ + FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ + FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ + FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ + FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ + FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ + FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ + FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ + GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ + GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ + GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ + GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ + GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ + GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ + GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ + GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ + GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ + GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ + HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ + HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ + HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ + HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ + HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ + HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ + HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ + HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ + HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ + II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ + II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ + II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ + II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ + II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ + II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ + II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ + II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ + II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. */ + memset(x, 0, sizeof(x)); +} + +/* encodes input (unsigned int) into output (unsigned char). Assumes len is + * a multiple of 4. + */ +static void AXIS2_CALL encode( + unsigned char *output, + const unsigned int *input, + unsigned int len) +{ + unsigned int i, j; + unsigned int k; + + for (i = 0, j = 0; j < len; i++, j += 4) + { + k = input[i]; + output[j] = (unsigned char)(k & 0xff); + output[j + 1] = (unsigned char)((k >> 8) & 0xff); + output[j + 2] = (unsigned char)((k >> 16) & 0xff); + output[j + 3] = (unsigned char)((k >> 24) & 0xff); + } +} + +/* decodes input (unsigned char) into output (unsigned int). Assumes len is + * a multiple of 4. + */ +static void AXIS2_CALL decode( + unsigned int *output, + const unsigned char *input, + unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((unsigned int)input[j]) | + (((unsigned int)input[j + 1]) << 8) | + (((unsigned int)input[j + 2]) << 16) | + (((unsigned int)input[j + 3]) << 24); +} diff --git a/util/src/minizip/Makefile.am b/util/src/minizip/Makefile.am new file mode 100644 index 0000000..6fc3413 --- /dev/null +++ b/util/src/minizip/Makefile.am @@ -0,0 +1,18 @@ +lib_LTLIBRARIES = libaxis2_minizip.la + +libaxis2_minizip_la_SOURCES = ioapi.c \ + unzip.c \ + archive_extract.c \ + crypt.c + +libaxis2_minizip_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/platforms + +EXTRA_DIST= axis2_archive_extract.h \ + axis2_crypt.h \ + axis2_ioapi.h \ + axis2_iowin32.h \ + axis2_unzip.h \ + iowin32.c diff --git a/util/src/minizip/archive_extract.c b/util/src/minizip/archive_extract.c new file mode 100644 index 0000000..dd68efb --- /dev/null +++ b/util/src/minizip/archive_extract.c @@ -0,0 +1,361 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_dir_handler.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <axutil_string.h> +#include <zlib.h> +#include <fcntl.h> +#include <axis2_unzip.h> +#include <axis2_crypt.h> +#include <axis2_ioapi.h> + +#ifdef WIN32 +#include <axis2_iowin32.h> +#endif + +#define CASESENSITIVITY (0) +#define WRITEBUFFERSIZE (8192) +#define MAXFILENAME (256) + +axis2_status_t aar_select( + ); +int aar_extract( + axis2_char_t * d_name); + +extern int AXIS2_ALPHASORT( + ); + +int +axis2_mkdir(const axis2_char_t * + dir_name) +{ + int value = 0; + value = AXIS2_MKDIR(dir_name, 0775); + return value; +} + +int +axis2_create_dir( + axis2_char_t *new_dir) +{ + axis2_char_t *buffer; + axis2_char_t *p; + axis2_bool_t loop_state = AXIS2_TRUE; + int len = (int) strlen(new_dir); + + if (len <= 0) + return 0; + + buffer = (axis2_char_t *) malloc(len + 1); + strcpy(buffer, new_dir); + + if (buffer[len - 1] == '/') + { + buffer[len - 1] = '\0'; + } + + if (axis2_mkdir(buffer) == 0) + { + free(buffer); + return 1; + } + + p = buffer + 1; + while (loop_state) + { + axis2_char_t hold; + + while (*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((axis2_mkdir(buffer) == -1)) + { + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +int +axis2_extract_currentfile( + unzFile uf, + const int *popt_extract_without_path, + int *popt_overwrite, + const axis2_char_t *password) +{ + axis2_char_t filename_inzip[256]; + axis2_char_t *filename_withoutpath; + axis2_char_t *p; + int err = UNZ_OK; + FILE *fout = NULL; + void *buf; + uInt size_buf; + + unz_file_info file_info; + err = + unzGetCurrentFileInfo(uf, &file_info, filename_inzip, + sizeof(filename_inzip), NULL, 0, NULL, 0); + + if (err != UNZ_OK) + { + return err; + } + + size_buf = WRITEBUFFERSIZE; + buf = (void *) malloc(size_buf); + if (buf == NULL) + return UNZ_INTERNALERROR; + + p = filename_withoutpath = filename_inzip; + while ((*p) != '\0') + { + if (((*p) == '/') || ((*p) == '\\')) + filename_withoutpath = p + 1; + p++; + } + + if ((*filename_withoutpath) == '\0') + { + if ((*popt_extract_without_path) == 0) + { + axis2_mkdir(filename_inzip); + } + } + else + { + axis2_char_t *write_filename; + int skip = 0; + + if ((*popt_extract_without_path) == 0) + write_filename = filename_inzip; + else + write_filename = filename_withoutpath; + + err = unzOpenCurrentFilePassword(uf, password); + + if ((skip == 0) && (err == UNZ_OK)) + { + fout = fopen(write_filename, "wb"); + + if ((fout == NULL) && ((*popt_extract_without_path) == 0) && + (filename_withoutpath != (axis2_char_t *) filename_inzip)) + { + axis2_char_t c = *(filename_withoutpath - 1); + *(filename_withoutpath - 1) = '\0'; + axis2_create_dir(write_filename); + *(filename_withoutpath - 1) = c; + fout = fopen(write_filename, "wb"); + } + + } + + if (fout) + { + do + { + err = unzReadCurrentFile(uf, buf, size_buf); + if (err < 0) + { + break; + } + if (err > 0) + if (fwrite(buf, err, 1, fout) != 1) + { + err = UNZ_ERRNO; + break; + } + } + while (err > 0); + if (fout) + fclose(fout); + } + + if (err == UNZ_OK) + { + err = unzCloseCurrentFile(uf); + } + else + unzCloseCurrentFile(uf); + } + + free(buf); + return err; +} + +int +axis2_extract( + unzFile uf, + int opt_extract_without_path, + int opt_overwrite, + const axis2_char_t *password) +{ + uLong i; + unz_global_info gi; + int err; + + err = unzGetGlobalInfo(uf, &gi); + if (err != UNZ_OK) + return -1; + + for (i = 0; i < gi.number_entry; i++) + { + if (axis2_extract_currentfile(uf, &opt_extract_without_path, + &opt_overwrite, password) != UNZ_OK) + break; + + if ((i + 1) < gi.number_entry) + { + err = unzGoToNextFile(uf); + if (err != UNZ_OK) + { + return -1; + break; + } + } + } + + return 0; +} + +int +aar_extract( + axis2_char_t * d_name) +{ + const axis2_char_t *zipfilename = NULL; + const axis2_char_t *filename_to_extract = NULL; + const axis2_char_t *password = NULL; + axis2_char_t filename_try[MAXFILENAME + 16] = ""; + int opt_do_extract_withoutpath = 0; + int opt_overwrite = 0; + int opt_extractdir = 0; + const axis2_char_t *dir_name = NULL; + int ret = 0; + unzFile uf = NULL; + + if (zipfilename == NULL) + zipfilename = d_name; + + filename_to_extract = d_name; + + if (zipfilename) + { + zlib_filefunc_def ffunc; + strncpy(filename_try, zipfilename, MAXFILENAME - 1); + filename_try[MAXFILENAME] = '\0'; + + axis2_fill_win32_filefunc(&ffunc); + + uf = AXIS2_UNZOPEN2(zipfilename, ffunc); + + if (uf == NULL) + { + strcat(filename_try, ".zip"); + uf = AXIS2_UNZOPEN2(zipfilename, ffunc); + } + } + + if (uf == NULL) + return -1; + + if (opt_extractdir && AXIS2_CHDIR(dir_name)) + exit(-1); + + ret = axis2_extract(uf, opt_do_extract_withoutpath, opt_overwrite, + password); + /*unzCloseCurrentFile(uf);*/ + return ret; +} + +int +axis2_extract_onefile( + unzFile uf, + const axis2_char_t *filename, + int opt_extract_without_path, + int opt_overwrite, + const axis2_char_t *password) +{ + if (unzLocateFile(uf, filename, CASESENSITIVITY) != UNZ_OK) + return -1; + + if (axis2_extract_currentfile(uf, &opt_extract_without_path, + &opt_overwrite, password) == UNZ_OK) + return 0; + else + return -1; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_archive_extract( + ) +{ + struct dirent **namelist; + int n, + i; + axis2_char_t *ptr; + +#ifdef WIN32 + n = axis2_scandir(".", &namelist, 0, alphasort); +#else + n = scandir(".", &namelist, 0, alphasort); +#endif + + if (n < 0) + return AXIS2_FALSE; + else + { + while (n--) + { + if ((strcmp(namelist[n]->d_name, ".") == 0) || + (strcmp(namelist[n]->d_name, "..") == 0)) + { + for (i = n; i >= 0; i--) /* clean remaining memory before return */ + free(namelist[i]); + free(namelist); + return (AXIS2_FALSE); + } + + ptr = axutil_rindex(namelist[n]->d_name, '.'); + if ((ptr) && + (((strcmp(ptr, AXIS2_AAR_SUFFIX) == 0)) || + (strcmp(ptr, AXIS2_MAR_SUFFIX) == 0))) + for (i = 0; i < n; i++) + if (strncmp + (namelist[n]->d_name, namelist[i]->d_name, + strlen(namelist[i]->d_name)) == 0) + { + int j; + for (j = n; j >= 0; j--) /* clean remaining memory before return */ + free(namelist[j]); + free(namelist); + return (AXIS2_FALSE); + } + + aar_extract(namelist[n]->d_name); + free(namelist[n]); + } + free(namelist); + } + return (AXIS2_TRUE); +} diff --git a/util/src/minizip/axis2_archive_extract.h b/util/src/minizip/axis2_archive_extract.h new file mode 100644 index 0000000..92cbab6 --- /dev/null +++ b/util/src/minizip/axis2_archive_extract.h @@ -0,0 +1,35 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_ARCHIVE_EXTRACT_H +#define AXIS2_ARCHIVE_EXTRACT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_archive_extract( + ); + +#ifdef __cplusplus +} +#endif + +#endif /** AXIS2_ARCHIVE_EXTRACT_H */ diff --git a/util/src/minizip/axis2_crypt.h b/util/src/minizip/axis2_crypt.h new file mode 100644 index 0000000..dcdf524 --- /dev/null +++ b/util/src/minizip/axis2_crypt.h @@ -0,0 +1,94 @@ + +/* + * Copyright 2004,2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +int decrypt_byte( + unsigned long *pkeys, + const unsigned long *pcrc_32_tab); + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +int update_keys( + unsigned long *pkeys, + const unsigned long *pcrc_32_tab, + int c); + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +void init_keys( + const char *passwd, + unsigned long *pkeys, + const unsigned long *pcrc_32_tab); + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 +/* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +int crypthead( + passwd, + buf, + bufSize, + pkeys, + pcrc_32_tab, + crcForCrypting); + +#endif diff --git a/util/src/minizip/axis2_ioapi.h b/util/src/minizip/axis2_ioapi.h new file mode 100644 index 0000000..8f14574 --- /dev/null +++ b/util/src/minizip/axis2_ioapi.h @@ -0,0 +1,118 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* ioapi.h -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#ifndef _ZLIBIOAPI_H +#define _ZLIBIOAPI_H + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + +#ifndef ZCALLBACK + +#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) +#define ZCALLBACK CALLBACK +#else +#define ZCALLBACK +#endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef voidpf( + ZCALLBACK * open_file_func) OF( + (voidpf opaque, + const char *filename, + int mode)); + typedef uLong( + ZCALLBACK * read_file_func) OF( + (voidpf opaque, + voidpf stream, + void *buf, + uLong size)); + typedef uLong( + ZCALLBACK * write_file_func) OF( + (voidpf opaque, + voidpf stream, + const void *buf, + uLong size)); + typedef long( + ZCALLBACK * tell_file_func) OF( + (voidpf opaque, + voidpf stream)); + typedef long( + ZCALLBACK * seek_file_func) OF( + (voidpf opaque, + voidpf stream, + uLong offset, + int origin)); + typedef int( + ZCALLBACK * close_file_func) OF( + (voidpf opaque, + voidpf stream)); + typedef int( + ZCALLBACK * testerror_file_func) OF( + (voidpf opaque, + voidpf stream)); + + typedef struct zlib_filefunc_def_s + { + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; + } + zlib_filefunc_def; + + void fill_fopen_filefunc OF( + (zlib_filefunc_def * pzlib_filefunc_def)); + +#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) +#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) +#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) +#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) +#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/util/src/minizip/axis2_iowin32.h b/util/src/minizip/axis2_iowin32.h new file mode 100644 index 0000000..bfe95cf --- /dev/null +++ b/util/src/minizip/axis2_iowin32.h @@ -0,0 +1,40 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* iowin32.h -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + This IO API version uses the Win32 API (for Microsoft Windows) + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include <windows.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + void fill_win32_filefunc OF( + (zlib_filefunc_def * pzlib_filefunc_def)); + +#ifdef __cplusplus +} +#endif diff --git a/util/src/minizip/axis2_unzip.h b/util/src/minizip/axis2_unzip.h new file mode 100644 index 0000000..f2e1f19 --- /dev/null +++ b/util/src/minizip/axis2_unzip.h @@ -0,0 +1,417 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported. + Encryption compatible with pkzip 2.04g only supported + Old compressions used by old PKZip 1.x are not supported + + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + http://www.info-zip.org/pub/infozip/doc/ + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "axis2_ioapi.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) + + /* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ + typedef struct TagunzFile__ + { + int unused; + } + unzFile__; + typedef unzFile__ *unzFile; +#else + typedef voidp unzFile; +#endif + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + + /* tm_unz contain date/time info */ + typedef struct tm_unz_s + { + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ + } + tm_unz; + + /* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ + typedef struct unz_global_info_s + { + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ + } + unz_global_info; + + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_info_s + { + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; + } + unz_file_info; + + extern int ZEXPORT unzStringFileNameCompare OF( + (const char *fileName1, + const char *fileName2, + int iCaseSensitivity)); + + /* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + */ + + extern unzFile ZEXPORT unzOpen OF( + (const char *path)); + + /* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + */ + + extern unzFile ZEXPORT unzOpen2 OF( + (const char *path, + zlib_filefunc_def * pzlib_filefunc_def)); + + /* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see axis2_ioapi.h) + */ + + extern int ZEXPORT unzClose OF( + (unzFile file)); + + /* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + + extern int ZEXPORT unzGetGlobalInfo OF( + (unzFile file, + unz_global_info * pglobal_info)); + + /* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + extern int ZEXPORT unzGetGlobalComment OF( + (unzFile file, + char *szComment, + uLong uSizeBuf)); + + /* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 + */ + + /***************************************************************************/ + + /* Unzip package allow you browse the directory of the zipfile */ + + extern int ZEXPORT unzGoToFirstFile OF( + (unzFile file)); + + /* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem + */ + + extern int ZEXPORT unzGoToNextFile OF( + (unzFile file)); + + /* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. + */ + + extern int ZEXPORT unzLocateFile OF( + (unzFile file, + const char *szFileName, + int iCaseSensitivity)); + + /* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found + */ + + /* ****************************************** */ + + /* Ryan supplied functions */ + + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_pos_s + { + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ + } + unz_file_pos; + + extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos * file_pos); + + extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos * file_pos); + + /* ****************************************** */ + + extern int ZEXPORT unzGetCurrentFileInfo OF( + (unzFile file, + unz_file_info * pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + + /* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) + */ + + /***************************************************************************/ + + /* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + + extern int ZEXPORT unzOpenCurrentFile OF( + (unzFile file)); + + /* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. + */ + + extern int ZEXPORT unzOpenCurrentFilePassword OF( + (unzFile file, + const char *password)); + + /* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. + */ + + extern int ZEXPORT unzOpenCurrentFile2 OF( + (unzFile file, + int *method, + int *level, + int raw)); + + /* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL + */ + + extern int ZEXPORT unzOpenCurrentFile3 OF( + (unzFile file, + int *method, + int *level, + int raw, + const char *password)); + + /* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL + */ + + extern int ZEXPORT unzCloseCurrentFile OF( + (unzFile file)); + + /* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good + */ + + extern int ZEXPORT unzReadCurrentFile OF( + (unzFile file, + voidp buf, + unsigned len)); + + /* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) + */ + + extern z_off_t ZEXPORT unztell OF( + (unzFile file)); + + /* + Give the current position in uncompressed data + */ + + extern int ZEXPORT unzeof OF( + (unzFile file)); + + /* + return 1 if the end of file was reached, 0 elsewhere + */ + + extern int ZEXPORT unzGetLocalExtrafield OF( + (unzFile file, + voidp buf, + unsigned len)); + + /* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code + */ + + /***************************************************************************/ + + /* Get the current file offset */ + extern uLong ZEXPORT unzGetOffset( + unzFile file); + + /* Set the current file offset */ + extern int ZEXPORT unzSetOffset( + unzFile file, + uLong pos); + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/util/src/minizip/crypt.c b/util/src/minizip/crypt.c new file mode 100644 index 0000000..bf2b1d8 --- /dev/null +++ b/util/src/minizip/crypt.c @@ -0,0 +1,172 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#include <axis2_crypt.h> + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +int +decrypt_byte( + unsigned long *pkeys, + const unsigned long *pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned) (*(pkeys + 2)) & 0xffff) | 2; + return (int) (((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +int +update_keys( + unsigned long *pkeys, + const unsigned long *pcrc_32_tab, + int c) +{ + (*(pkeys + 0)) = CRC32((*(pkeys + 0)), c); + (*(pkeys + 1)) += (*(pkeys + 0)) & 0xff; + (*(pkeys + 1)) = (*(pkeys + 1)) * 134775813L + 1; + { + register int keyshift = (int) ((*(pkeys + 1)) >> 24); + (*(pkeys + 2)) = CRC32((*(pkeys + 2)), keyshift); + } + return c; +} + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +void +init_keys( + const char *passwd, + unsigned long *pkeys, + const unsigned long *pcrc_32_tab) +{ + *(pkeys + 0) = 305419896L; + *(pkeys + 1) = 591751049L; + *(pkeys + 2) = 878082192L; + while (*passwd != '\0') + { + update_keys(pkeys, pcrc_32_tab, (int) *passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + +/* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +int +crypthead( + passwd, + buf, + bufSize, + pkeys, + pcrc_32_tab, + crcForCrypting) + const char *passwd; /* password string */ + unsigned char *buf; /* where to write header */ + int bufSize; + unsigned long *pkeys; + const unsigned long *pcrc_32_tab; + unsigned long crcForCrypting; +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN - 2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize < RAND_HEAD_LEN) + return 0; + + /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the + * output of rand() to get less predictability, since rand() is + * often poorly implemented. + */ + if (++calls == 1) + { + srand((unsigned) (time(NULL) ^ ZCR_SEED2)); + } + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + c = (rand() >> 7) & 0xff; + header[n] = (unsigned char) zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + buf[n] = (unsigned char) zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = + zencode(pkeys, pcrc_32_tab, (int) (crcForCrypting >> 16) & 0xff, t); + buf[n++] = + zencode(pkeys, pcrc_32_tab, (int) (crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/util/src/minizip/ioapi.c b/util/src/minizip/ioapi.c new file mode 100644 index 0000000..7a0ac22 --- /dev/null +++ b/util/src/minizip/ioapi.c @@ -0,0 +1,197 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ioapi.c -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "zlib.h" +#include "axis2_ioapi.h" + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +voidpf ZCALLBACK fopen_file_func OF( + (voidpf opaque, + const char *filename, + int mode)); + +uLong ZCALLBACK fread_file_func OF( + (voidpf opaque, + voidpf stream, + void *buf, + uLong size)); + +uLong ZCALLBACK fwrite_file_func OF( + (voidpf opaque, + voidpf stream, + const void *buf, + uLong size)); + +long ZCALLBACK ftell_file_func OF( + (voidpf opaque, + voidpf stream)); + +long ZCALLBACK fseek_file_func OF( + (voidpf opaque, + voidpf stream, + uLong offset, + int origin)); + +int ZCALLBACK fclose_file_func OF( + (voidpf opaque, + voidpf stream)); + +int ZCALLBACK ferror_file_func OF( + (voidpf opaque, + voidpf stream)); + +voidpf ZCALLBACK +fopen_file_func( + voidpf opaque, + const char *filename, + int mode) +{ + FILE *file = NULL; + const char *mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +uLong ZCALLBACK +fread_file_func( + voidpf opaque, + voidpf stream, + void *buf, + uLong size) +{ + uLong ret; + ret = (uLong) fread(buf, 1, (size_t) size, (FILE *) stream); + return ret; +} + +uLong ZCALLBACK +fwrite_file_func( + voidpf opaque, + voidpf stream, + const void *buf, + uLong size) +{ + uLong ret; + ret = (uLong) fwrite(buf, 1, (size_t) size, (FILE *) stream); + return ret; +} + +long ZCALLBACK +ftell_file_func( + voidpf opaque, + voidpf stream) +{ + long ret; + ret = ftell((FILE *) stream); + return ret; +} + +long ZCALLBACK +fseek_file_func( + voidpf opaque, + voidpf stream, + uLong offset, + int origin) +{ + int fseek_origin = 0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR: + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END: + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET: + fseek_origin = SEEK_SET; + break; + default: + return -1; + } + ret = 0; + fseek((FILE *) stream, offset, fseek_origin); + return ret; +} + +int ZCALLBACK +fclose_file_func( + voidpf opaque, + voidpf stream) +{ + int ret; + ret = fclose((FILE *) stream); + return ret; +} + +int ZCALLBACK +ferror_file_func( + voidpf opaque, + voidpf stream) +{ + int ret; + ret = ferror((FILE *) stream); + return ret; +} + +void +fill_fopen_filefunc( + zlib_filefunc_def *pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/util/src/minizip/iowin32.c b/util/src/minizip/iowin32.c new file mode 100644 index 0000000..f774437 --- /dev/null +++ b/util/src/minizip/iowin32.c @@ -0,0 +1,300 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* iowin32.c -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + This IO API version uses the Win32 API (for Microsoft Windows) + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include <stdlib.h> + +#include "zlib.h" +#include "axis2_ioapi.h" +#include "axis2_iowin32.h" + +#ifndef INVALID_HANDLE_VALUE +#define INVALID_HANDLE_VALUE (0xFFFFFFFF) +#endif + +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +voidpf ZCALLBACK win32_open_file_func OF( + (voidpf opaque, + const char *filename, + int mode)); + +uLong ZCALLBACK win32_read_file_func OF( + (voidpf opaque, + voidpf stream, + void *buf, + uLong size)); + +uLong ZCALLBACK win32_write_file_func OF( + (voidpf opaque, + voidpf stream, + const void *buf, + uLong size)); + +long ZCALLBACK win32_tell_file_func OF( + (voidpf opaque, + voidpf stream)); + +long ZCALLBACK win32_seek_file_func OF( + (voidpf opaque, + voidpf stream, + uLong offset, + int origin)); + +int ZCALLBACK win32_close_file_func OF( + (voidpf opaque, + voidpf stream)); + +int ZCALLBACK win32_error_file_func OF( + (voidpf opaque, + voidpf stream)); + +typedef struct +{ + HANDLE hf; + int error; +} +WIN32FILE_IOWIN; + +voidpf ZCALLBACK +win32_open_file_func( + voidpf opaque, + const char *filename, + int mode) +{ + /*const char *mode_fopen = NULL;*/ + DWORD dwDesiredAccess, + dwCreationDisposition, + dwShareMode, + dwFlagsAndAttributes; + HANDLE hFile = 0; + voidpf ret = NULL; + + dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = dwCreationDisposition = 0; + /* dwCreationDisposition = 0, to avoid C4701 */ + + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) + { + dwDesiredAccess = GENERIC_READ; + dwCreationDisposition = OPEN_EXISTING; + dwShareMode = FILE_SHARE_READ; + } + else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + { + dwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + dwCreationDisposition = OPEN_EXISTING; + } + else if (mode & ZLIB_FILEFUNC_MODE_CREATE) + { + dwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + dwCreationDisposition = CREATE_ALWAYS; + } + + if ((filename) && (dwDesiredAccess != 0)) + hFile = + CreateFile((LPCTSTR) filename, dwDesiredAccess, dwShareMode, NULL, + dwCreationDisposition, dwFlagsAndAttributes, NULL); + + if (hFile == INVALID_HANDLE_VALUE) + hFile = NULL; + + if (hFile) + { + WIN32FILE_IOWIN w32fiow; + w32fiow.hf = hFile; + w32fiow.error = 0; + ret = malloc(sizeof(WIN32FILE_IOWIN)); + if (ret == NULL) + CloseHandle(hFile); + else + *((WIN32FILE_IOWIN *) ret) = w32fiow; + } + return ret; +} + +uLong ZCALLBACK +win32_read_file_func( + voidpf opaque, + voidpf stream, + void *buf, + uLong size) +{ + uLong ret = 0; + HANDLE hFile = NULL; + if (stream) + hFile = ((WIN32FILE_IOWIN *) stream)->hf; + if (hFile) + if (!ReadFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN *) stream)->error = (int) dwErr; + } + + return ret; +} + +uLong ZCALLBACK +win32_write_file_func( + voidpf opaque, + voidpf stream, + const void *buf, + uLong size) +{ + uLong ret = 0; + HANDLE hFile = NULL; + if (stream) + hFile = ((WIN32FILE_IOWIN *) stream)->hf; + + if (hFile) + if (!WriteFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN *) stream)->error = (int) dwErr; + } + + return ret; +} + +long ZCALLBACK +win32_tell_file_func( + voidpf opaque, + voidpf stream) +{ + long ret = -1; + HANDLE hFile = NULL; + if (stream) + hFile = ((WIN32FILE_IOWIN *) stream)->hf; + if (hFile) + { + DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT); + if (dwSet == INVALID_SET_FILE_POINTER) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN *) stream)->error = (int) dwErr; + ret = -1; + } + else + ret = (long) dwSet; + } + return ret; +} + +long ZCALLBACK +win32_seek_file_func( + voidpf opaque, + voidpf stream, + uLong offset, + int origin) +{ + DWORD dwMoveMethod = 0xFFFFFFFF; + HANDLE hFile = NULL; + + long ret = -1; + if (stream) + hFile = ((WIN32FILE_IOWIN *) stream)->hf; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR: + dwMoveMethod = FILE_CURRENT; + break; + case ZLIB_FILEFUNC_SEEK_END: + dwMoveMethod = FILE_END; + break; + case ZLIB_FILEFUNC_SEEK_SET: + dwMoveMethod = FILE_BEGIN; + break; + default: + return -1; + } + + if (hFile) + { + DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod); + if (dwSet == INVALID_SET_FILE_POINTER) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN *) stream)->error = (int) dwErr; + ret = -1; + } + else + ret = 0; + } + return ret; +} + +int ZCALLBACK +win32_close_file_func( + voidpf opaque, + voidpf stream) +{ + int ret = -1; + + if (stream) + { + HANDLE hFile; + hFile = ((WIN32FILE_IOWIN *) stream)->hf; + if (hFile) + { + CloseHandle(hFile); + ret = 0; + } + free(stream); + } + return ret; +} + +int ZCALLBACK +win32_error_file_func( + voidpf opaque, + voidpf stream) +{ + int ret = -1; + if (stream) + { + ret = ((WIN32FILE_IOWIN *) stream)->error; + } + return ret; +} + +void +fill_win32_filefunc( + zlib_filefunc_def *pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen_file = win32_open_file_func; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell_file = win32_tell_file_func; + pzlib_filefunc_def->zseek_file = win32_seek_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/util/src/minizip/unzip.c b/util/src/minizip/unzip.c new file mode 100644 index 0000000..146d93a --- /dev/null +++ b/util/src/minizip/unzip.c @@ -0,0 +1,1655 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* unzip.c -- IO for uncompress .zip files using zlib + * Version 1.01e, February 12th, 2005 + * + * Copyright (C) 1998-2005 Gilles Vollant + * + * Read axis2_unzip.h for more info + * + * + * Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + * compatibility with older software. The following is from the original crypt.c. Code + * woven in by Terry Thorsen 1/2003. + * + * + * + * Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + * + * See the accompanying file LICENSE, version 2000-Apr-09 or later + * (the contents of which are also included in zip.h) for terms of use. + * If, for some reason, all these files are missing, the Info-ZIP license + * also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + * + * + * + * crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + * + * The encryption/decryption parts of this source code (as opposed to the + * non-echoing password parts) were originally written in Europe. The + * whole source package can be freely distributed, including from the USA. + * (Prior to January 2000, re-export from the US was a violation of US law.) + * + * + * + * This encryption code is a direct transcription of the algorithm from + * Roger Schlafly, described by Phil Katz in the file appnote.txt. This + * file (appnote.txt) is distributed with the PKZIP program (even in the + * version without encryption capabilities). + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "zlib.h" +#include "axis2_unzip.h" + +#ifdef STDC +# include <stddef.h> +# include <string.h> +# include <stdlib.h> +#endif +#ifdef NO_ERRNO_H +extern int errno; +#else +# include <errno.h> +#endif + +#ifndef local +# define local static +#endif + +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile; /* relative offset of local header 4 bytes */ +} +unz_file_info_internal; + +/* + * file_in_zip_read_info_s contain internal information about a file in zipfile, + * when reading and decompress it + */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek */ + uLong stream_initialised; /* flag set if stream structure is initialised */ + + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read */ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed; /*number of byte to be obtained after decomp */ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx) */ + int raw; +} +file_in_zip_read_info_s; + +/* unz_s contain internal information about the zipfile */ +typedef struct +{ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx) */ + uLong num_file; /* number of the current file in the zipfile */ + uLong pos_in_central_dir; /* pos of the current file in the central dir */ + uLong current_file_ok; /* flag about the usability of the current file */ + uLong central_pos; /* position of the beginning of the central dir */ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + * respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip */ + unz_file_info_internal cur_file_info_internal; /* private info about it */ + file_in_zip_read_info_s *pfile_in_zip_read; /* structure about the current + * file if we are decompressing it */ + int encrypted; +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long *pcrc_32_tab; +# endif +} +unz_s; + +#ifndef NOUNCRYPT +#include <axis2_crypt.h> +#endif + +/* + * Read a byte from a gz_stream; update next_in and avail_in. Return EOF + * for end of file. + * IN assertion: the stream s has been sucessfully opened for reading. + */ + +local int unzlocal_getByte OF( + (const zlib_filefunc_def * pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int +unzlocal_getByte( + const zlib_filefunc_def *pzlib_filefunc_def, + voidpf filestream, + int *pi) +{ + unsigned char c; + int err = (int) ZREAD(*pzlib_filefunc_def, filestream, &c, 1); + if (err == 1) + { + *pi = (int) c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def, filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + +/* Reads a long in LSB order from the given gz_stream. Sets */ +local int unzlocal_getShort OF( + (const zlib_filefunc_def * pzlib_filefunc_def, + voidpf filestream, + uLong * pX)); + +local int +unzlocal_getShort( + const zlib_filefunc_def *pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x; + int i = 0; + int err = 0; + + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x = (uLong) i; + + if (err == UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong) i) << 8; + + if (err == UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong OF( + (const zlib_filefunc_def * pzlib_filefunc_def, + voidpf filestream, + uLong * pX)); + +local int +unzlocal_getLong( + const zlib_filefunc_def *pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x; + int i = 0; + int err = 0; + + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x = (uLong) i; + + if (err == UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong) i) << 8; + + if (err == UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong) i) << 16; + + if (err == UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong) i) << 24; + + if (err == UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int +strcmpcasenosensitive_internal( + const char *fileName1, + const char *fileName2) +{ + for (;;) + { + char c1 = *(fileName1++); + char c2 = *(fileName2++); + if ((c1 >= 'a') && (c1 <= 'z')) + c1 -= 0x20; + if ((c2 >= 'a') && (c2 <= 'z')) + c2 -= 0x20; + if (c1 == '\0') + return ((c2 == '\0') ? 0 : -1); + if (c2 == '\0') + return 1; + if (c1 < c2) + return -1; + if (c1 > c2) + return 1; + } +} + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + * Compare two filename (fileName1,fileName2). + * If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + * If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + * or strcasecmp) + * If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + * (like 1 on Unix, 2 on Windows) + */ +extern int ZEXPORT +unzStringFileNameCompare( + const char *fileName1, + const char *fileName2, + int iCaseSensitivity) +{ + if (iCaseSensitivity == 0) + iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity == 1) + return strcmp(fileName1, fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1, fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + * Locate the Central directory of a zipfile (at the end, just before + * the global comment) + */ +local uLong unzlocal_SearchCentralDir OF( + (const zlib_filefunc_def * pzlib_filefunc_def, + voidpf filestream)); + +local uLong +unzlocal_SearchCentralDir( + const zlib_filefunc_def *pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char *buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack = 0xffff; /* maximum size of global comment */ + uLong uPosFound = 0; + + if (ZSEEK(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL(*pzlib_filefunc_def, filestream); + + if (uMaxBack > uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char *) ALLOC(BUFREADCOMMENT + 4); + if (buf == NULL) + return 0; + + uBackRead = 4; + while (uBackRead < uMaxBack) + { + uLong uReadSize, + uReadPos; + int i = 0; + if (uBackRead + BUFREADCOMMENT > uMaxBack) + uBackRead = uMaxBack; + else + uBackRead += BUFREADCOMMENT; + uReadPos = uSizeFile - uBackRead; + + uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? + (BUFREADCOMMENT + 4) : (uSizeFile - uReadPos); + if (ZSEEK + (*pzlib_filefunc_def, filestream, uReadPos, + ZLIB_FILEFUNC_SEEK_SET) != 0) + break; + + if (ZREAD(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) + break; + + for (i = (int) uReadSize - 3; (i--) > 0;) + if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && + ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06)) + { + uPosFound = uReadPos + i; + break; + } + + if (uPosFound != 0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + * Open a Zip file. path contain the full pathname (by example, + * on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + * "zlib/zlib114.zip". + * If the zipfile cannot be opened (file doesn't exist or in not valid), the + * return value is NULL. + * Else, the return value is a unzFile Handle, usable with other function + * of this unzip package. + */ +extern unzFile ZEXPORT +unzOpen2( + const char *path, + zlib_filefunc_def *pzlib_filefunc_def) +{ + unz_s us; + unz_s *s; + uLong central_pos, + uL; + + uLong number_disk; /* number of the current dist, used for + * spaning ZIP, unsupported, always 0 */ + uLong number_disk_with_CD; /* number the the disk with central dir, used + * for spaning ZIP, unsupported, always 0 */ + uLong number_entry_CD; /* total number of entries in + * the central dir + * (same than number_entry on nospan) */ + + int err = UNZ_OK; + + if (unz_copyright[0] != ' ') + return NULL; + + if (pzlib_filefunc_def == NULL) + fill_fopen_filefunc(&us.z_filefunc); + else + us.z_filefunc = *pzlib_filefunc_def; + + us.filestream = (*(us.z_filefunc.zopen_file)) (us.z_filefunc.opaque, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream == NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc, us.filestream); + if (central_pos == 0) + err = UNZ_ERRNO; + + if (ZSEEK(us.z_filefunc, us.filestream, + central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk) != + UNZ_OK) + err = UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk_with_CD) + != UNZ_OK) + err = UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &us.gi.number_entry) != + UNZ_OK) + err = UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_entry_CD) != + UNZ_OK) + err = UNZ_ERRNO; + + if ((number_entry_CD != us.gi.number_entry) || + (number_disk_with_CD != 0) || (number_disk != 0)) + err = UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &us.size_central_dir) != + UNZ_OK) + err = UNZ_ERRNO; + + /* offset of start of central directory with respect to the + * starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &us.offset_central_dir) + != UNZ_OK) + err = UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment) != + UNZ_OK) + err = UNZ_ERRNO; + + if ((central_pos < us.offset_central_dir + us.size_central_dir) && + (err == UNZ_OK)) + err = UNZ_BADZIPFILE; + + if (err != UNZ_OK) + { + ZCLOSE(us.z_filefunc, us.filestream); + return NULL; + } + + us.byte_before_the_zipfile = central_pos - + (us.offset_central_dir + us.size_central_dir); + us.central_pos = central_pos; + us.pfile_in_zip_read = NULL; + us.encrypted = 0; + + s = (unz_s *) ALLOC(sizeof(unz_s)); + *s = us; + unzGoToFirstFile((unzFile) s); + return (unzFile) s; +} + +extern unzFile ZEXPORT +unzOpen( + const char *path) +{ + return unzOpen2(path, NULL); +} + +/* + * Close a ZipFile opened with unzipOpen. + * If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), + * these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + * return UNZ_OK if there is no problem. + */ +extern int ZEXPORT +unzClose( + unzFile file) +{ + unz_s *s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + + if (s->pfile_in_zip_read) + unzCloseCurrentFile(file); + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + +/* + * Write info about the ZipFile in the *pglobal_info structure. + * No preparation of the structure is needed + * return UNZ_OK if there is no problem. + */ +extern int ZEXPORT +unzGetGlobalInfo( + unzFile file, + unz_global_info *pglobal_info) +{ + unz_s *s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + *pglobal_info = s->gi; + return UNZ_OK; +} + +/* Translate date/time from Dos format to tm_unz (readable more easilty) */ +local void +unzlocal_DosDateToTmuDate( + uLong ulDosDate, + tm_unz *ptm) +{ + uLong uDate; + uDate = (uLong) (ulDosDate >> 16); + ptm->tm_mday = (uInt) (uDate & 0x1f); + ptm->tm_mon = (uInt) ((((uDate) & 0x1E0) / 0x20) - 1); + ptm->tm_year = (uInt) (((uDate & 0x0FE00) / 0x0200) + 1980); + + ptm->tm_hour = (uInt) ((ulDosDate & 0xF800) / 0x800); + ptm->tm_min = (uInt) ((ulDosDate & 0x7E0) / 0x20); + ptm->tm_sec = (uInt) (2 * (ulDosDate & 0x1f)); +} + +/* Get Info about the current file in the zipfile, with internal only info */ +local int unzlocal_GetCurrentFileInfoInternal OF( + (unzFile file, + unz_file_info * pfile_info, + unz_file_info_internal * pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int +unzlocal_GetCurrentFileInfoInternal( + unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz_s *s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err = UNZ_OK; + uLong uMagic = 0x00000000; + long lSeek = 0; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + if (ZSEEK(s->z_filefunc, s->filestream, + s->pos_in_central_dir + s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; + + /* we check the magic */ + if (err == UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + err = UNZ_ERRNO; + } + else if (uMagic != 0x02014b50) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version) != + UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort + (&s->z_filefunc, s->filestream, &file_info.version_needed) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.flag) != + UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort + (&s->z_filefunc, s->filestream, + &file_info.compression_method) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.dosDate) != + UNZ_OK) + err = UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.crc) != + UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong + (&s->z_filefunc, s->filestream, &file_info.compressed_size) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong + (&s->z_filefunc, s->filestream, &file_info.uncompressed_size) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort + (&s->z_filefunc, s->filestream, &file_info.size_filename) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort + (&s->z_filefunc, s->filestream, &file_info.size_file_extra) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort + (&s->z_filefunc, s->filestream, &file_info.size_file_comment) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort + (&s->z_filefunc, s->filestream, &file_info.disk_num_start) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.internal_fa) + != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.external_fa) + != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong + (&s->z_filefunc, s->filestream, + &file_info_internal.offset_curfile) != UNZ_OK) + err = UNZ_ERRNO; + + lSeek += file_info.size_filename; + if ((err == UNZ_OK) && (szFileName)) + { + uLong uSizeRead; + if (file_info.size_filename < fileNameBufferSize) + { + *(szFileName + file_info.size_filename) = '\0'; + uSizeRead = file_info.size_filename; + } + else + uSizeRead = fileNameBufferSize; + + if ((file_info.size_filename > 0) && (fileNameBufferSize > 0)) + if (ZREAD(s->z_filefunc, s->filestream, szFileName, uSizeRead) != + uSizeRead) + err = UNZ_ERRNO; + lSeek -= uSizeRead; + } + + if ((err == UNZ_OK) && (extraField)) + { + uLong uSizeRead; + if (file_info.size_file_extra < extraFieldBufferSize) + uSizeRead = file_info.size_file_extra; + else + uSizeRead = extraFieldBufferSize; + + if (lSeek != 0) + { + if (ZSEEK + (s->z_filefunc, s->filestream, lSeek, + ZLIB_FILEFUNC_SEEK_CUR) == 0) + lSeek = 0; + else + err = UNZ_ERRNO; + } + if ((file_info.size_file_extra > 0) && (extraFieldBufferSize > 0)) + if (ZREAD(s->z_filefunc, s->filestream, extraField, uSizeRead) != + uSizeRead) + err = UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + if ((err == UNZ_OK) && (szComment)) + { + uLong uSizeRead; + if (file_info.size_file_comment < commentBufferSize) + { + *(szComment + file_info.size_file_comment) = '\0'; + uSizeRead = file_info.size_file_comment; + } + else + uSizeRead = commentBufferSize; + + if (lSeek != 0) + { + if (ZSEEK + (s->z_filefunc, s->filestream, lSeek, + ZLIB_FILEFUNC_SEEK_CUR) == 0) + lSeek = 0; + else + err = UNZ_ERRNO; + } + if ((file_info.size_file_comment > 0) && (commentBufferSize > 0)) + if (ZREAD(s->z_filefunc, s->filestream, szComment, uSizeRead) != + uSizeRead) + err = UNZ_ERRNO; + lSeek += file_info.size_file_comment - uSizeRead; + } + else + lSeek += file_info.size_file_comment; + + if ((err == UNZ_OK) && (pfile_info)) + *pfile_info = file_info; + + if ((err == UNZ_OK) && (pfile_info_internal)) + *pfile_info_internal = file_info_internal; + + return err; +} + +/* + * Write info about the ZipFile in the *pglobal_info structure. + * No preparation of the structure is needed + * return UNZ_OK if there is no problem. + */ +extern int ZEXPORT +unzGetCurrentFileInfo( + unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file, pfile_info, NULL, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize); +} + +/* + * Set the current file of the zipfile to the first file. + * return UNZ_OK if there is no problem + */ +extern int ZEXPORT +unzGoToFirstFile( + unzFile file) +{ + int err = UNZ_OK; + unz_s *s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + s->pos_in_central_dir = s->offset_central_dir; + s->num_file = 0; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, + &s->cur_file_info_internal, + NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + * Set the current file of the zipfile to the next file. + * return UNZ_OK if there is no problem + * return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. + */ +extern int ZEXPORT +unzGoToNextFile( + unzFile file) +{ + unz_s *s; + int err; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file + 1 == s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += + SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, + &s->cur_file_info_internal, + NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + * Try locate the file szFileName in the zipfile. + * For the iCaseSensitivity signification, see unzipStringFileNameCompare + * + * return value : + * UNZ_OK if the file is found. It becomes the current file. + * UNZ_END_OF_LIST_OF_FILE if the file is not found + */ +extern int ZEXPORT +unzLocateFile( + unzFile file, + const char *szFileName, + int iCaseSensitivity) +{ + unz_s *s; + int err = 0; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info cur_file_infoSaved; + unz_file_info_internal cur_file_info_internalSaved; + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + if (file == NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName) >= UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s = (unz_s *) file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1]; + err = unzGetCurrentFileInfo(file, NULL, + szCurrentFileName, + sizeof(szCurrentFileName) - 1, NULL, 0, + NULL, 0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName, iCaseSensitivity) == 0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved; + s->pos_in_central_dir = pos_in_central_dirSaved; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + +/* + * Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) + * I need random access + * + * Further optimization could be realized by adding an ability + * to cache the directory in memory. The goal being a single + * comprehensive file read to put the file I need in a memory. + */ + +/* +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; + uLong num_of_file; +} unz_file_pos; +*/ + +extern int ZEXPORT +unzGetFilePos( + unzFile file, + unz_file_pos *file_pos) +{ + unz_s *s; + + if (file == NULL || file_pos == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT +unzGoToFilePos( + unzFile file, + unz_file_pos *file_pos) +{ + unz_s *s; + int err = 0; + + if (file == NULL || file_pos == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, + &s->cur_file_info_internal, + NULL, 0, NULL, 0, NULL, 0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + * Unzip Helper Functions - should be here? + */ + +/* + * Read the local header of the current zipfile + * Check the coherency of the local header and info in the end of central + * directory about this file + * store in *piSizeVar the size of extra info in local header + * (filename and size of extra field data) + */ +local int +unzlocal_CheckCurrentFileCoherencyHeader( + unz_s *s, + uInt *piSizeVar, + uLong *poffset_local_extrafield, + uInt *psize_local_extrafield) +{ + uLong uMagic, + uData, + uFlags; + uLong size_filename; + uLong size_extra_field; + int err = UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK + (s->z_filefunc, s->filestream, + s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + + if (err == UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + err = UNZ_ERRNO; + else if (uMagic != 0x04034b50) + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + err = UNZ_ERRNO; + /* + * else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + * err=UNZ_BADZIPFILE; + */ + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method)) + err = UNZ_BADZIPFILE; + + if ((err == UNZ_OK) && (s->cur_file_info.compression_method != 0) && + (s->cur_file_info.compression_method != Z_DEFLATED)) + err = UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* date/time */ + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* crc */ + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) && + ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* size compr */ + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compressed_size) && + ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* size uncompr */ + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.uncompressed_size) && + ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_filename) != + UNZ_OK) + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && + (size_filename != s->cur_file_info.size_filename)) + err = UNZ_BADZIPFILE; + + *piSizeVar += (uInt) size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_extra_field) != + UNZ_OK) + err = UNZ_ERRNO; + *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt) size_extra_field; + + *piSizeVar += (uInt) size_extra_field; + + return err; +} + +/* + * Open for reading data the current file in the zipfile. + * If there is no error and the file is opened, the return value is UNZ_OK. + */ +extern int ZEXPORT +unzOpenCurrentFile3( + unzFile file, + int *method, + int *level, + int raw, + const char *password) +{ + int err = UNZ_OK; + uInt iSizeVar; + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password) + return UNZ_PARAMERROR; +# endif + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s, &iSizeVar, + &offset_local_extrafield, + &size_local_extrafield) != + UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s *) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info == NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer = (char *) ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield = 0; + pfile_in_zip_read_info->raw = raw; + + if (pfile_in_zip_read_info->read_buffer == NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised = 0; + + if (method) + *method = (int) s->cur_file_info.compression_method; + + if (level) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6: + *level = 1; + break; + case 4: + *level = 2; + break; + case 2: + *level = 9; + break; + } + } + + if ((s->cur_file_info.compression_method != 0) && + (s->cur_file_info.compression_method != Z_DEFLATED)) + err = UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc; + pfile_in_zip_read_info->crc32 = 0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream = s->filestream; + pfile_in_zip_read_info->z_filefunc = s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile = + s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method == Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func) 0; + pfile_in_zip_read_info->stream.zfree = (free_func) 0; + pfile_in_zip_read_info->stream.opaque = (voidpf) 0; + pfile_in_zip_read_info->stream.next_in = (voidpf) 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised = 1; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size; + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt) 0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + +# ifndef NOUNCRYPT + if (password) + { + int i = 0; + s->pcrc_32_tab = get_crc_table(); + init_keys(password, s->keys, s->pcrc_32_tab); + if (ZSEEK(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, SEEK_SET) != 0) + return UNZ_INTERNALERROR; + if (ZREAD(s->z_filefunc, s->filestream, source, 12) < 12) + return UNZ_INTERNALERROR; + + for (i = 0; i < 12; i++) + zdecode(s->keys, s->pcrc_32_tab, source[i]); + + s->pfile_in_zip_read->pos_in_zipfile += 12; + s->encrypted = 1; + } +# endif + + return UNZ_OK; +} + +extern int ZEXPORT +unzOpenCurrentFile( + unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT +unzOpenCurrentFilePassword( + unzFile file, + const char *password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT +unzOpenCurrentFile2( + unzFile file, + int *method, + int *level, + int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/* + * Read bytes from the current file. + * buf contain buffer where data must be copied + * len the size of buf. + * + * return the number of byte copied if somes bytes are copied + * return 0 if the end of file was reached + * return <0 with error code if there is an error + * (UNZ_ERRNO for IO error, or zLib error for uncompress error) + */ +extern int ZEXPORT +unzReadCurrentFile( + unzFile file, + voidp buf, + unsigned len) +{ + int err = UNZ_OK; + uInt iRead = 0; + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len == 0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef *) buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt) len; + + if ((len > pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt) pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len > pfile_in_zip_read_info->rest_read_compressed + + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt) pfile_in_zip_read_info->rest_read_compressed + + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out > 0) + { + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed > 0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressed < uReadThis) + uReadThis = (uInt) pfile_in_zip_read_info->rest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis) != uReadThis) + return UNZ_ERRNO; + +# ifndef NOUNCRYPT + if (s->encrypted) + { + uInt i; + for (i = 0; i < uReadThis; i++) + pfile_in_zip_read_info->read_buffer[i] = + (char)zdecode(s->keys, s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + /* We are sure that the conversion is safe */ + } +# endif + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed -= uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef *) pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt) uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method == 0) || + (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy, + i; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead == 0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in; + + for (i = 0; i < uDoCopy; i++) + *(pfile_in_zip_read_info->stream.next_out + i) = + *(pfile_in_zip_read_info->stream.next_in + i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info-> + stream.next_out, uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore, + uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush = Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + * if ((pfile_in_zip_read_info->rest_read_uncompressed == + * pfile_in_zip_read_info->stream.avail_out) && + * (pfile_in_zip_read_info->rest_read_compressed == 0)) + * flush = Z_FINISH; + */ + err = inflate(&pfile_in_zip_read_info->stream, flush); + + if ((err >= 0) && (pfile_in_zip_read_info->stream.msg)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter - uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32, bufBefore, + (uInt) (uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + + iRead += (uInt) (uTotalOutAfter - uTotalOutBefore); + + if (err == Z_STREAM_END) + return (iRead == 0) ? UNZ_EOF : iRead; + if (err != Z_OK) + break; + } + } + + if (err == Z_OK) + return iRead; + return err; +} + +/* Give the current position in uncompressed data */ +extern z_off_t ZEXPORT +unztell( + unzFile file) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + return (z_off_t) pfile_in_zip_read_info->stream.total_out; +} + +/* return 1 if the end of file was reached, 0 elsewhere */ +extern int ZEXPORT +unzeof( + unzFile file) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + +/* + * Read extra field from the current file (opened by unzOpenCurrentFile) + * This is the local-header version of the extra field (sometimes, there is + * more info in the local-header version than in the central-header) + * + * if buf==NULL, it return the size of the local extra field that can be read + * + * if buf!=NULL, len is the size of the buffer, the extra header is copied in + * buf. + * the return value is the number of bytes copied in buf, or (if <0) + * the error code + */ +extern int ZEXPORT +unzGetLocalExtrafield( + unzFile file, + voidp buf, + unsigned len) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf == NULL) + return (int) size_to_read; + + if (len > size_to_read) + read_now = (uInt) size_to_read; + else + read_now = (uInt) len; + + if (read_now == 0) + return 0; + + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, buf, read_now) != read_now) + return UNZ_ERRNO; + + return (int) read_now; +} + +/* + * Close the file in zip opened with unzipOpenCurrentFile + * Return UNZ_CRCERROR if all the file was read but the CRC is not good + */ +extern int ZEXPORT +unzCloseCurrentFile( + unzFile file) +{ + int err = UNZ_OK; + + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err = UNZ_CRCERROR; + } + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read = NULL; + + return err; +} + +/* + * Get the global comment string of the ZipFile, in the szComment buffer. + * uSizeBuf is the size of the szComment buffer. + * return the number of byte copied or an error code <0 + */ +extern int ZEXPORT +unzGetGlobalComment( + unzFile file, + char *szComment, + uLong uSizeBuf) +{ + unz_s *s; + uLong uReadThis; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + + uReadThis = uSizeBuf; + if (uReadThis > s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK + (s->z_filefunc, s->filestream, s->central_pos + 22, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + + if (uReadThis > 0) + { + *szComment = '\0'; + if (ZREAD(s->z_filefunc, s->filestream, szComment, uReadThis) != + uReadThis) + return UNZ_ERRNO; + } + + if ((szComment) && (uSizeBuf > s->gi.size_comment)) + *(szComment + s->gi.size_comment) = '\0'; + return (int) uReadThis; +} + +/* Additions by RX '2004 */ +extern uLong ZEXPORT +unzGetOffset( + unzFile file) +{ + unz_s *s; + + if (file == NULL) + return 0; + s = (unz_s *) file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file == s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern int ZEXPORT +unzSetOffset( + unzFile file, + uLong pos) +{ + unz_s *s; + int err; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *) file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, + &s->cur_file_info_internal, + NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} diff --git a/util/src/network_handler.c b/util/src/network_handler.c new file mode 100644 index 0000000..a8d154e --- /dev/null +++ b/util/src/network_handler.c @@ -0,0 +1,644 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <axutil_network_handler.h>
+#include <fcntl.h>
+
+
+#if defined(WIN32)
+/* fix for an older version of winsock2.h */
+#if !defined(SO_EXCLUSIVEADDRUSE)
+#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR))
+#endif
+#endif
+
+#if defined(WIN32)
+static int is_init_socket = 0;
+axis2_bool_t axis2_init_socket(
+);
+#endif
+
+AXIS2_EXTERN axis2_socket_t AXIS2_CALL
+axutil_network_handler_open_socket(
+ const axutil_env_t *env,
+ char *server,
+ int port)
+{
+ axis2_socket_t sock = AXIS2_INVALID_SOCKET;
+ struct sockaddr_in sock_addr;
+ struct linger ll;
+ int nodelay = 1;
+
+#if defined(WIN32)
+ if (is_init_socket == 0)
+ {
+ axis2_init_socket();
+ is_init_socket = 1;
+ }
+#endif
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, server, AXIS2_INVALID_SOCKET);
+
+#ifndef WIN32
+ if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ /*AF_INET is not defined in sys/socket.h but PF_INET */
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+#else
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+ /* In Win 32 if the socket creation failed it return 0 not a negative value */
+ {
+ char buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ /* Get the detailed error message */
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+#endif
+
+ memset(&sock_addr, 0, sizeof(sock_addr));
+ sock_addr.sin_family = AF_INET;
+ sock_addr.sin_addr.s_addr = inet_addr(server); /*arpa/inet.d */
+
+ if(sock_addr.sin_addr.s_addr == AXIS2_INADDR_NONE) /*netinet/in.h */
+ {
+ /*
+ * server may be a host name
+ */
+ struct hostent *lphost = NULL;
+ lphost = gethostbyname(server);
+
+ if(lphost)
+ {
+ sock_addr.sin_addr.s_addr = ((struct in_addr *)lphost->h_addr)->s_addr;
+ }
+ else
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+ }
+
+ sock_addr.sin_port = htons((axis2_unsigned_short_t)port);
+
+ /* Connect to server */
+ if(connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
+ {
+ AXIS2_CLOSE_SOCKET(sock);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay));
+ ll.l_onoff = 1;
+ ll.l_linger = 5;
+ setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char *)&ll, sizeof(struct linger));
+ return sock;
+}
+
+AXIS2_EXTERN axis2_socket_t AXIS2_CALL
+axutil_network_handler_create_server_socket(
+ const axutil_env_t *env,
+ int port)
+{
+ axis2_socket_t sock = AXIS2_INVALID_SOCKET;
+ axis2_socket_t i = 0;
+ struct sockaddr_in sock_addr;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+#if defined(WIN32)
+ if (is_init_socket == 0)
+ {
+ axis2_init_socket();
+ is_init_socket = 1;
+ }
+#endif
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+
+#ifndef WIN32
+ if(sock < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+#else
+ if (sock == INVALID_SOCKET)
+ {
+ axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ return AXIS2_INVALID_SOCKET;
+ }
+#endif
+ /* Address re-use */
+ i = 1;
+#if defined(WIN32)
+ setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &i, sizeof(axis2_socket_t)); /*casted 4th param to char* */
+#else
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(axis2_socket_t)); /*casted 4th param to char* */
+#endif
+
+ /* Exec behaviour */
+ AXIS2_CLOSE_SOCKET_ON_EXIT(sock) memset(&sock_addr, 0, sizeof(sock_addr));
+
+ sock_addr.sin_family = AF_INET;
+ sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ sock_addr.sin_port = htons((axis2_unsigned_short_t)port);
+
+ /* Bind the socket to our port number */
+ if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+ if(listen(sock, 50) < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_LISTEN_FAILED, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+ return sock;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_network_handler_close_socket(
+ const axutil_env_t *env,
+ axis2_socket_t socket)
+{
+ int i = 0;
+ char buf[32];
+ if(socket < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+ shutdown(socket, AXIS2_SHUT_WR);
+ axutil_network_handler_set_sock_option(env, socket, SO_RCVTIMEO, 1);
+ i = recv(socket, buf, 32, 0);
+ AXIS2_CLOSE_SOCKET(socket);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_network_handler_set_sock_option(
+ const axutil_env_t *env,
+ axis2_socket_t socket,
+ int option,
+ int value)
+{
+ if(option == SO_RCVTIMEO || option == SO_SNDTIMEO)
+ {
+#if defined(WIN32)
+ DWORD tv = value; /* windows expects milliseconds in a DWORD */
+#else
+ struct timeval tv;
+ /* we deal with milliseconds */
+ tv.tv_sec = value / 1000;
+ tv.tv_usec = (value % 1000) * 1000;
+#endif
+ setsockopt(socket, SOL_SOCKET, option, (char *)&tv, sizeof(tv));
+ return AXIS2_SUCCESS;
+ }
+ else if(option == SO_REUSEADDR)
+ {
+ if((setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value))) < 0)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_socket_t AXIS2_CALL
+axutil_network_handler_svr_socket_accept(
+ const axutil_env_t *env,
+ axis2_socket_t svr_socket)
+{
+ struct sockaddr cli_addr;
+ struct linger ll;
+ int nodelay = 1;
+ axis2_socket_len_t cli_len = 0;
+ axis2_socket_t cli_socket = AXIS2_INVALID_SOCKET;
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+
+ cli_len = sizeof(cli_addr);
+ cli_socket = accept(svr_socket, (struct sockaddr *)&cli_addr, &cli_len);
+#ifndef WIN32
+ if(cli_socket < 0)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[Axis2][network_handler] Socket accept \
+ failed");
+ }
+#else
+ if (cli_socket == INVALID_SOCKET)
+ {
+ axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ }
+#endif
+
+ setsockopt(svr_socket, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, (int)sizeof(nodelay));
+ /* We are sure that the difference lies within the int range */
+ ll.l_onoff = 1;
+ ll.l_linger = 5;
+ setsockopt(cli_socket, SOL_SOCKET, SO_LINGER, (const char *)&ll, (int)sizeof(struct linger));
+ /* We are sure that the difference lies within the int range */
+ return cli_socket;
+}
+
+#if defined (WIN32)
+axis2_bool_t
+axis2_init_socket(
+)
+{
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int err;
+ wVersionRequested = MAKEWORD(2, 2);
+
+ err = WSAStartup(wVersionRequested, &wsaData);
+
+ if (err != 0)
+ return 0; /* WinSock 2.2 not found */
+
+ /* Confirm that the WinSock DLL supports 2.2.
+ * Note that if the DLL supports versions greater
+ * than 2.2 in addition to 2.2, it will still return
+ * 2.2 in wVersion since that is the version we
+ * requested.
+ */
+
+ if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
+ {
+ WSACleanup();
+ return 0; /* WinSock 2.2 not supported */
+ }
+ return 1;
+}
+#endif
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axutil_network_handler_get_svr_ip(
+ const axutil_env_t *env,
+ axis2_socket_t socket)
+{
+ struct sockaddr_in addr;
+ axis2_socket_len_t len = sizeof(addr);
+ char *ret = NULL;
+ memset(&addr, 0, sizeof(addr));
+ if(getsockname(socket, (struct sockaddr *)&addr, &len) < 0)
+ {
+ return NULL;
+ }
+ ret = inet_ntoa(addr.sin_addr);
+ return ret;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axutil_network_handler_get_peer_ip(
+ const axutil_env_t *env,
+ axis2_socket_t socket)
+{
+ struct sockaddr_in addr;
+ axis2_socket_len_t len = sizeof(addr);
+ char *ret = NULL;
+ memset(&addr, 0, sizeof(addr));
+ if(getpeername(socket, (struct sockaddr *)&addr, &len) < 0)
+ {
+ return NULL;
+ }
+ ret = inet_ntoa(addr.sin_addr);
+ return ret;
+}
+
+AXIS2_EXTERN axis2_socket_t AXIS2_CALL
+axutil_network_handler_create_dgram_svr_socket(
+ const axutil_env_t *env,
+ int port)
+{
+ axis2_socket_t sock = AXIS2_INVALID_SOCKET;
+ struct sockaddr_in sock_addr;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+#if defined(WIN32)
+ if (is_init_socket == 0)
+ {
+ axis2_init_socket();
+ is_init_socket = 1;
+ }
+#endif
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+#ifndef WIN32
+ if(sock < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+#else
+ if (sock == INVALID_SOCKET)
+ {
+ axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ return AXIS2_INVALID_SOCKET;
+ }
+#endif
+ /* Exec behaviour */
+ AXIS2_CLOSE_SOCKET_ON_EXIT(sock) memset(&sock_addr, 0, sizeof(sock_addr));
+
+ sock_addr.sin_family = AF_INET;
+ sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ sock_addr.sin_port = htons((axis2_unsigned_short_t)port);
+
+ /* Bind the socket to our port number */
+ if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+ return sock;
+}
+
+AXIS2_EXTERN axis2_socket_t AXIS2_CALL
+axutil_network_handler_open_dgram_socket(
+ const axutil_env_t *env)
+{
+ axis2_socket_t sock = AXIS2_INVALID_SOCKET;
+#if defined(WIN32)
+ if (is_init_socket == 0)
+ {
+ axis2_init_socket();
+ is_init_socket = 1;
+ }
+#endif
+
+#ifndef WIN32
+ if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ /*AF_INET is not defined in sys/socket.h but PF_INET */
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+#else
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
+ /* In Win 32 if the socket creation failed it return 0 not a negative value */
+ {
+ char buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ /* Get the detailed error message */
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+#endif
+ return sock;
+}
+
+/*
+ * This function blocks until data is available to read from the socket
+ * and read all the data in the socket. If the buffer size specified is
+ * lesser than the actual data a failure will be returned.
+ */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_network_handler_read_dgram(
+ const axutil_env_t *env,
+ axis2_socket_t sock,
+ axis2_char_t *buffer,
+ int *buf_len,
+ axis2_char_t **addr,
+ int *port)
+{
+ struct sockaddr_in sender_address;
+ int received = 0;
+ unsigned int sender_address_size = sizeof(sender_address);
+
+ received = recvfrom(sock, buffer, *buf_len, 0, (struct sockaddr *)&sender_address,
+ &sender_address_size);
+
+#ifdef WIN32
+ if (SOCKET_ERROR == received)
+ {
+ axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ return AXIS2_FAILURE;
+ }
+#else
+ if(received < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+#endif
+ if(port && addr)
+ {
+ *port = ntohs(sender_address.sin_port);
+ *addr = inet_ntoa(sender_address.sin_addr);
+ }
+ *buf_len = received;
+ return AXIS2_SUCCESS;
+}
+
+/*
+ * Sends a datagram to the specified location.
+ */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_network_handler_send_dgram(
+ const axutil_env_t *env,
+ axis2_socket_t sock,
+ axis2_char_t *buff,
+ int *buf_len,
+ axis2_char_t *addr,
+ int dest_port,
+ int *source_port)
+{
+ struct sockaddr_in recv_addr, source_addr;
+ int send_bytes = 0;
+ unsigned int recv_addr_size = 0;
+ unsigned int source_addr_size = sizeof(source_addr);
+ recv_addr_size = sizeof(recv_addr);
+
+ memset(&recv_addr, 0, sizeof(recv_addr));
+ memset(&recv_addr, 0, sizeof(source_addr));
+
+ recv_addr.sin_addr.s_addr = inet_addr(addr);
+ if(recv_addr.sin_addr.s_addr == AXIS2_INADDR_NONE) /*netinet/in.h */
+ {
+ /*
+ * server may be a host name
+ */
+ struct hostent *lphost = NULL;
+ lphost = gethostbyname(addr);
+
+ if(lphost)
+ {
+ recv_addr.sin_addr.s_addr = ((struct in_addr *)lphost->h_addr)->s_addr;
+ }
+ else
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ recv_addr.sin_family = AF_INET;
+ recv_addr.sin_port = htons((axis2_unsigned_short_t)dest_port);
+
+ send_bytes = sendto(sock, buff, *buf_len, 0, (struct sockaddr *)&recv_addr, recv_addr_size);
+
+ getsockname(sock, (struct sockaddr *)&source_addr, &source_addr_size);
+
+#ifdef WIN32
+ if (send_bytes == SOCKET_ERROR)
+ {
+ axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ return AXIS2_FAILURE;
+ }
+#else
+ if(send_bytes < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+#endif
+ if(source_port)
+ {
+ *source_port = ntohs(source_addr.sin_port);
+ }
+ *buf_len = send_bytes;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_network_handler_bind_socket(
+ const axutil_env_t *env,
+ axis2_socket_t sock,
+ int port)
+{
+ struct sockaddr_in source_addr;
+
+ memset(&source_addr, 0, sizeof(source_addr));
+ source_addr.sin_family = AF_INET;
+ source_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ source_addr.sin_port = htons((axis2_unsigned_short_t)port);
+#ifdef WIN32
+ if (bind(sock, (struct sockaddr *)&source_addr, sizeof(source_addr)) == SOCKET_ERROR)
+ {
+ axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ return AXIS2_FAILURE;
+ }
+#else
+ if(bind(sock, (struct sockaddr *)&source_addr, sizeof(source_addr)) < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+#endif
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_socket_t AXIS2_CALL
+axutil_network_hadler_create_multicast_svr_socket(
+ const axutil_env_t *env,
+ int port,
+ axis2_char_t *mul_addr)
+{
+ axis2_socket_t sock = AXIS2_INVALID_SOCKET;
+ struct sockaddr_in sock_addr;
+ struct ip_mreq mc_req;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+#if defined(WIN32)
+ if (is_init_socket == 0)
+ {
+ axis2_init_socket();
+ is_init_socket = 1;
+ }
+#endif
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+#ifndef WIN32
+ if(sock < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+#else
+ if (sock == INVALID_SOCKET)
+ {
+ axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ return AXIS2_FAILURE;
+ }
+#endif
+
+ /* Exec behaviour */
+ AXIS2_CLOSE_SOCKET_ON_EXIT(sock) memset(&sock_addr, 0, sizeof(sock_addr));
+
+ sock_addr.sin_family = AF_INET;
+ sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ sock_addr.sin_port = htons((axis2_unsigned_short_t)port);
+
+ /* Bind the socket to our port number */
+ if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE);
+ return AXIS2_INVALID_SOCKET;
+ }
+
+ /* Send an IGMP request to join the multicast group */
+ mc_req.imr_multiaddr.s_addr = inet_addr(mul_addr);
+ mc_req.imr_interface.s_addr = htonl(INADDR_ANY);
+#ifdef WIN32
+ if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mc_req, sizeof(mc_req))) == SOCKET_ERROR)
+ {
+ axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
+ axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
+ return AXIS2_FAILURE;
+ }
+#else
+ if((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mc_req, sizeof(mc_req))) < 0)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+#endif
+ return sock;
+}
+
diff --git a/util/src/param.c b/util/src/param.c new file mode 100644 index 0000000..48e14ae --- /dev/null +++ b/util/src/param.c @@ -0,0 +1,302 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_param.h> +#include <axutil_utils.h> +#include <axutil_string.h> +#include <axutil_generic_obj.h> + +struct axutil_param +{ + /** Parameter name */ + axis2_char_t *name; + + /** Parameter value */ + void *value; + + /** Parameter locked? */ + axis2_bool_t locked; + + /** Parameter type */ + int type; /*default is AXIS2_TEXT_PARAM */ + axutil_hash_t *attrs; + axutil_array_list_t *value_list; + void( + AXIS2_CALL *value_free) ( + void *param_value, + const axutil_env_t *env); +}; + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axutil_param_create( + const axutil_env_t *env, + axis2_char_t *name, + void *value) +{ + axutil_param_t *param = NULL; + AXIS2_ENV_CHECK(env, NULL); + + param = AXIS2_MALLOC(env->allocator, sizeof(axutil_param_t)); + if(!param) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Not enough memory"); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + return NULL; + } + + param->name = axutil_strdup(env, name); + param->value = value; /* shallow copy. */ + param->locked = AXIS2_FALSE; + param->type = AXIS2_TEXT_PARAM; + param->attrs = NULL; + param->value_list = NULL; + param->value_free = NULL; + + return param; +} + +axis2_char_t *AXIS2_CALL +axutil_param_get_name( + axutil_param_t *param, + const axutil_env_t *env) +{ + return param->name; +} + +void *AXIS2_CALL +axutil_param_get_value( + axutil_param_t *param, + const axutil_env_t *env) +{ + return param->value; +} + +axis2_status_t AXIS2_CALL +axutil_param_set_name( + axutil_param_t *param, + const axutil_env_t *env, + const axis2_char_t *name) +{ + param->name = axutil_strdup(env, name); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axutil_param_set_value( + axutil_param_t *param, + const axutil_env_t *env, + const void *value) +{ + void *param_value = NULL; + param_value = axutil_param_get_value(param, env); + if(param_value) + { + if(param && param->value_free) + { + param->value_free(param_value, env); + } + else /* we assume that param value is axis2_char_t* */ + { + AXIS2_FREE(env->allocator, param_value); + } + } + param->value = (void *)value; + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axutil_param_is_locked( + axutil_param_t *param, + const axutil_env_t *env) +{ + return param->locked; +} + +axis2_status_t AXIS2_CALL +axutil_param_set_locked( + axutil_param_t *param, + const axutil_env_t *env, + axis2_bool_t value) +{ + param->locked = value; + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +axutil_param_get_param_type( + axutil_param_t *param, + const axutil_env_t *env) +{ + return param->type; +} + +axis2_status_t AXIS2_CALL +axutil_param_set_param_type( + axutil_param_t *param, + const axutil_env_t *env, + int type) +{ + param->type = type; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axutil_param_set_attributes( + axutil_param_t *param, + const axutil_env_t *env, + axutil_hash_t *attrs) +{ + AXIS2_PARAM_CHECK(env->error, attrs, AXIS2_FAILURE); + + if(param->attrs) + { + axutil_hash_index_t *i = NULL; + void *v = NULL; + + for(i = axutil_hash_first(param->attrs, env); i; i = axutil_hash_next(env, i)) + { + axutil_hash_this(i, NULL, NULL, &v); + axutil_generic_obj_free(v, env); + } + axutil_hash_free(param->attrs, env); + } + + param->attrs = attrs; + return AXIS2_SUCCESS; +} + +axutil_hash_t *AXIS2_CALL +axutil_param_get_attributes( + axutil_param_t *param, + const axutil_env_t *env) +{ + return param->attrs; +} + +axis2_status_t AXIS2_CALL +axutil_param_set_value_list( + axutil_param_t *param, + const axutil_env_t *env, + axutil_array_list_t *value_list) +{ + AXIS2_PARAM_CHECK(env->error, value_list, AXIS2_FAILURE); + + if(param->value_list) + { + int i = 0, size = 0; + + size = axutil_array_list_size(param->value_list, env); + for(i = 0; i < size; i++) + { + axutil_param_t *param = NULL; + + param = (axutil_param_t *)axutil_array_list_get(param->value_list, env, i); + axutil_param_free(param, env); + } + axutil_array_list_free(param->value_list, env); + } + param->value_list = value_list; + + return AXIS2_SUCCESS; +} + +axutil_array_list_t *AXIS2_CALL +axutil_param_get_value_list( + axutil_param_t *param, + const axutil_env_t *env) +{ + return param->value_list; +} + +void AXIS2_CALL +axutil_param_free( + axutil_param_t *param, + const axutil_env_t *env) +{ + void *param_value = NULL; + axis2_char_t *param_name = NULL; + + param_value = axutil_param_get_value(param, env); + if(param_value) + { + if(param && param->value_free) + { + param->value_free(param_value, env); + } + else /* we assume that param value is axis2_char_t* */ + { + AXIS2_FREE(env->allocator, param_value); + } + } + + if(param->attrs) + { + axutil_hash_index_t *i = NULL; + void *v = NULL; + + for(i = axutil_hash_first(param->attrs, env); i; i = axutil_hash_next(env, i)) + { + axutil_hash_this(i, NULL, NULL, &v); + axutil_generic_obj_free(v, env); + } + axutil_hash_free(param->attrs, env); + } + + if(param->value_list) + { + int i = 0, size = 0; + + size = axutil_array_list_size(param->value_list, env); + for(i = 0; i < size; i++) + { + axutil_param_t *param_l = NULL; + + param_l = (axutil_param_t *)axutil_array_list_get(param->value_list, env, i); + if(param_l) + { + axutil_param_free(param_l, env); + } + } + axutil_array_list_free(param->value_list, env); + } + param_name = axutil_param_get_name(param, env); + AXIS2_FREE(env->allocator, param_name); + AXIS2_FREE(env->allocator, param); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_param_set_value_free( + axutil_param_t *param, + const axutil_env_t *env, + AXIS2_PARAM_VALUE_FREE free_fn) +{ + param->value_free = free_fn; + return AXIS2_SUCCESS; +} + +/* Use this function for the copied parameters + * to avoid double free + */ +AXIS2_EXTERN void AXIS2_CALL +axutil_param_dummy_free_fn( + void *param, + const axutil_env_t *env) +{ + return; +} diff --git a/util/src/param_container.c b/util/src/param_container.c new file mode 100644 index 0000000..8d9f188 --- /dev/null +++ b/util/src/param_container.c @@ -0,0 +1,228 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_param_container.h> + +struct axutil_param_container +{ + axutil_hash_t *params; + axutil_array_list_t *params_list; +}; + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axutil_param_container_create( + const axutil_env_t *env) +{ + axutil_param_container_t *param_container = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + param_container = (axutil_param_container_t *)AXIS2_MALLOC(env->allocator, + sizeof(axutil_param_container_t)); + + if(!param_container) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Not enough memory"); + return NULL; + } + + param_container->params = NULL; + param_container->params_list = NULL; + param_container->params_list = axutil_array_list_create(env, 0); + + param_container->params = axutil_hash_make(env); + if(!param_container->params) + { + axutil_param_container_free(param_container, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Not enough memory"); + return NULL; + } + + return param_container; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_param_container_free( + axutil_param_container_t *param_container, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(param_container->params) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(param_container->params, env); hi; hi + = axutil_hash_next(env, hi)) + { + axutil_param_t *param = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + param = (axutil_param_t *)val; + if(param) + { + axutil_param_free(param, env); + param = NULL; + } + val = NULL; + } + axutil_hash_free(param_container->params, env); + } + if(param_container->params_list) + { + /* This is the array list which is returned when all params are + * requested from param_container. Params referenced here are + * actually contained in params hash table + */ + axutil_array_list_free(param_container->params_list, env); + param_container->params_list = NULL; + } + + AXIS2_FREE(env->allocator, param_container); + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_param_container_free_void_arg( + void *param_container, + const axutil_env_t *env) +{ + axutil_param_container_t *param_container_l = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + param_container_l = (axutil_param_container_t *)param_container; + axutil_param_container_free(param_container_l, env); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_param_container_add_param( + axutil_param_container_t *param_container, + const axutil_env_t *env, + axutil_param_t *param) +{ + axis2_char_t *param_name = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FAILURE); + + if(!(param_container->params)) + { + param_container->params = axutil_hash_make(env); + if(!param_container->params) + { + return AXIS2_FAILURE; + } + } + param_name = axutil_param_get_name(param, env); + if(!param_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid param state"); + return AXIS2_FAILURE; + } + axutil_hash_set(param_container->params, param_name, AXIS2_HASH_KEY_STRING, param); + axutil_array_list_add(param_container->params_list, env, param); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axutil_param_container_get_param( + axutil_param_container_t *param_container, + const axutil_env_t *env, + const axis2_char_t *name) +{ + return (axutil_param_t *)(axutil_hash_get(param_container->params, name, AXIS2_HASH_KEY_STRING)); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axutil_param_container_get_params( + axutil_param_container_t *param_container, + const axutil_env_t *env) +{ + if(param_container->params_list) + { + return param_container->params_list; + }else + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + param_container->params_list = axutil_array_list_create(env, 0); + + for(hi = axutil_hash_first(param_container->params, env); hi; hi + = axutil_hash_next(env, hi)) + { + axutil_param_t *param = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + param = (axutil_param_t *)val; + if(param) + { + axutil_array_list_add(param_container->params_list, env, param); + } + } + } + return param_container->params_list; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_param_container_is_param_locked( + axutil_param_container_t *param_container, + const axutil_env_t *env, + const axis2_char_t *param_name) +{ + axutil_param_t *param = NULL; + + param = (axutil_param_t *)(axutil_hash_get(param_container->params, param_name, + AXIS2_HASH_KEY_STRING)); + if(!param) + { + /* In this case we consider param is not locked */ + return AXIS2_FALSE; + } + return axutil_param_is_locked(param, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_param_container_delete_param( + axutil_param_container_t *param_container, + const axutil_env_t *env, + const axis2_char_t *param_name) +{ + axutil_param_t *param = NULL; + + if(!param_name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "The requested parameter does not exist"); + return AXIS2_FAILURE; + } + param = axutil_hash_get(param_container->params, param_name, AXIS2_HASH_KEY_STRING); + if(param) + { + /** Parameter exists, So remove it from hash table and delete the array list param_list + which will be built in the next call to get_params + */ + axutil_hash_set(param_container->params, param_name, AXIS2_HASH_KEY_STRING, NULL); + axutil_param_free(param, env); + axutil_array_list_free(param_container->params_list, env); + param_container->params_list = NULL; + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} diff --git a/util/src/platforms/unix/Makefile.am b/util/src/platforms/unix/Makefile.am new file mode 100644 index 0000000..6506a01 --- /dev/null +++ b/util/src/platforms/unix/Makefile.am @@ -0,0 +1,8 @@ +noinst_LTLIBRARIES = libaxis2_unix.la + +libaxis2_unix_la_SOURCES = uuid_gen_unix.c\ + thread_unix.c date_time_util_unix.c + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/include/platforms \ + -I$(top_builddir)/include/platforms/unix diff --git a/util/src/platforms/unix/date_time_util_unix.c b/util/src/platforms/unix/date_time_util_unix.c new file mode 100644 index 0000000..e0c4a28 --- /dev/null +++ b/util/src/platforms/unix/date_time_util_unix.c @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <platforms/unix/axutil_date_time_util_unix.h> + +AXIS2_EXTERN int AXIS2_CALL +axis2_platform_get_milliseconds() +{ + struct timeb t_current; + int milliseconds; + + ftime(&t_current); + milliseconds = t_current.millitm; + + return milliseconds; + +} diff --git a/util/src/platforms/unix/thread_unix.c b/util/src/platforms/unix/thread_unix.c new file mode 100644 index 0000000..ccedd06 --- /dev/null +++ b/util/src/platforms/unix/thread_unix.c @@ -0,0 +1,362 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <config.h> +#include "axutil_thread_unix.h" + +AXIS2_EXTERN axutil_threadattr_t *AXIS2_CALL +axutil_threadattr_create( + axutil_allocator_t * allocator) +{ + int stat = 0; + axutil_threadattr_t *new = NULL; + + new = AXIS2_MALLOC(allocator, sizeof(axutil_threadattr_t)); + if(!new) + { + return NULL; + } + stat = pthread_attr_init(&(new->attr)); + + if(stat != 0) + { + AXIS2_FREE(allocator, new); + return NULL; + } + return new; +} + +/* Destroy the threadattr object */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +threadattr_cleanup( + void *data) +{ + axutil_threadattr_t *attr = data; + int rv; + + rv = pthread_attr_destroy(&(attr->attr)); + + if(0 != rv) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +#define DETACH_ARG(v) ((v) ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE) + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_detach_set( + axutil_threadattr_t * attr, + axis2_bool_t detached) +{ + if(0 == pthread_attr_setdetachstate(&(attr->attr), DETACH_ARG(detached))) + { + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_detach_get( + axutil_threadattr_t * attr) +{ + int state = 0; + pthread_attr_getdetachstate(&(attr->attr), &state); + if(state == 1) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +static void * +dummy_worker( + void *opaque) +{ + axutil_thread_t *thread = (axutil_thread_t *)opaque; + return thread->func(thread, thread->data); +} + +AXIS2_EXTERN axutil_thread_t *AXIS2_CALL +axutil_thread_create( + axutil_allocator_t * allocator, + axutil_threadattr_t * attr, + axutil_thread_start_t func, + void *data) +{ + axis2_status_t stat; + pthread_attr_t *temp = NULL; + axutil_thread_t *new = NULL; + + new = (axutil_thread_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_t)); + + if(!new) + { + return NULL; + } + new->td = (pthread_t *)AXIS2_MALLOC(allocator, sizeof(pthread_t)); + if(!new->td) + { + return NULL; + } + + new->data = data; + new->func = func; + new->try_exit = AXIS2_FALSE; + + if(attr) + { + temp = &(attr->attr); + } + else + { + temp = NULL; + } + + if((stat = pthread_create(new->td, temp, dummy_worker, new)) == 0) + { + return new; + } + return NULL; +} + +AXIS2_EXTERN axis2_os_thread_t AXIS2_CALL +axis2_os_thread_current( + void) +{ + return pthread_self(); +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_os_thread_equal( + axis2_os_thread_t tid1, + axis2_os_thread_t tid2) +{ + return pthread_equal(tid1, tid2); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_exit( + axutil_thread_t * thd, + axutil_allocator_t * allocator) +{ + axis2_bool_t same_thread = AXIS2_TRUE; + if(thd) + { + while(!thd->try_exit) + { + sleep(1); + } + + if(thd->td) + { + same_thread = pthread_equal(pthread_self(), *thd->td); + if(!same_thread) + { + pthread_kill(*(thd->td), 0); + axutil_thread_join(thd); + } + AXIS2_FREE(allocator, thd->td); + } + AXIS2_FREE(allocator, thd); + } + if(same_thread) + { + pthread_exit(NULL); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_join( + axutil_thread_t * thd) +{ + void *thread_stat; + if(0 == pthread_join(*(thd->td), (void *)(&thread_stat))) + { + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_detach( + axutil_thread_t * thd) +{ + if(0 == pthread_detach(*(thd->td))) + { + thd->try_exit = AXIS2_TRUE; + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +void +axutil_thread_yield( + void) +{ + return; +} + +/** + * function is used to allocate a new key. This key now becomes valid for all threads in our process. + * When a key is created, the value it points to defaults to NULL. Later on each thread may change + * its copy of the value as it wishes. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_key_create( + axutil_threadkey_t * axis2_key) +{ + int rc = -1; + pthread_key_t key = axis2_key->key; + rc = pthread_key_create(&key, NULL); + if(0 == rc) + return AXIS2_SUCCESS; + else + return AXIS2_FAILURE; +} + +/** + * This function is used to get the value of a given key + * @return void*. A key's value is simply a void pointer (void*) + */ +AXIS2_EXTERN void *AXIS2_CALL +axutil_thread_getspecific( + axutil_threadkey_t * axis2_key) +{ + void *value = NULL; + pthread_key_t key = axis2_key->key; + value = pthread_getspecific(key); + return value; +} + +/** + * This function is used to get the value of a given key + * @param keys value. A key's value is simply a void pointer (void*), so we can + * store in it anything that we want + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_setspecific( + axutil_threadkey_t * axis2_key, + void *value) +{ + int rc = -1; + pthread_key_t key = axis2_key->key; + rc = pthread_setspecific(key, value); + if(0 == rc) + return AXIS2_SUCCESS; + else + return AXIS2_FAILURE; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_thread_key_free( + axutil_threadkey_t * axis2_key) +{ + pthread_key_t key = axis2_key->key; + pthread_key_delete(key); +} + +AXIS2_EXTERN axis2_os_thread_t *AXIS2_CALL +axis2_os_thread_get( + axutil_thread_t * thd) +{ + if(!thd) + { + return NULL; + } + return thd->td; +} + +AXIS2_EXTERN axutil_thread_once_t *AXIS2_CALL +axutil_thread_once_init( + axutil_allocator_t * allocator) +{ +#if defined(AXIS2_SOLARIS) && (__GNUC__ <= 3) + static const pthread_once_t once_init = + { PTHREAD_ONCE_INIT}; +#else + static const pthread_once_t once_init = PTHREAD_ONCE_INIT; +#endif + axutil_thread_once_t *control = AXIS2_MALLOC(allocator, sizeof(axutil_thread_once_t)); + if(!control) + { + return NULL;; + } + (control)->once = once_init; + return control; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_once( + axutil_thread_once_t * control, + void + (*func)( + void)) +{ + return pthread_once(&(control->once), func); +} + +/*************************Thread locking functions*****************************/ +AXIS2_EXTERN axutil_thread_mutex_t *AXIS2_CALL +axutil_thread_mutex_create( + axutil_allocator_t * allocator, + unsigned int flags) +{ + axutil_thread_mutex_t *new_mutex = NULL; + + new_mutex = AXIS2_MALLOC(allocator, sizeof(axutil_thread_mutex_t)); + new_mutex->allocator = allocator; + + if(pthread_mutex_init(&(new_mutex->mutex), NULL) != 0) + { + AXIS2_FREE(allocator, new_mutex); + return NULL; + } + return new_mutex; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_lock( + axutil_thread_mutex_t * mutex) +{ + return pthread_mutex_lock(&(mutex->mutex)); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_unlock( + axutil_thread_mutex_t * mutex) +{ + if(pthread_mutex_unlock(&(mutex->mutex)) != 0) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_destroy( + axutil_thread_mutex_t * mutex) +{ + if(0 != pthread_mutex_destroy(&(mutex->mutex))) + { + return AXIS2_FAILURE; + } + AXIS2_FREE(mutex->allocator, mutex); + return AXIS2_SUCCESS; +} diff --git a/util/src/platforms/unix/uuid_gen_unix.c b/util/src/platforms/unix/uuid_gen_unix.c new file mode 100644 index 0000000..cdc2544 --- /dev/null +++ b/util/src/platforms/unix/uuid_gen_unix.c @@ -0,0 +1,345 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <config.h> + +#include <sys/ioctl.h> +#include <string.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <netdb.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> + +#ifdef HAVE_LINUX_IF_H +# include <linux/if.h> +#else +# ifdef HAVE_NET_IF_H +# include <sys/sockio.h> +# include <net/if.h> +# include <net/if_arp.h> +# endif +# ifdef HAVE_NET_IF_TYPES_H +# include <net/if_types.h> +# endif +# ifdef HAVE_NET_IF_DL_H +# include <net/if_dl.h> +# endif +#endif +#ifdef HAVE_GETIFADDRS +#include <ifaddrs.h> +#endif +#include <platforms/unix/axutil_uuid_gen_unix.h> +#include <platforms/axutil_platform_auto_sense.h> + +/* We need these static variables to track throughout the program execution */ +static axis2_bool_t axutil_uuid_gen_is_first = AXIS2_TRUE; +static struct axutil_uuid_st axutil_uuid_static; + +axutil_uuid_t *AXIS2_CALL +axutil_uuid_gen_v1() +{ + struct timeval time_now; + struct timeval tv; + unsigned long long time_val; + unsigned long long time_val2; + unsigned short int clck = 0; + axutil_uuid_t *ret_uuid = NULL; + unsigned short int time_high_version = 0; + + if(AXIS2_TRUE == axutil_uuid_gen_is_first) + { + char *mac_addr = axutil_uuid_get_mac_addr(); + memcpy(axutil_uuid_static.mac, mac_addr, 6); + axutil_uuid_static.time_seq = 0; + axutil_uuid_static.clock = 0; + free(mac_addr); + axutil_uuid_gen_is_first = AXIS2_FALSE; + } + /* + * GENERATE TIME + */ + + /* determine current system time and sequence counter */ + if(gettimeofday(&time_now, NULL) == -1) + return NULL; + + /* check whether system time changed since last retrieve */ + if(!(time_now.tv_sec == axutil_uuid_static.time_last.tv_sec && time_now.tv_usec + == axutil_uuid_static.time_last.tv_usec)) + { + /* reset time sequence counter and continue */ + axutil_uuid_static.time_seq = 0; + } + + /* until we are out of UUIDs per tick, increment + the time/tick sequence counter and continue */ + while(axutil_uuid_static.time_seq < UUIDS_PER_TICK) + { + axutil_uuid_static.time_seq++; + } + /* sleep for 1000ns (1us) */ + tv.tv_sec = 0; + tv.tv_usec = 1; + /* + The following select causes severe performance problems. + Hence commenting out. I am not sure why this is required. - Samisa. + select(0, NULL, NULL, NULL, &tv); */ + + time_val = (unsigned long long)time_now.tv_sec * 10000000ull; + time_val += (unsigned long long)time_now.tv_usec * 10ull; + + ret_uuid = malloc(sizeof(axutil_uuid_t)); + + time_val += UUID_TIMEOFFSET; + /* compensate for low resolution system clock by adding + the time/tick sequence counter */ + if(axutil_uuid_static.time_seq > 0) + time_val += (unsigned long long)axutil_uuid_static.time_seq; + + time_val2 = time_val; + ret_uuid->time_low = (unsigned long)time_val2; + time_val2 >>= 32; + ret_uuid->time_mid = (unsigned short int)time_val2; + time_val2 >>= 16; + time_high_version = (unsigned short int)time_val2; + + /* store the 60 LSB of the time in the UUID and make version 1 */ + time_high_version <<= 4; + time_high_version &= 0xFFF0; + time_high_version |= 0x0001; + ret_uuid->time_high_version = time_high_version; + + /* + * GENERATE CLOCK + */ + + /* retrieve current clock sequence */ + clck = axutil_uuid_static.clock; + + /* generate new random clock sequence (initially or if the + time has stepped backwards) or else just increase it */ + if(clck == 0 || (time_now.tv_sec < axutil_uuid_static.time_last.tv_sec || (time_now.tv_sec + == axutil_uuid_static.time_last.tv_sec && time_now.tv_usec + < axutil_uuid_static.time_last.tv_usec))) + { + srand(time_now.tv_usec); + clck = rand(); + } + else + { + clck++; + } + clck %= (2 << 14); + + /* store back new clock sequence */ + axutil_uuid_static.clock = clck; + + clck &= 0x1FFF; + clck |= 0x2000; + + /* + * FINISH + */ + /* remember current system time for next iteration */ + axutil_uuid_static.time_last.tv_sec = time_now.tv_sec; + axutil_uuid_static.time_last.tv_usec = time_now.tv_usec; + + if(!ret_uuid) + { + return NULL; + } + ret_uuid->clock_variant = clck; + memcpy(ret_uuid->mac_addr, axutil_uuid_static.mac, 6); + return ret_uuid; +} + +axis2_char_t *AXIS2_CALL +axutil_platform_uuid_gen( + char *s) +{ + axutil_uuid_t *uuid_struct = NULL; + axis2_char_t *uuid_str = NULL; + unsigned char mac[7]; + char mac_hex[13]; + + if(!s) + { + return NULL; + } + uuid_struct = axutil_uuid_gen_v1(); + if(!uuid_struct) + { + return NULL; + } + uuid_str = s; + if(!uuid_str) + { + return NULL; + } + memcpy(mac, uuid_struct->mac_addr, 6); + sprintf(mac_hex, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + sprintf(uuid_str, "%08x-%04x-%04x-%04x-%s", uuid_struct->time_low, uuid_struct->time_mid, + uuid_struct->time_high_version, uuid_struct->clock_variant, mac_hex); + free(uuid_struct); + uuid_struct = NULL; + return uuid_str; +} + +#ifdef HAVE_LINUX_IF_H /* Linux */ + +char *AXIS2_CALL +axutil_uuid_get_mac_addr( +) +{ + struct ifreq ifr; + struct ifreq *IFR; + struct ifconf ifc; + struct sockaddr *sa; + int s = 0; + int i = 0; + char *buffer = NULL; + char buf[1024]; + int ok = AXIS2_FALSE; + + if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + return NULL; + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + ioctl(s, SIOCGIFCONF, &ifc); + IFR = ifc.ifc_req; + + for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++) + { + strcpy(ifr.ifr_name, IFR->ifr_name); + /*sprintf(ifr.ifr_name, "eth0"); */ + if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) + { + if (!(ifr.ifr_flags & IFF_LOOPBACK)) + { + if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) + { + ok = AXIS2_TRUE; + break; + } + } + } + } + buffer = (char *) malloc(6 * sizeof(char)); + if (ok) + { + sa = (struct sockaddr *) &ifr.ifr_addr; + for (i = 0; i < 6; i++) + buffer[i] = (unsigned char) (sa->sa_data[i] & 0xff); + } + else + { + for (i = 0; i < 6; i++) + buffer[i] = (unsigned char) ((AXIS2_LOCAL_MAC_ADDR[i]) - '0'); + } + close(s); + return buffer; +} + +#else + +#ifdef HAVE_GETIFADDRS /* NetBSD, MacOSX, etc... */ + +#ifndef max +# define max(a,b) ((a) > (b) ? (a) : (b)) +#endif /* !max */ + +char *AXIS2_CALL +axutil_uuid_get_mac_addr( +) +{ + struct ifaddrs *ifap; + struct ifaddrs *ifap_head; + const struct sockaddr_dl *sdl; + unsigned char *ucp; + int i; + char *data_ptr; + + if (getifaddrs(&ifap_head) < 0) + return NULL; + for (ifap = ifap_head; ifap != NULL; ifap = ifap->ifa_next) + { + if (ifap->ifa_addr != NULL && ifap->ifa_addr->sa_family == AF_LINK) + { + sdl = (const struct sockaddr_dl *) (void *) ifap->ifa_addr; + ucp = (unsigned char *) (sdl->sdl_data + sdl->sdl_nlen); + if (sdl->sdl_alen > 0) + { + data_ptr = malloc(6 * sizeof(char)); + for (i = 0; i < 6 && i < sdl->sdl_alen; i++, ucp++) + data_ptr[i] = (unsigned char) (*ucp & 0xff); + + freeifaddrs(ifap_head); + return data_ptr; + } + } + } + freeifaddrs(ifap_head); + return NULL; +} +# else /* Solaris-ish */ + +/* code modified from that posted on: + * http://forum.sun.com/jive/thread.jspa?threadID=84804&tstart=30 + */ + +char *AXIS2_CALL +axutil_uuid_get_mac_addr() +{ + char hostname[MAXHOSTNAMELEN]; + char *data_ptr; + struct hostent *he; + struct arpreq ar; + struct sockaddr_in *sa; + int s; + int i; + + if(gethostname(hostname, sizeof(hostname)) < 0) + return NULL; + if((he = gethostbyname(hostname)) == NULL) + return NULL; + if((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + return NULL; + memset(&ar, 0, sizeof(ar)); + sa = (struct sockaddr_in *)((void *)&(ar.arp_pa)); + sa->sin_family = AF_INET; + memcpy(&(sa->sin_addr), *(he->h_addr_list), sizeof(struct in_addr)); + if(ioctl(s, SIOCGARP, &ar) < 0) + { + close(s); + return NULL; + } + close(s); + if(!(ar.arp_flags & ATF_COM)) + return NULL; + data_ptr = malloc(6 * sizeof(char)); + for(i = 0; i < 6; i++) + data_ptr[i] = (unsigned char)(ar.arp_ha.sa_data[i] & 0xff); + + return data_ptr; +} +# endif +#endif diff --git a/util/src/platforms/windows/axutil_windows.c b/util/src/platforms/windows/axutil_windows.c new file mode 100644 index 0000000..e2abb5d --- /dev/null +++ b/util/src/platforms/windows/axutil_windows.c @@ -0,0 +1,93 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <windows/axutil_windows.h>
+#include <stdio.h>
+
+
+/*
+
+std::string* getPlatformErrorMessage(long errorNumber)
+{
+ std::string* returningString = new std::string();
+ LPVOID lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ errorNumber,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL );
+
+ returningString->append((LPTSTR)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+
+ return returningString;
+}
+ */
+AXIS2_EXTERN HMODULE AXIS2_CALL
+callLoadLib(
+ char *lib)
+{
+ /* Disable display of the critical-error-handler message box */
+ SetErrorMode(SEM_FAILCRITICALERRORS);
+ return LoadLibraryEx(lib, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+}
+
+AXIS2_EXTERN struct tm *AXIS2_CALL
+axis2_win_gmtime(
+ const time_t * timep,
+ struct tm *result)
+{
+ return gmtime(timep);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axutil_win32_get_last_error(
+ axis2_char_t *buf,
+ unsigned int buf_size)
+{
+ LPVOID lpMsgBuf;
+ int rc = GetLastError();
+ sprintf(buf, "DLL Load Error %d: ", rc);
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, rc, 0,
+ (LPTSTR) & lpMsgBuf, 0, NULL);
+ if(lpMsgBuf)
+ {
+ strncat(buf, (char*)lpMsgBuf, buf_size - strlen(buf) - 1);
+ }
+ LocalFree(lpMsgBuf);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axutil_win32_get_last_wsa_error(
+ axis2_char_t *buf,
+ unsigned int buf_size)
+{
+ LPVOID lpMsgBuf;
+ int rc = WSAGetLastError();
+ sprintf(buf, "Winsock error %d: ", rc);
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, rc, 0,
+ (LPTSTR) & lpMsgBuf, 0, NULL);
+ if(lpMsgBuf)
+ {
+ strncat(buf, (char*)lpMsgBuf, buf_size - strlen(buf) - 1);
+ }
+ LocalFree(lpMsgBuf);
+}
diff --git a/util/src/platforms/windows/date_time_util_windows.c b/util/src/platforms/windows/date_time_util_windows.c new file mode 100644 index 0000000..c07903b --- /dev/null +++ b/util/src/platforms/windows/date_time_util_windows.c @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <platforms/windows/axutil_date_time_util_windows.h> + +AXIS2_EXTERN int AXIS2_CALL +axis2_platform_get_milliseconds() +{ + struct _timeb timebuffer; + char *timeline; + int milliseconds = 0; + + _ftime(&timebuffer); + timeline = ctime(&(timebuffer.time)); + milliseconds = timebuffer.millitm; + + return milliseconds; +} diff --git a/util/src/platforms/windows/dir_windows.c b/util/src/platforms/windows/dir_windows.c new file mode 100644 index 0000000..1e0ad8f --- /dev/null +++ b/util/src/platforms/windows/dir_windows.c @@ -0,0 +1,272 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <malloc.h> +#include <string.h> +#include <errno.h> + +#include <platforms/windows/axutil_dir_windows.h> + +/*dirent.h style mehtods for win32*/ + +AXIS2_DIR *AXIS2_CALL +axis2_opendir( + const char *_dirname) +{ + AXIS2_DIR *dirp; + char *filespec; + long handle; + int index; + + filespec = malloc(strlen(_dirname) + 2 + 1); + strcpy(filespec, _dirname); + index = (int)strlen(filespec) - 1; + if(index >= 0 && (filespec[index] == '/' || (filespec[index] == '\\' && !IsDBCSLeadByte( + filespec[index - 1])))) + filespec[index] = '\0'; + strcat(filespec, "/*"); + + dirp = (AXIS2_DIR *)malloc(sizeof(AXIS2_DIR)); + dirp->offset = 0; + dirp->finished = 0; + + if((handle = (long)_findfirst(filespec, &(dirp->fileinfo))) < 0) + /* We are sure that the difference lies within the long range */ + { + if(errno == ENOENT || errno == EINVAL) + dirp->finished = 1; + else + { + free(dirp); + free(filespec); + return NULL; + } + } + /* We are using the ISO C++ conformant name: _strdup, as demanded by VS 2005 */ + dirp->dirname = _strdup(_dirname); + dirp->handle = handle; + free(filespec); + + return dirp; +} + +int AXIS2_CALL +axis2_closedir( + AXIS2_DIR * _dirp) +{ + int iret = -1; + if(!_dirp) + return iret; + iret = _findclose(_dirp->handle); + if(_dirp->dirname) + free(_dirp->dirname); + if(_dirp) + free(_dirp); + + return iret; +} + +struct dirent *AXIS2_CALL +axis2_readdir( + AXIS2_DIR * _dirp) +{ + if(!_dirp || _dirp->finished) + return NULL; + + if(_dirp->offset != 0) + { + if(_findnext(_dirp->handle, &(_dirp->fileinfo)) < 0) + { + _dirp->finished = 1; + return NULL; + } + } + _dirp->offset++; + + strcpy(_dirp->dent.d_name, _dirp->fileinfo.name); /*, _MAX_FNAME+1); */ + _dirp->dent.d_ino = 1; + _dirp->dent.d_reclen = (unsigned short)strlen(_dirp->dent.d_name); + _dirp->dent.d_off = _dirp->offset; + + return &(_dirp->dent); +} + +int AXIS2_CALL +axis2_readdir_r( + AXIS2_DIR * _dirp, + struct dirent *_entry, + struct dirent **__result) +{ + if(!_dirp || _dirp->finished) + { + *__result = NULL; + return -1; + } + + if(_dirp->offset != 0) + { + if(_findnext(_dirp->handle, &(_dirp->fileinfo)) < 0) + { + _dirp->finished = 1; + *__result = NULL; + return -1; + } + } + _dirp->offset++; + + strcpy(_dirp->dent.d_name, _dirp->fileinfo.name); /*, _MAX_FNAME+1); */ + _dirp->dent.d_ino = 1; + _dirp->dent.d_reclen = (unsigned short)strlen(_dirp->dent.d_name); + _dirp->dent.d_off = _dirp->offset; + + memcpy(_entry, &_dirp->dent, sizeof(*_entry)); + + *__result = &_dirp->dent; + + return 0; +} + +int AXIS2_CALL +axis2_rewinddir( + AXIS2_DIR * dirp) +{ + char *filespec; + long handle; + int index; + + _findclose(dirp->handle); + + dirp->offset = 0; + dirp->finished = 0; + + filespec = malloc(strlen(dirp->dirname) + 2 + 1); + strcpy(filespec, dirp->dirname); + index = (int)(strlen(filespec) - 1); + if(index >= 0 && (filespec[index] == '/' || filespec[index] == '\\')) + filespec[index] = '\0'; + strcat(filespec, "/*"); + + if((handle = (long)_findfirst(filespec, &(dirp->fileinfo))) < 0) + /* We are sure that the difference lies within the int range */ + { + if(errno == ENOENT || errno == EINVAL) + dirp->finished = 1; + } + dirp->handle = handle; + free(filespec); + + return 0; +} + +int +alphasort( + const struct dirent **__d1, + const struct dirent **__d2) +{ + return strcoll((*__d1)->d_name, (*__d2)->d_name); +} + +int AXIS2_CALL +axis2_scandir( + const char *_dirname, + struct dirent **__namelist[], + int + (*selector)( + const struct dirent * entry), + int + (*compare)( + const struct dirent ** __d1, + const struct dirent ** __d2)) +{ + AXIS2_DIR *dirp = NULL; + struct dirent **vector = NULL; + struct dirent *dp = NULL; + int vector_size = 0; + int nfiles = 0; + + if(__namelist == NULL) + { + return -1; + } + dirp = axis2_opendir(_dirname); + if(!dirp) + { + return -1; + } + dp = axis2_readdir(dirp); + while(dp) + { + int dsize = 0; + struct dirent *newdp = NULL; + + if(selector && (*selector)(dp) == 0) + { + dp = axis2_readdir(dirp); + continue; + } + + if(nfiles == vector_size) + { + struct dirent **newv; + if(vector_size == 0) + { + vector_size = 10; + } + else + { + vector_size *= 2; + } + + newv = (struct dirent **)realloc(vector, vector_size * sizeof(struct dirent *)); + if(!newv) + { + return -1; + } + vector = newv; + } + + /*dsize = + (int) sizeof(struct dirent) + + (int) ((strlen(dp->d_name) + 1) * sizeof(char));*/ + dsize = (int)sizeof(struct dirent); + newdp = (struct dirent *)malloc(dsize); + + if(newdp == NULL) + { + while(nfiles-- > 0) + { + free(vector[nfiles]); + } + free(vector); + return -1; + } + + vector[nfiles++] = (struct dirent *)memcpy(newdp, dp, dsize); + dp = axis2_readdir(dirp); + } + + axis2_closedir(dirp); + + *__namelist = vector; + + if(compare) + { + qsort(*__namelist, nfiles, sizeof(struct dirent *), compare); + } + + return nfiles; +} diff --git a/util/src/platforms/windows/getopt_windows.c b/util/src/platforms/windows/getopt_windows.c new file mode 100644 index 0000000..6f5e18b --- /dev/null +++ b/util/src/platforms/windows/getopt_windows.c @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifndef AXIS2_GET_OPT_DEFINE_MODE_NO_IMPORT +/* Required by "axutil_getopt_windows.h" */ +#define AXIS2_GET_OPT_DEFINE_MODE_NO_IMPORT +#endif +#include <platforms/windows/axutil_getopt_windows.h> + +int optind = 1; +int opterr = 1; +int optopt; +char *optarg; + +#define AXIS2_OPT_ERR_NO_ARG 1 +#define AXIS2_OPT_ERR_INVALID_OPTION 2 +#define AXIS2_OPT_ERR_BAD_ARG 3 + +int +_axis2_opt_error( + int __optopt, + int __err, + int __showerr) +{ + switch(__err) + { + case AXIS2_OPT_ERR_NO_ARG: + if(__showerr) + fprintf(stderr, " option requires an argument -- %c\n", __optopt); + break; + case AXIS2_OPT_ERR_INVALID_OPTION: + if(__showerr) + fprintf(stderr, " illegal option -- %c\n", __optopt); + break; + case AXIS2_OPT_ERR_BAD_ARG: + return (int)':'; + default: + if(__showerr) + fprintf(stderr, "unknown\n"); + } + return (int)'?'; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_getopt( + int __argc, + char * const *__argv, + const char *__shortopts) +{ + static char *pos = ""; + char *olstindex = NULL; + + if(!*pos) + { + /* no option or invalid option */ + if(optind >= __argc || *(pos = __argv[optind]) != '-') + { + pos = ""; + return -1; + } + + /*-- option*/ + if(pos[1] && *++pos == '-') + { + ++optind; + pos = ""; + return -1; + } + } + + if((optopt = (int)*pos++) == (int)':') + { + if(optopt == (int)'-') + return -1; + if(!*pos) + ++optind; + if(*__shortopts != ':') + return _axis2_opt_error(optopt, AXIS2_OPT_ERR_BAD_ARG, opterr); + _axis2_opt_error(optopt, AXIS2_OPT_ERR_INVALID_OPTION, opterr); + } + else + { + olstindex = strchr(__shortopts, optopt); + if(!olstindex) + { + if(optopt == (int)'-') + return -1; + if(!*pos) + ++optind; + if(*__shortopts != ':') + return _axis2_opt_error(optopt, AXIS2_OPT_ERR_BAD_ARG, opterr); + _axis2_opt_error(optopt, AXIS2_OPT_ERR_INVALID_OPTION, opterr); + } + } + + if(!olstindex || *++olstindex != ':') + { + optarg = NULL; + if(!*pos) + ++optind; + } + else + { + if(*pos) + optarg = pos; + else if(__argc <= ++optind) + { + pos = ""; + if(*__shortopts == ':') + return _axis2_opt_error(-1, AXIS2_OPT_ERR_BAD_ARG, opterr); + return _axis2_opt_error(optopt, AXIS2_OPT_ERR_NO_ARG, opterr); + } + else + optarg = __argv[optind]; + pos = ""; + ++optind; + } + return optopt; +} diff --git a/util/src/platforms/windows/thread_mutex_windows.c b/util/src/platforms/windows/thread_mutex_windows.c new file mode 100644 index 0000000..13df497 --- /dev/null +++ b/util/src/platforms/windows/thread_mutex_windows.c @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_thread.h> +#include <platforms/windows/axutil_thread_mutex_windows.h> + +static axis2_status_t +thread_mutex_cleanup( + void *data) +{ + axutil_thread_mutex_t *lock = NULL; + axutil_allocator_t *allocator = NULL; + if(!data) + return AXIS2_FAILURE; + + lock = (axutil_thread_mutex_t *)data; + allocator = lock->allocator; + + if(lock->type == thread_mutex_critical_section) + { + DeleteCriticalSection(&lock->section); + } + else + { + if(!CloseHandle(lock->handle)) + { + return AXIS2_FAILURE; + } + } + + AXIS2_FREE(allocator, lock); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_thread_mutex_t *AXIS2_CALL +axutil_thread_mutex_create( + axutil_allocator_t * allocator, + unsigned int flags) +{ + axutil_thread_mutex_t *mutex = NULL; + + mutex = (axutil_thread_mutex_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_mutex_t)); + mutex->allocator = allocator; + + if(flags == AXIS2_THREAD_MUTEX_DEFAULT) /*unnested */ + { + /* Use an auto-reset signaled event, ready to accept one + * waiting thread. + */ + mutex->type = thread_mutex_unnested_event; + mutex->handle = CreateEvent(NULL, FALSE, TRUE, NULL); + } + else + { + /* TODO :support critical_section and nested_mutex */ + } + + return mutex; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_lock( + axutil_thread_mutex_t * mutex) +{ + if(mutex->type == thread_mutex_critical_section) + { + EnterCriticalSection(&mutex->section); + } + else + { + DWORD rv = WaitForSingleObject(mutex->handle, INFINITE); + if((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) + { + return AXIS2_FAILURE; + /*can be either BUSY or an os specific error */ + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_trylock( + axutil_thread_mutex_t * mutex) +{ + + if(mutex->type == thread_mutex_critical_section) + { + /* TODO :implement trylock for critical section */ + } + else + { + DWORD rv = WaitForSingleObject(mutex->handle, 0); + if((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) + { + /*can be either BUSY or an os specific error */ + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_unlock( + axutil_thread_mutex_t * mutex) +{ + if(mutex->type == thread_mutex_critical_section) + { + LeaveCriticalSection(&mutex->section); + } + else if(mutex->type == thread_mutex_unnested_event) + { + if(!SetEvent(mutex->handle)) + { + /*os specific error */ + return AXIS2_FAILURE; + } + } + else if(mutex->type == thread_mutex_nested_mutex) + { + if(!ReleaseMutex(mutex->handle)) + { + /*os specific error */ + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_destroy( + axutil_thread_mutex_t * mutex) +{ + return thread_mutex_cleanup((void *)mutex); +} diff --git a/util/src/platforms/windows/thread_windows.c b/util/src/platforms/windows/thread_windows.c new file mode 100644 index 0000000..67af332 --- /dev/null +++ b/util/src/platforms/windows/thread_windows.c @@ -0,0 +1,326 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_utils.h> +#include <platforms/windows/axutil_thread_windows.h> + +DWORD tls_axutil_thread = 0; + +AXIS2_EXTERN axutil_threadattr_t *AXIS2_CALL +axutil_threadattr_create( + axutil_allocator_t * allocator) +{ + axutil_threadattr_t *new = NULL; + + new = AXIS2_MALLOC(allocator, sizeof(axutil_threadattr_t)); + if(!new) + { + /*AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE) */ + return NULL; + } + new->detach = 0; + new->stacksize = 0; + + return new; +} + +/* Destroy the threadattr object */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +threadattr_cleanup( + void *data) +{ + /*axutil_threadattr_t *attr = data;*/ + /*nothing to clean up */ + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_detach_set( + axutil_threadattr_t * attr, + axis2_bool_t detached) +{ + attr->detach = detached; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_detach_get( + axutil_threadattr_t * attr, + const axutil_env_t * env) +{ + if(1 == attr->detach) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_stacksize_set( + axutil_threadattr_t * attr, + size_t stacksize) +{ + attr->stacksize = stacksize; + return AXIS2_SUCCESS; +} + +static void * +dummy_worker( + void *opaque) +{ + axutil_thread_t *thd = (axutil_thread_t *)opaque; + TlsSetValue(tls_axutil_thread, thd->td); + return thd->func(thd, thd->data); +} + +AXIS2_EXTERN axutil_thread_t *AXIS2_CALL +axutil_thread_create( + axutil_allocator_t * allocator, + axutil_threadattr_t * attr, + axutil_thread_start_t func, + void *data) +{ + HANDLE handle; + unsigned long temp; + axutil_thread_t *new = NULL; + + new = (axutil_thread_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_t)); + + if(!new) + { + return NULL; + } + + new->data = data; + new->func = func; + new->td = NULL; + new->try_exit = AXIS2_FALSE; + + /* Use 0 for Thread Stack Size, because that will default the stack to the + * same size as the calling thread. + */ + if((handle = + CreateThread(NULL, attr && + attr->stacksize > 0 ? attr->stacksize : 0, + (unsigned long (AXIS2_THREAD_FUNC *) (void *)) + dummy_worker, new, 0, &temp)) == 0) + { + return NULL; + } + + if(attr && attr->detach) + { + CloseHandle(handle); + } + else + new->td = handle; + + return new; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_exit( + axutil_thread_t * thd, + axutil_allocator_t * allocator) +{ + axis2_status_t status = AXIS2_SUCCESS; + + if(thd) + { + if(thd->td && (axis2_os_thread_current() != thd->td)) + { + TerminateThread(thd->td, 0); + axutil_thread_join(thd); + AXIS2_FREE(allocator, thd); + return status; + } + AXIS2_FREE(allocator, thd); + } + if(status) + { + ExitThread(0); + } + + return status; +} + +AXIS2_EXTERN axis2_os_thread_t AXIS2_CALL +axis2_os_thread_current( + void) +{ + HANDLE hthread = (HANDLE)TlsGetValue(tls_axutil_thread); + HANDLE hproc; + + if(hthread) + { + return hthread; + } + + hproc = GetCurrentProcess(); + hthread = GetCurrentThread(); + if(!DuplicateHandle(hproc, hthread, hproc, &hthread, 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + return NULL; + } + TlsSetValue(tls_axutil_thread, hthread); + return hthread; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_os_thread_equal( + axis2_os_thread_t tid1, + axis2_os_thread_t tid2) +{ + return (tid1 == tid2); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_join( + axutil_thread_t * thd) +{ + axis2_status_t rv = AXIS2_SUCCESS, rv1; + + if(!thd->td) + { + /* Can not join on detached threads */ + return AXIS2_FAILURE; + } + rv1 = WaitForSingleObject(thd->td, INFINITE); + if(rv1 == WAIT_OBJECT_0 || rv1 == WAIT_ABANDONED) + { + /*rv = AXIS2_INCOMPLETE; */ + } + else + rv = AXIS2_FAILURE; + CloseHandle(thd->td); + thd->td = NULL; + + return rv; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_detach( + axutil_thread_t * thd) +{ + if(thd->td && CloseHandle(thd->td)) + { + thd->td = NULL; + return AXIS2_SUCCESS; + } + else + { + return AXIS2_FAILURE; + } +} + +AXIS2_EXTERN axis2_os_thread_t AXIS2_CALL +axis2_os_thread_get( + axutil_thread_t * thd, + const axutil_env_t * env) +{ + return thd->td; +} + +/** + * function is used to allocate a new key. This key now becomes valid for all threads in our process. + * When a key is created, the value it points to defaults to NULL. Later on each thread may change + * its copy of the value as it wishes. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_key_create( + axutil_threadkey_t * axis2_key) +{ + DWORD tls_key = axis2_key->key; + if ((tls_key = TlsAlloc()) == TLS_OUT_OF_INDEXES) + { + return AXIS2_FAILURE; + } + else + { + return AXIS2_SUCCESS; + } +} + +/** + * This function is used to get the value of a given key + * @return void*. A key's value is simply a void pointer (void*) + */ +AXIS2_EXTERN void *AXIS2_CALL +axutil_thread_getspecific( + axutil_threadkey_t * axis2_key) +{ + void *value = NULL; + DWORD tls_key = axis2_key->key; + value = TlsGetValue(tls_key); + return value; +} + +/** + * This function is used to get the value of a given key + * @param keys value. A key's value is simply a void pointer (void*), so we can + * store in it anything that we want + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_setspecific( + axutil_threadkey_t * axis2_key, + void *value) +{ + DWORD tls_key = axis2_key->key; + if(!TlsSetValue(tls_key, value)) + { + return AXIS2_FAILURE; + } + else + { + return AXIS2_SUCCESS; + } +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_thread_key_free( + axutil_threadkey_t * axis2_key) +{ + DWORD tls_key = axis2_key->key; + TlsFree(tls_key); +} + +AXIS2_EXTERN axutil_thread_once_t *AXIS2_CALL +axutil_thread_once_init( + axutil_allocator_t * allocator) +{ + axutil_thread_once_t *control = NULL; + control = AXIS2_MALLOC(allocator, sizeof(*control)); + if(control) + { + control->value = 0; + } + return control; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_once( + axutil_thread_once_t * control, + void + (*func)( + void)) +{ + if(!InterlockedExchange(&control->value, 1)) + { + func(); + } + return AXIS2_SUCCESS; +} diff --git a/util/src/platforms/windows/uuid_gen_windows.c b/util/src/platforms/windows/uuid_gen_windows.c new file mode 100644 index 0000000..c075746 --- /dev/null +++ b/util/src/platforms/windows/uuid_gen_windows.c @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <platforms/windows/axutil_uuid_gen_windows.h> +#include <rpc.h> +#include <stdio.h> +#include <string.h> +#include <axutil_utils_defines.h> + +AXIS2_EXTERN axis2_char_t * AXIS2_CALL +axutil_platform_uuid_gen( + char *s) +{ + RPC_STATUS retval; + UUID uuid; + unsigned char *str; + axis2_char_t * retstr; + + if(!s) + { + return NULL; + } + + retstr = s; + retval = UuidCreate(&uuid); + if(retval == RPC_S_UUID_LOCAL_ONLY) + { + printf("warning - unique within computer \n"); + } + else if(retval == RPC_S_UUID_NO_ADDRESS) + { + return NULL; + } + + retval = UuidToStringA(&uuid, &str); + + if(retval == RPC_S_OK) + { + strcpy(retstr, (char *)str); + RpcStringFree(&str); + } + else if(retval == RPC_S_OUT_OF_MEMORY) + { + return NULL; + } + return retstr; +} diff --git a/util/src/properties.c b/util/src/properties.c new file mode 100644 index 0000000..265765e --- /dev/null +++ b/util/src/properties.c @@ -0,0 +1,363 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_properties.h> +#include <axutil_string.h> +#include <axutil_utils.h> + +#define MAX_SIZE 1024 +#define MAX_ALLOC (MAX_SIZE * 64) + +axis2_char_t * +axutil_properties_read( + FILE *input, + const axutil_env_t *env); + +axis2_char_t * +axutil_properties_read_next( + axis2_char_t *cur); + +axis2_char_t * +axutil_properties_trunk_and_dup( + axis2_char_t *start, + axis2_char_t *end, + const axutil_env_t *env); + +struct axutil_properties +{ + axutil_hash_t *prop_hash; +}; + +AXIS2_EXTERN axutil_properties_t *AXIS2_CALL +axutil_properties_create( + const axutil_env_t *env) +{ + axutil_properties_t *properties = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + properties = (axutil_properties_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_properties_t)); + + if(!properties) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Not enough memory"); + return NULL; + } + properties->prop_hash = axutil_hash_make(env); + + return properties; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_properties_free( + axutil_properties_t *properties, + const axutil_env_t *env) +{ + axis2_char_t *key = NULL; + axis2_char_t *value = NULL; + axutil_hash_index_t *hi = NULL; + + if(properties->prop_hash) + { + for(hi = axutil_hash_first(properties->prop_hash, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, (void *)&key, NULL, (void *)&value); + if(key) + { + AXIS2_FREE(env->allocator, key); + } + if(value) + { + AXIS2_FREE(env->allocator, value); + } + } + axutil_hash_free(properties->prop_hash, env); + } + + if(properties) + { + AXIS2_FREE(env->allocator, properties); + } + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_properties_get_property( + axutil_properties_t *properties, + const axutil_env_t *env, + axis2_char_t *key) +{ + AXIS2_PARAM_CHECK(env->error, key, NULL); + + return axutil_hash_get(properties->prop_hash, key, AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_properties_set_property( + axutil_properties_t *properties, + const axutil_env_t *env, + axis2_char_t *key, + axis2_char_t *value) +{ + axis2_char_t *old = NULL; + AXIS2_PARAM_CHECK(env->error, key, AXIS2_FAILURE); + + old = axutil_properties_get_property(properties, env, key); + if(old) + { + AXIS2_FREE(env->allocator, old); + axutil_hash_set(properties->prop_hash, key, AXIS2_HASH_KEY_STRING, + axutil_strdup(env, value)); + return AXIS2_SUCCESS; + } + axutil_hash_set(properties->prop_hash, axutil_strdup(env, key), AXIS2_HASH_KEY_STRING, + axutil_strdup(env, value)); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axutil_properties_get_all( + axutil_properties_t *properties, + const axutil_env_t *env) +{ + return properties->prop_hash; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_properties_store( + axutil_properties_t *properties, + const axutil_env_t *env, + FILE *output) +{ + axutil_hash_index_t *hi = NULL; + axis2_char_t *key = NULL; + axis2_char_t *value = NULL; + + AXIS2_PARAM_CHECK(env->error, output, AXIS2_FAILURE); + + if(properties->prop_hash) + { + for(hi = axutil_hash_first(properties->prop_hash, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, (void *)&key, NULL, (void *)&value); + if(key) + { + if(!value) + { + value = axutil_strdup(env, ""); + } + fprintf(output, "%s=%s\n", key, value); + } + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_properties_load( + axutil_properties_t *properties, + const axutil_env_t *env, + axis2_char_t *input_filename) +{ + FILE *input = NULL; + axis2_char_t *cur = NULL; + axis2_char_t *tag = NULL; + const int LINE_STARTED = -1; + const int LINE_MIDWAY = 0; + const int EQUAL_FOUND = 1; + const int LINE_HALFWAY = 2; + int status = LINE_STARTED; + + axis2_char_t *key = NULL; + axutil_hash_t *prop_hash = NULL; + axis2_char_t *buffer = NULL; + axis2_char_t loginfo[1024]; + + AXIS2_PARAM_CHECK(env->error, input_filename, AXIS2_FAILURE); + + prop_hash = properties->prop_hash; + + input = fopen(input_filename, "r+"); + if(!input) + { + return AXIS2_FAILURE; + } + buffer = axutil_properties_read(input, env); + + if(!buffer) + { + sprintf(loginfo, "error in reading file\n"); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, loginfo); + AXIS2_FREE(env->allocator, buffer); + return AXIS2_FAILURE; + } + + for(cur = axutil_properties_read_next(buffer); *cur; cur = axutil_properties_read_next(++cur)) + { + if(*cur == '\r') + { + *cur = '\0'; + } + else if(*cur != '\0' && *cur != '\n' && status == LINE_STARTED) + { + tag = cur; + status = LINE_MIDWAY; + } + /* equal found just create a property */ + else if(*cur == '=' && status == LINE_MIDWAY) + { + *cur = '\0'; + if(status != LINE_MIDWAY) + { + sprintf(loginfo, "equal apear in wrong place around %s\n", tag); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, loginfo); + AXIS2_FREE(env->allocator, buffer); + return AXIS2_FAILURE; + } + status = EQUAL_FOUND; + key = axutil_properties_trunk_and_dup(tag, cur, env); + } + /* right next to the equal found */ + else if(status == EQUAL_FOUND) + { + tag = cur; + status = LINE_HALFWAY; + } + + else if(*cur == '\n') + { + *cur = '\0'; + if(status == LINE_HALFWAY) + { + tag = axutil_properties_trunk_and_dup(tag, cur, env); + axutil_hash_set(prop_hash, key, AXIS2_HASH_KEY_STRING, tag); + } + status = LINE_STARTED; + } + } + if(status == LINE_HALFWAY) + { + *cur = '\0'; + tag = axutil_properties_trunk_and_dup(tag, cur, env); + axutil_hash_set(prop_hash, key, AXIS2_HASH_KEY_STRING, tag); + status = LINE_STARTED; + } + if(status != LINE_STARTED) + { + sprintf(loginfo, "error parsing properties\n"); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, loginfo); + AXIS2_FREE(env->allocator, buffer); + return AXIS2_FAILURE; + } + if(input) + { + fclose(input); + } + AXIS2_FREE(env->allocator, buffer); + return AXIS2_SUCCESS; +} + +axis2_char_t * +axutil_properties_read_next( + axis2_char_t *cur) +{ + /* ignore comment */ + if(*cur == '#') + { + for(; *cur != '\n' && *cur != '\0'; cur++) + ; + } + /* check '\\''\n' case */ + if(*cur == '\\' && *(cur + 1) == '\n') + { + /* ignore two axis2_char_ts */ + *(cur++) = ' '; + *(cur++) = ' '; + } + return cur; +} + +axis2_char_t * +axutil_properties_trunk_and_dup( + axis2_char_t *start, + axis2_char_t *end, + const axutil_env_t *env) +{ + for(; *start == ' '; start++) + ; /* remove front spaces */ + for(end--; *end == ' '; end--) + ; /* remove rear spaces */ + *(++end) = '\0'; + start = (axis2_char_t *)axutil_strdup(env, start); + return start; +} + +axis2_char_t * +axutil_properties_read( + FILE *input, + const axutil_env_t *env) +{ + size_t nread = 0; + axis2_char_t *out_stream = NULL; + size_t ncount = 0; + size_t curr_alloc = MAX_SIZE * 2; + size_t total_alloc = curr_alloc; + + out_stream = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * curr_alloc); + if(!out_stream) + { + return NULL; + } + + do + { + nread = fread(out_stream + ncount, sizeof(axis2_char_t), MAX_SIZE, input); + ncount += nread; + + if(ncount + MAX_SIZE > total_alloc) + { + axis2_char_t *new_stream = NULL; + if(curr_alloc < MAX_ALLOC) + { + curr_alloc *= 2; + } + + total_alloc += curr_alloc; + new_stream = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * total_alloc); + if(!new_stream) + { + if(out_stream) + { + AXIS2_FREE(env->allocator, out_stream); + } + return NULL; + } + + memcpy(new_stream, out_stream, sizeof(axis2_char_t) * ncount); + if(out_stream) + { + AXIS2_FREE(env->allocator, out_stream); + } + out_stream = new_stream; + } + } + while(nread == MAX_SIZE); + + out_stream[ncount] = '\0'; + return out_stream; +} diff --git a/util/src/property.c b/util/src/property.c new file mode 100644 index 0000000..55826d1 --- /dev/null +++ b/util/src/property.c @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_property.h> +#include <stdio.h> + +struct axutil_property +{ + axis2_scope_t scope; + AXIS2_FREE_VOID_ARG free_func; + void *value; + axis2_bool_t own_value; +}; + +axutil_property_t *AXIS2_CALL +axutil_property_create( + const axutil_env_t * env) +{ + axutil_property_t *property = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + property = (axutil_property_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_property_t)); + + if(!property) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + property->value = NULL; + property->scope = AXIS2_SCOPE_REQUEST; + property->free_func = 0; + property->own_value = AXIS2_TRUE; + + return property; +} + +/*****************************************************************************/ +axutil_property_t *AXIS2_CALL +axutil_property_create_with_args( + const axutil_env_t * env, + axis2_scope_t scope, + axis2_bool_t own_value, + AXIS2_FREE_VOID_ARG free_func, + void *value) +{ + axutil_property_t *property = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + property = (axutil_property_t *)axutil_property_create(env); + + if(!property) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + property->value = value; + property->scope = scope; + property->own_value = own_value; + property->free_func = free_func; + + return property; +} + +void AXIS2_CALL +axutil_property_free( + axutil_property_t * property, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(property->value) + { + if(property->scope != AXIS2_SCOPE_APPLICATION) + { + if(property->free_func && property->own_value) + { + property->free_func(property->value, env); + } + else if(property->own_value) + { + AXIS2_FREE(env->allocator, property->value); + } + } + } + + if(property) + { + AXIS2_FREE(env->allocator, property); + } + return; +} + +axis2_status_t AXIS2_CALL +axutil_property_set_scope( + axutil_property_t * property, + const axutil_env_t * env, + axis2_scope_t scope) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + property->scope = scope; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axutil_property_set_free_func( + axutil_property_t * property, + const axutil_env_t * env, + AXIS2_FREE_VOID_ARG free_func) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + property->free_func = free_func; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axutil_property_set_value( + axutil_property_t * property, + const axutil_env_t * env, + void *value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(property->value) + { + if(property->scope != AXIS2_SCOPE_APPLICATION) + { + if(property->free_func && property->own_value) + { + property->free_func(property->value, env); + } + else if(property->own_value) + { + AXIS2_FREE(env->allocator, property->value); + } + } + } + + property->value = value; + return AXIS2_SUCCESS; +} + +void *AXIS2_CALL +axutil_property_get_value( + axutil_property_t * property, + const axutil_env_t * env) +{ + return property->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_property_set_own_value( + axutil_property_t * property, + const axutil_env_t * env, + axis2_bool_t own_value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + property->own_value = own_value; + return AXIS2_SUCCESS; +} + +axutil_property_t *AXIS2_CALL +axutil_property_clone( + axutil_property_t * property, + const axutil_env_t * env) +{ + axutil_property_t *new_property = NULL; + AXIS2_ENV_CHECK(env, NULL); + new_property = axutil_property_create(env); + axutil_property_set_free_func(new_property, env, property->free_func); + axutil_property_set_scope(new_property, env, property->scope); + axutil_property_set_own_value(new_property, env, property->own_value); + axutil_property_set_value(new_property, env, property->value); + return new_property; +} diff --git a/util/src/qname.c b/util/src/qname.c new file mode 100644 index 0000000..e4197c3 --- /dev/null +++ b/util/src/qname.c @@ -0,0 +1,337 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_qname.h> +#include <axutil_env.h> +#include <axutil_utils.h> +#include <axutil_utils_defines.h> +#include <string.h> +#include <stdio.h> + +struct axutil_qname +{ + + /** localpart of qname is mandatory */ + axis2_char_t *localpart; + + /** namespace uri is optional */ + axis2_char_t *namespace_uri; + + /** prefix mandatory */ + axis2_char_t *prefix; + + /** qname represented as a string, used as keys in hash tables, etc. */ + axis2_char_t *qname_string; + unsigned int ref; +}; + +AXIS2_EXTERN axutil_qname_t *AXIS2_CALL +axutil_qname_create( + const axutil_env_t *env, + const axis2_char_t *localpart, + const axis2_char_t *namespace_uri, + const axis2_char_t *prefix) +{ + + axutil_qname_t *qname = NULL; + AXIS2_ENV_CHECK(env, NULL); + + /* localpart can't be null */ + if(!localpart) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + return NULL; + } + + qname = (axutil_qname_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_qname_t)); + if(!qname) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + /* set properties */ + qname->localpart = NULL; + qname->qname_string = NULL; + qname->prefix = NULL; + qname->namespace_uri = NULL; + qname->ref = 1; + + qname->localpart = (axis2_char_t *)axutil_strdup(env, localpart); + if(!(qname->localpart)) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + axutil_qname_free(qname, env); + return NULL; + } + + if(prefix) + { + qname->prefix = (axis2_char_t *)axutil_strdup(env, prefix); + } + + if(prefix && !(qname->prefix)) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + axutil_qname_free(qname, env); + return NULL; + } + + if(namespace_uri) + { + qname->namespace_uri = (axis2_char_t *)axutil_strdup(env, namespace_uri); + } + + if(namespace_uri && !(qname->namespace_uri)) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + axutil_qname_free(qname, env); + return NULL; + } + + return qname; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_qname_free( + axutil_qname_t *qname, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + qname->ref--; + + if(qname->ref > 0) + { + return; + } + + if(qname->localpart) + { + AXIS2_FREE(env->allocator, qname->localpart); + } + if(qname->namespace_uri) + { + AXIS2_FREE(env->allocator, qname->namespace_uri); + } + if(qname->prefix) + { + AXIS2_FREE(env->allocator, qname->prefix); + } + if(qname->qname_string) + { + AXIS2_FREE(env->allocator, qname->qname_string); + } + + AXIS2_FREE(env->allocator, qname); + + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_qname_equals( + const axutil_qname_t *qname, + const axutil_env_t *env, + const axutil_qname_t *qname2) +{ + int uris_differ = 0; + int localparts_differ = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + + if(!qname2) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_INVALID_NULL_PARAM); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + return AXIS2_FALSE; + } + + if(qname->localpart && qname2->localpart) + { + localparts_differ = axutil_strcmp(qname->localpart, qname2->localpart); + } + else + { + localparts_differ = ((qname->localpart) || (qname2->localpart)); + } + + if(qname->namespace_uri && qname2->namespace_uri) + { + uris_differ = axutil_strcmp(qname->namespace_uri, qname2->namespace_uri); + } + else + { + uris_differ = ((qname->namespace_uri) || (qname2->namespace_uri)); + } + + return (!uris_differ && !localparts_differ) ? AXIS2_TRUE : AXIS2_FALSE; +} + +AXIS2_EXTERN axutil_qname_t *AXIS2_CALL +axutil_qname_clone( + axutil_qname_t *qname, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, NULL); + + if(!qname) + { + return NULL; + } + qname->ref++; + + return qname; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_qname_get_uri( + const axutil_qname_t *qname, + const axutil_env_t *env) +{ + AXIS2_PARAM_CHECK(env->error, qname, NULL); + return qname->namespace_uri; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_qname_get_prefix( + const axutil_qname_t *qname, + const axutil_env_t *env) +{ + AXIS2_PARAM_CHECK(env->error, qname, NULL); + return qname->prefix; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_qname_get_localpart( + const axutil_qname_t *qname, + const axutil_env_t *env) +{ + AXIS2_PARAM_CHECK(env->error, qname, NULL); + return qname->localpart; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_qname_to_string( + axutil_qname_t *qname, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, NULL); + if(qname->qname_string) + { + return qname->qname_string; + } + + if(!(qname->namespace_uri) || axutil_strcmp(qname->namespace_uri, "") == 0) + { + qname->qname_string = axutil_strdup(env, qname->localpart); + } + else if(!(qname->prefix) || axutil_strcmp(qname->prefix, "") == 0) + { + axis2_char_t *temp_string1 = NULL; + temp_string1 = axutil_stracat(env, qname->localpart, "|"); + qname->qname_string = axutil_stracat(env, temp_string1, qname->namespace_uri); + if(temp_string1) + { + AXIS2_FREE(env->allocator, temp_string1); + } + } + else + { + axis2_char_t *temp_string1 = NULL; + axis2_char_t *temp_string2 = NULL; + axis2_char_t *temp_string3 = NULL; + + temp_string1 = axutil_stracat(env, qname->localpart, "|"); + temp_string2 = axutil_stracat(env, temp_string1, qname->namespace_uri); + temp_string3 = axutil_stracat(env, temp_string2, "|"); + qname->qname_string = axutil_stracat(env, temp_string3, qname->prefix); + + if(temp_string1) + { + AXIS2_FREE(env->allocator, temp_string1); + } + if(temp_string2) + { + AXIS2_FREE(env->allocator, temp_string2); + } + if(temp_string3) + { + AXIS2_FREE(env->allocator, temp_string3); + } + } + return qname->qname_string; +} + +AXIS2_EXTERN axutil_qname_t *AXIS2_CALL +axutil_qname_create_from_string( + const axutil_env_t *env, + const axis2_char_t *qstring) +{ + axis2_char_t *localpart = NULL; + axis2_char_t *namespace_uri = NULL; + axis2_char_t *prefix = NULL; + axis2_char_t *index = NULL; + axis2_char_t *next = NULL; + axis2_char_t *temp_string = NULL; + axutil_qname_t *qname = NULL; + if(!qstring || axutil_strcmp(qstring, "") == 0) + return NULL; + + temp_string = axutil_strdup(env, qstring); + + index = strchr(temp_string, '|'); + if(index) + { + next = index + 1; + temp_string[index - temp_string] = '\0'; + localpart = temp_string; + + index = strchr(next, '|'); + if(index) + { + prefix = index + 1; + next[index - next] = '\0'; + namespace_uri = next; + qname = axutil_qname_create(env, localpart, namespace_uri, prefix); + } + else + { + /** only uri and localpart is available */ + qname = axutil_qname_create(env, localpart, next, NULL); + } + } + else + { + /** only localpart is there in this qname */ + qname = axutil_qname_create(env, temp_string, NULL, NULL); + } + if(temp_string) + { + AXIS2_FREE(env->allocator, temp_string); + } + return qname; +} diff --git a/util/src/rand.c b/util/src/rand.c new file mode 100644 index 0000000..c3a7aa9 --- /dev/null +++ b/util/src/rand.c @@ -0,0 +1,66 @@ +/* + * Copyright 2004,2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <axutil_rand.h> +#include <axutil_string.h> +#include <platforms/axutil_platform_auto_sense.h> + +#define AXIS2_RAND_MAX 32768 + +AXIS2_EXTERN int AXIS2_CALL +axutil_rand( + unsigned int *seedp) +{ + *seedp = *seedp * 1103515245 + 12345; + return ((unsigned)(*seedp / (2 * AXIS2_RAND_MAX)) % AXIS2_RAND_MAX); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_rand_with_range( + unsigned int *seedp, + int start, + int end) +{ + int rand = -1; + float range = 0.0; + if(start < 0 || end <= 0) + return -1; + if(start >= AXIS2_RAND_MAX || end > AXIS2_RAND_MAX) + return -1; + if(end <= start) + return -1; + + range = (float)(end - start); + rand = axutil_rand(seedp); + rand = start + (int)(range * rand / (AXIS2_RAND_MAX + 1.0)); + return rand; +} + +AXIS2_EXTERN unsigned int AXIS2_CALL +axutil_rand_get_seed_value_based_on_time( + const axutil_env_t * env) +{ + axutil_date_time_t *date = axutil_date_time_create(env); + unsigned int rand_var = axutil_date_time_get_year(date, env); + rand_var += axutil_date_time_get_month(date, env); + rand_var += axutil_date_time_get_date(date, env); + rand_var += axutil_date_time_get_hour(date, env); + rand_var += axutil_date_time_get_minute(date, env); + rand_var += axutil_date_time_get_second(date, env); + axutil_date_time_free(date, env); + return rand_var; +} diff --git a/util/src/stack.c b/util/src/stack.c new file mode 100644 index 0000000..5d45a93 --- /dev/null +++ b/util/src/stack.c @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_stack.h> +#include <axutil_utils.h> +#include <axutil_env.h> +#include <stdlib.h> +#include <string.h> + +#define AXIS2_STACK_DEFAULT_CAPACITY 10 + +struct axutil_stack +{ + void **data; + + /** current number of elements */ + int size; + + /** total capacity */ + int capacity; + axis2_bool_t is_empty_stack; +}; + +AXIS2_EXTERN axutil_stack_t *AXIS2_CALL +axutil_stack_create( + const axutil_env_t *env) +{ + axutil_stack_t *stack = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + stack = (axutil_stack_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_stack_t)); + + if(!stack) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + + stack->data = NULL; + stack->size = 0; + stack->capacity = AXIS2_STACK_DEFAULT_CAPACITY; + stack->is_empty_stack = AXIS2_TRUE; + + stack->data = AXIS2_MALLOC(env->allocator, sizeof(void *) * AXIS2_STACK_DEFAULT_CAPACITY); + if(!stack->data) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + axutil_stack_free(stack, env); + return NULL; + } + + return stack; +} + +void AXIS2_CALL +axutil_stack_free( + axutil_stack_t *stack, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(stack->data) + { + AXIS2_FREE(env->allocator, stack->data); + } + AXIS2_FREE(env->allocator, stack); + return; +} + +void *AXIS2_CALL +axutil_stack_pop( + axutil_stack_t *stack, + const axutil_env_t *env) +{ + void *value = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(stack->is_empty_stack == AXIS2_TRUE || stack->size == 0) + { + return NULL; + } + if(stack->size > 0) + { + value = stack->data[stack->size - 1]; + stack->data[stack->size - 1] = NULL; + stack->size--; + if(stack->size == 0) + { + stack->is_empty_stack = AXIS2_TRUE; + } + } + return value; +} + +axis2_status_t AXIS2_CALL +axutil_stack_push( + axutil_stack_t *stack, + const axutil_env_t *env, + void *value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + + if((stack->size < stack->capacity) && (stack->capacity > 0)) + { + stack->data[stack->size++] = value; + } + else + { + void **new_data = NULL; + + int new_capacity = stack->capacity + AXIS2_STACK_DEFAULT_CAPACITY; + + new_data = AXIS2_MALLOC(env->allocator, sizeof(void *) * new_capacity); + if(!new_data) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return AXIS2_FAILURE; + } + memset(new_data, 0, sizeof(void *) * new_capacity); + memcpy(new_data, stack->data, sizeof(void *) * (stack->capacity)); + stack->capacity = new_capacity; + + AXIS2_FREE(env->allocator, stack->data); + stack->data = new_data; + + stack->data[stack->size++] = value; + } + stack->is_empty_stack = AXIS2_FALSE; + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +axutil_stack_size( + axutil_stack_t *stack, + const axutil_env_t *env) +{ + return stack->size; +} + +void *AXIS2_CALL +axutil_stack_get( + axutil_stack_t *stack, + const axutil_env_t *env) +{ + if(stack->size > 0) + { + return stack->data[stack->size - 1]; + } + return NULL; +} + +void *AXIS2_CALL +axutil_stack_get_at( + axutil_stack_t *stack, + const axutil_env_t *env, + int i) +{ + if((stack->size == 0) || (i < 0) || (i >= stack->size)) + { + return NULL; + } + return stack->data[i]; +} diff --git a/util/src/stream.c b/util/src/stream.c new file mode 100644 index 0000000..1034a03 --- /dev/null +++ b/util/src/stream.c @@ -0,0 +1,719 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <stdlib.h> +#include <axutil_stream.h> +#include <platforms/axutil_platform_auto_sense.h> + +/** basic stream operatons **/ +int AXIS2_CALL axutil_stream_write_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_read_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_skip_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + int count); + +/** file stream operations **/ +int AXIS2_CALL axutil_stream_write_file( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_read_file( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_skip_file( + axutil_stream_t *stream, + const axutil_env_t *env, + int count); + +/** socket stream operations **/ +int AXIS2_CALL axutil_stream_write_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_read_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_skip_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + int count); + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_internal( + const axutil_env_t *env) +{ + axutil_stream_t *stream = NULL; + stream = (axutil_stream_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_stream_t)); + if(!stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory. Cannot create axutil stream"); + return NULL; + } + stream->buffer = NULL; + stream->buffer_head = NULL; + stream->fp = NULL; + stream->socket = -1; + stream->len = -1; + stream->max_len = -1; + stream->axis2_eof = EOF; + + return stream; +} + +void AXIS2_CALL +axutil_stream_free( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + switch(stream->stream_type) + { + case AXIS2_STREAM_BASIC: + { + if(stream->buffer_head) + { + AXIS2_FREE(env->allocator, stream->buffer_head); + } + stream->buffer = NULL; + stream->len = -1; + break; + } + case AXIS2_STREAM_FILE: + { + stream->fp = NULL; + stream->len = -1; + break; + } + case AXIS2_STREAM_SOCKET: + { + if(stream->fp) + { + fclose(stream->fp); + } + stream->socket = -1; + stream->len = -1; + break; + } + default: + break; + } + + AXIS2_FREE(env->allocator, stream); +} + +void AXIS2_CALL +axutil_stream_free_void_arg( + void *stream, + const axutil_env_t *env) +{ + axutil_stream_t *stream_l = NULL; + + stream_l = (axutil_stream_t *)stream; + axutil_stream_free(stream_l, env); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_flush( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + if(stream->fp) + { + if(fflush(stream->fp)) + { + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_close( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + switch(stream->stream_type) + { + case AXIS2_STREAM_BASIC: + { + if(stream->buffer_head) + { + AXIS2_FREE(env->allocator, stream->buffer_head); + } + stream->buffer = NULL; + stream->len = -1; + break; + } + case AXIS2_STREAM_FILE: + { + if(stream->fp) + { + if(fclose(stream->fp)) + { + return AXIS2_FAILURE; + } + } + stream->fp = NULL; + stream->len = -1; + break; + } + case AXIS2_STREAM_SOCKET: + { + if(stream->fp) + { + if(fclose(stream->fp)) + { + return AXIS2_FAILURE; + } + } + stream->socket = -1; + stream->len = -1; + break; + } + default: + break; + } + + return AXIS2_SUCCESS; +} + +/************************ Basic Stream Operations *****************************/ +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_basic( + const axutil_env_t *env) +{ + axutil_stream_t *stream = NULL; + + AXIS2_ENV_CHECK(env, NULL); + stream = axutil_stream_create_internal(env); + if(!stream) + { + /* + * We leave the error returned by the + * axutil_stream_create_internal intact + */ + return NULL; + } + stream->stream_type = AXIS2_STREAM_BASIC; + stream->read = axutil_stream_read_basic; + stream->write = axutil_stream_write_basic; + stream->skip = axutil_stream_skip_basic; + stream->buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, AXIS2_STREAM_DEFAULT_BUF_SIZE + * sizeof(axis2_char_t)); + stream->buffer_head = stream->buffer; + stream->len = 0; + stream->max_len = AXIS2_STREAM_DEFAULT_BUF_SIZE; + + if(!stream->buffer) + { + axutil_stream_free(stream, env); + return NULL; + } + return stream; +} + +int AXIS2_CALL +axutil_stream_read_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + int len = 0; + char *buf = NULL; + + buf = stream->buffer; + if(!buf) + { + return -1; + } + if(!buffer) + { + return -1; + } + if((int)(count - 1) > stream->len) + /* We are sure that the difference lies within the int range */ + { + len = stream->len; + } + else + { + len = (int)(count - 1); + /* We are sure that the difference lies within the int range */ + } + memcpy(buffer, buf, len); + /* + * Finally we need to remove the read bytes from the stream + * adjust the length of the stream. + */ + stream->len -= len; + stream->buffer = buf + len; + ((axis2_char_t *)buffer)[len] = '\0'; + return len; +} + +int AXIS2_CALL +axutil_stream_write_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + int new_len = 0; + + if(!buffer) + return -1; + + new_len = (int)(stream->len + count); + /* We are sure that the difference lies within the int range */ + if(new_len > stream->max_len) + { + axis2_char_t *tmp = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (new_len + AXIS2_STREAM_DEFAULT_BUF_SIZE)); + if(!tmp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return -1; + } + /* + * pre allocation: extra AXIS2_STREAM_DEFAULT_BUF_SIZE more bytes + * allocated + */ + stream->max_len = new_len + AXIS2_STREAM_DEFAULT_BUF_SIZE; + memcpy(tmp, stream->buffer, sizeof(axis2_char_t) * stream->len); + AXIS2_FREE(env->allocator, stream->buffer_head); + stream->buffer = tmp; + stream->buffer_head = tmp; + } + memcpy(stream->buffer + (stream->len * sizeof(axis2_char_t)), buffer, count); + stream->len += (int)count; + /* We are sure that the difference lies within the int range */ + return (int)count; +} + +int AXIS2_CALL +axutil_stream_get_len( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + return stream->len; +} + +int AXIS2_CALL +axutil_stream_skip_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + int count) +{ + int del_len = 0; + + if(count > 0) + { + if(count <= stream->len) + { + del_len = count; + } + else + { + del_len = stream->len; + } + stream->len -= del_len; + stream->buffer += del_len; + return del_len; + } + return -1; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_stream_get_buffer( + const axutil_stream_t *stream, + const axutil_env_t *env) +{ + return stream->buffer; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_flush_buffer( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + stream->len = 0; + return AXIS2_SUCCESS; +} + +/********************* End of Basic Stream Operations *************************/ + +/************************** File Stream Operations ****************************/ +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_file( + const axutil_env_t *env, + FILE * fp) +{ + axutil_stream_t *stream = NULL; + + AXIS2_ENV_CHECK(env, NULL); + stream = axutil_stream_create_internal(env); + if(!stream) + { + /* + * We leave the error returned by the + * axutil_stream_create_internal intact + */ + return NULL; + } + stream->stream_type = AXIS2_STREAM_FILE; + stream->fp = fp; + + stream->read = axutil_stream_read_file; + stream->write = axutil_stream_write_file; + stream->skip = axutil_stream_skip_file; + + return stream; +} + +int AXIS2_CALL +axutil_stream_read_file( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + FILE *fp = NULL; + + if(!stream->fp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Trying to do operation on invalid file descriptor"); + + return -1; + } + fp = stream->fp; + if(!buffer) + { + return -1; + } + return (int)fread(buffer, sizeof(axis2_char_t), count, fp); + /* We are sure that the difference lies within the int range */ +} + +int AXIS2_CALL +axutil_stream_write_file( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + int len = 0; + FILE *fp = NULL; + + if(!(stream->fp)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Trying to do operation on invalid file descriptor"); + + return -1; + } + fp = stream->fp; + if(!buffer) + return -1; + len = (int)fwrite(buffer, sizeof(axis2_char_t), count, fp); + /* We are sure that the difference lies within the int range */ + return len; +} + +int AXIS2_CALL +axutil_stream_skip_file( + axutil_stream_t *stream, + const axutil_env_t *env, + int count) +{ + int c = -1; + int i = count; + if(!(stream->fp)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Trying to do operation on invalid file descriptor"); + return -1; + } + while(EOF != (c = fgetc(stream->fp)) && i > 0) + { + i--; + } + return count - i; +} + +/********************** End of File Stream Operations *************************/ + +/************************** Socket Stream Operations **************************/ +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_socket( + const axutil_env_t *env, + int socket) +{ + axutil_stream_t *stream = NULL; + stream = axutil_stream_create_internal(env); + if(!stream) + { + /* + * We leave the error returned by the + * axutil_stream_create_internal intact + */ + return NULL; + } + + stream->read = axutil_stream_read_socket; + stream->write = axutil_stream_write_socket; + stream->skip = axutil_stream_skip_socket; + stream->stream_type = AXIS2_STREAM_SOCKET; + stream->socket = socket; + stream->fp = NULL; + + return stream; +} + +int AXIS2_CALL +axutil_stream_read_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + int len = 0; + + if(-1 == stream->socket) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Trying to do operation on closed/not-opened socket"); + return -1; + } + if(!buffer) + { + return -1; + } + + len = (int)recv(stream->socket, buffer, (int)count, 0); + /* We are sure that the difference lies within the int range */ +#ifdef AXIS2_TCPMON + if (len > 1) + { + axis2_char_t *temp = NULL; + temp = (axis2_char_t *) AXIS2_MALLOC(env->allocator, (len + 1) * sizeof(axis2_char_t)); + if (temp) + { + memcpy(temp, buffer, len * sizeof(axis2_char_t)); + temp[len] = '\0'; + fprintf(stderr, "%s", temp); + AXIS2_FREE(env->allocator, temp); + } + } +#endif + return len; +} + +int AXIS2_CALL +axutil_stream_write_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + int len = 0; +#ifdef AXIS2_TCPMON + axis2_char_t *temp = NULL; +#endif + + if(-1 == stream->socket) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Trying to do operation on closed/not-opened socket"); + return -1; + } + if(!buffer) + return -1; + len = (int)send(stream->socket, buffer, (int)count, 0); + /* We are sure that the difference lies within the int range */ +#ifdef AXIS2_TCPMON + if (len > 0) + { + temp = + (axis2_char_t *) AXIS2_MALLOC(env->allocator, + (len + 1) * sizeof(axis2_char_t)); + if (temp) + { + memcpy(temp, buffer, len * sizeof(axis2_char_t)); + temp[len] = '\0'; + fprintf(stderr, "%s", temp); + AXIS2_FREE(env->allocator, temp); + } + } +#endif + return len; + +} + +int AXIS2_CALL +axutil_stream_skip_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + int count) +{ + int len = 0; + int received = 0; + char buffer[2]; + + if(-1 == stream->socket) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Trying to do operation on closed/not-opened socket"); + return -1; + } + while(len < count) + { + received = recv(stream->socket, buffer, 1, 0); + if(received == 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Socket has being shutdown"); + return -1; + } + if(received < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error while trying to read the socke"); + return -1; + } + len += received; + } + return len; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_peek_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + int len = 0; + + /* Added to prevent a segfault */ + AXIS2_PARAM_CHECK(env->error, stream, -1); + + if(-1 == stream->socket) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Trying to do operation on closed/not-opened socket"); + return -1; + } + if(!buffer) + { + return -1; + } + + len = (int)recv(stream->socket, buffer, (int)count, MSG_PEEK); + /* We are sure that the difference lies within the int range */ + + return len; +} + +/********************** End of Socket Stream Operations ***********************/ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_set_read( + axutil_stream_t *stream, + const axutil_env_t *env, + AXUTIL_STREAM_READ func) +{ + stream->read = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_set_write( + axutil_stream_t *stream, + const axutil_env_t *env, + AXUTIL_STREAM_WRITE func) +{ + stream->write = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_set_skip( + axutil_stream_t *stream, + const axutil_env_t *env, + AXUTIL_STREAM_SKIP func) +{ + stream->skip = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_read( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + return stream->read(stream, env, buffer, count); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_write( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + return stream->write(stream, env, buffer, count); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_skip( + axutil_stream_t *stream, + const axutil_env_t *env, + int count) +{ + return stream->skip(stream, env, count); +} diff --git a/util/src/string.c b/util/src/string.c new file mode 100644 index 0000000..4a3f8f0 --- /dev/null +++ b/util/src/string.c @@ -0,0 +1,822 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_string.h> +#include <stdlib.h> +#include <ctype.h> +#include <axutil_utils.h> +#include <axutil_utils_defines.h> +#include <stdarg.h> /* NULL */ + +struct axutil_string +{ + axis2_char_t *buffer; + unsigned int length; + unsigned int ref_count; + axis2_bool_t owns_buffer; +}; + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axutil_string_create( + const axutil_env_t *env, + const axis2_char_t *str) +{ + axutil_string_t *string = NULL; + AXIS2_ENV_CHECK(env, NULL); + + /* str can't be null */ + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + return NULL; + } + + string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t)); + if(!string) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + /* set properties */ + string->buffer = NULL; + string->ref_count = 1; + string->owns_buffer = AXIS2_TRUE; + + string->length = axutil_strlen(str); + + if(string->length < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + axutil_string_free(string, env); + return NULL; + } + + string->buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (string->length + 1)); + if(!(string->buffer)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + axutil_string_free(string, env); + return NULL; + } + memcpy(string->buffer, str, string->length + 1); + + return string; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axutil_string_create_assume_ownership( + const axutil_env_t *env, + axis2_char_t **str) +{ + axutil_string_t *string = NULL; + AXIS2_ENV_CHECK(env, NULL); + + /* str can't be null */ + if(!str || !(*str)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + return NULL; + } + + string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t)); + if(!string) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + /* set properties */ + string->buffer = *str; + string->length = axutil_strlen(*str); + string->ref_count = 1; + string->owns_buffer = AXIS2_TRUE; + + if(string->length < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + axutil_string_free(string, env); + return NULL; + } + + return string; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axutil_string_create_const( + const axutil_env_t *env, + axis2_char_t **str) +{ + axutil_string_t *string = NULL; + AXIS2_ENV_CHECK(env, NULL); + + /* str can't be null */ + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + + return NULL; + } + + string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t)); + if(!string) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + /* set properties */ + string->buffer = *str; + string->length = axutil_strlen(*str); + string->ref_count = 1; + string->owns_buffer = AXIS2_FALSE; + + if(string->length < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + axutil_string_free(string, env); + return NULL; + } + + return string; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_string_free( + struct axutil_string *string, + const axutil_env_t *env) +{ + if(!string) + { + return; + } + + string->ref_count--; + + if(string->ref_count > 0) + { + return; + } + + if(string->owns_buffer && string->buffer) + { + AXIS2_FREE(env->allocator, string->buffer); + } + + AXIS2_FREE(env->allocator, string); + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_string_equals( + const struct axutil_string *string, + const axutil_env_t * env, + const struct axutil_string *string1) +{ + if(!string || !string1) + { + return AXIS2_FALSE; + } + + return (string->buffer == string1->buffer); +} + +AXIS2_EXTERN struct axutil_string *AXIS2_CALL +axutil_string_clone( + struct axutil_string *string, + const axutil_env_t *env) +{ + if(!string) + { + return NULL; + } + + string->ref_count++; + + return string; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axutil_string_get_buffer( + const struct axutil_string *string, + const axutil_env_t *env) +{ + if(!string) + { + return NULL; + } + + return string->buffer; +} + +AXIS2_EXTERN unsigned int AXIS2_CALL +axutil_string_get_length( + const struct axutil_string *string, + const axutil_env_t *env) +{ + int error_return = -1; + if(!string) + { + return error_return; + } + + return string->length; +} + +/* END of string struct implementation */ + +/** this is used to cache lengths in axutil_strcat */ +#define MAX_SAVED_LENGTHS 6 + +AXIS2_EXTERN void *AXIS2_CALL +axutil_strdup( + const axutil_env_t *env, + const void *ptr) +{ + if(ptr) + { + int len = axutil_strlen(ptr); + axis2_char_t *str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (len + 1)); + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + memcpy(str, ptr, len + 1); + return (void *)str; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_strmemdup( + const void *ptr, + size_t n, + const axutil_env_t *env) +{ + axis2_char_t *str; + + AXIS2_PARAM_CHECK(env->error, ptr, NULL); + + str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (n + 1)); + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + memcpy(str, ptr, n); + str[n] = '\0'; + + return (void *)str; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_memchr( + const void *ptr, + int c, + size_t n) +{ + const axis2_char_t *cp; + + for(cp = ptr; n > 0; n--, cp++) + { + if(*cp == c) + return (char *)cp; /* Casting away the const here */ + } + + return NULL; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_strndup( + const axutil_env_t *env, + const void *ptr, + int n) +{ + const axis2_char_t *end; + axis2_char_t *str; + + AXIS2_PARAM_CHECK(env->error, ptr, NULL); + + end = axutil_memchr(ptr, '\0', n); + if(end) + n = (int)(end - (axis2_char_t *)ptr); + /* We are sure that the difference lies within the int range */ + str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (n + 1)); + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + memcpy(str, ptr, n); + str[n] = '\0'; + + return (void *)str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strcat( + const axutil_env_t *env, + ...) +{ + axis2_char_t *cp, *argp, *str; + size_t saved_lengths[MAX_SAVED_LENGTHS]; + int nargs = 0; + int str_len = 0; + + /* Pass one --- find length of required string */ + + size_t len = 0; + va_list adummy; + + va_start(adummy, env); + + cp = va_arg(adummy, axis2_char_t *); + while(cp) + { + size_t cplen = strlen(cp); + if(nargs < MAX_SAVED_LENGTHS) + { + saved_lengths[nargs++] = cplen; + } + len += cplen; + cp = va_arg(adummy, axis2_char_t *); + } + + va_end(adummy); + + /* Allocate the required string */ + str_len = (int)(sizeof(axis2_char_t) * (len + 1)); + /* We are sure that the difference lies within the int range */ + str = (axis2_char_t *) AXIS2_MALLOC(env->allocator, str_len); + if (!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + cp = str; + + /* Pass two --- copy the argument strings into the result space */ + + va_start(adummy, env); + + nargs = 0; + argp = va_arg(adummy, axis2_char_t *); + while (argp) + { + if (nargs < MAX_SAVED_LENGTHS) + { + len = saved_lengths[nargs++]; + } + else + { + len = strlen(argp); + } + + memcpy(cp, argp, len); + cp += len; + argp = va_arg(adummy, axis2_char_t *); + } + + va_end(adummy); + + /* Return the result string */ + + *cp = '\0'; + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_stracat( + const axutil_env_t *env, + const axis2_char_t *s1, + const axis2_char_t *s2) +{ + axis2_char_t *ret = NULL; + int alloc_len = -1; + int len1 = 0; + int len2 = 0; + + if(!s1 && !s2) + { + return NULL; + } + if(!s1) + { + return (axis2_char_t *)axutil_strdup(env, s2); + } + if(!s2) + { + return (axis2_char_t *)axutil_strdup(env, s1); + } + + len1 = axutil_strlen(s1); + len2 = axutil_strlen(s2); + alloc_len = len1 + len2 + 1; + ret = (axis2_char_t *)AXIS2_MALLOC(env->allocator, alloc_len * sizeof(axis2_char_t)); + memcpy(ret, s1, len1 * sizeof(axis2_char_t)); + memcpy((ret + len1 * sizeof(axis2_char_t)), s2, len2 * sizeof(axis2_char_t)); + ret[alloc_len * sizeof(axis2_char_t) - sizeof(axis2_char_t)] = '\0'; + return ret; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_strcmp( + const axis2_char_t *s1, + const axis2_char_t *s2) +{ + if(s1 && s2) + { + return strcmp(s1, s2); + } + else + { + return -1; + } +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_strncmp( + const axis2_char_t *s1, + const axis2_char_t *s2, + int n) +{ + if(s1 && s2) + { + return strncmp(s1, s2, n); + } + else + { + return -1; + } +} + +AXIS2_EXTERN axis2_ssize_t AXIS2_CALL +axutil_strlen( + const axis2_char_t *s) +{ + int error_return = -1; + if(s) + { + return (axis2_ssize_t)strlen(s); + /* We are sure that the difference lies within the axis2_ssize_t range */ + } + return error_return; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_strcasecmp( + const axis2_char_t *s1, + const axis2_char_t *s2) +{ + while(*s1 != '\0' && *s2 != '\0') + { + if(*s1 >= 'A' && *s1 <= 'Z' && *s2 >= 'a' && *s2 <= 'z') + { + if(*s2 - *s1 - (char)32 != 0) + { + return 1; + } + } + else if(*s1 >= 'a' && *s1 <= 'z' && *s2 >= 'A' && *s2 <= 'Z') + { + if(*s1 - *s2 - 32 != 0) + { + return 1; + } + } + else if(*s1 - *s2 != 0) + { + return 1; + } + s1++; + s2++; + } + if(*s1 != *s2) + { + return 1; + } + + return 0; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_strncasecmp( + const axis2_char_t *s1, + const axis2_char_t *s2, + const int n) +{ + axis2_char_t *str1 = (axis2_char_t *)s1, *str2 = (axis2_char_t *)s2; + int i = (int)n; + + while(--i >= 0 && toupper((int)*str1) == toupper((int)*str2++)) + { + if(toupper((int)*str1++) == '\0') + { + return (0); + } + } + return (i < 0 ? 0 : toupper((int)*str1) - toupper((int)*--str2)); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strstr( + const axis2_char_t *haystack, + const axis2_char_t *needle) +{ + return strstr(haystack, needle); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strchr( + const axis2_char_t *s, + axis2_char_t ch) +{ + return (axis2_char_t *)strchr(s, ch); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_rindex( + const axis2_char_t *_s, + axis2_char_t _ch) +{ + int i, ilen = axutil_strlen(_s); + if(ilen < 1) + { + return NULL; + } + for(i = ilen - 1; i >= 0; i--) + { + if(_s[i] == _ch) + { + return (axis2_char_t *)(_s + i); + } + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_replace( + const axutil_env_t *env, + axis2_char_t *str, + int s1, + int s2) +{ + axis2_char_t *newstr = NULL; + axis2_char_t *index = NULL; + if(!str) + { + return NULL; + } + + newstr = axutil_strdup(env, str); + index = strchr(newstr, s1); + while(index) + { + newstr[index - newstr] = (axis2_char_t)s2; + /* We are sure that the conversion is safe */ + index = strchr(newstr, s1); + } + return newstr; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strltrim( + const axutil_env_t *env, + const axis2_char_t *_s, + const axis2_char_t *_trim) +{ + axis2_char_t *_p = NULL; + axis2_char_t *ret = NULL; + + if(!_s) + { + return NULL; + } + _p = (axis2_char_t *)_s; + if(!_trim) + { + _trim = " \t\r\n"; + } + + while(*_p) + { + if(!strchr(_trim, *_p)) + { + ret = (axis2_char_t *)axutil_strdup(env, _p); + break; + } + ++_p; + } + return ret; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strrtrim( + const axutil_env_t *env, + const axis2_char_t *_in, + const axis2_char_t *_trim) +{ + axis2_char_t *__tail; + axis2_char_t *_s = NULL; + axis2_char_t *ret = NULL; + + if(_in) + { + _s = axutil_strdup(env, _in); + } + if(!_s) + { + return NULL; + } + __tail = _s + axutil_strlen(_s); + if(!_trim) + { + _trim = " \t\n\r"; + } + while(_s < __tail--) + { + if(!strchr(_trim, *__tail)) + { + ret = _s; + break; + } + *__tail = 0; + } + if(!ret && _s) + { + AXIS2_FREE(env->allocator, _s); + } + return ret; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strtrim( + const axutil_env_t *env, + const axis2_char_t *_s, + const axis2_char_t *_trim) +{ + axis2_char_t *_p = NULL; + axis2_char_t *_q = NULL; + + _p = axutil_strltrim(env, _s, _trim); + _q = axutil_strrtrim(env, _p, _trim); + if(_p) + { + AXIS2_FREE(env->allocator, _p); + } + return _q; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_replace( + axis2_char_t *str, + axis2_char_t old, + axis2_char_t new) +{ + axis2_char_t *str_returns = str; + for(; *str != '\0'; str++) + { + if(*str == old) + { + *str = new; + } + } + return str_returns; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_substring_starting_at( + axis2_char_t *str, + int s) +{ + int len; + int pos_to_shift; + + len = (int)strlen(str); + /* We are sure that the difference lies within the int range */ + pos_to_shift = len - s + 1; + + if(len <= s) + { + return NULL; + } + memmove(str, str + s, pos_to_shift); + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_substring_ending_at( + axis2_char_t *str, + int e) +{ + axis2_char_t *ptr = NULL; + int length = 0; + + length = (int)strlen(str); + /* We are sure that the difference lies within the int range */ + ptr = str; + if(length <= e) + { + return NULL; + } + ptr += e; + *ptr = '\0'; + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_tolower( + axis2_char_t *str) +{ + axis2_char_t *temp_str = NULL; + for(temp_str = str; *temp_str != '\0'; temp_str++) + { + *temp_str = (axis2_char_t)tolower((int)*temp_str); + /* We are sure that the conversion is safe */ + } + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_toupper( + axis2_char_t *str) +{ + axis2_char_t *temp_str = NULL; + for(temp_str = str; *temp_str != '\0'; temp_str++) + { + *temp_str = (axis2_char_t)toupper((int)*temp_str); + /* We are sure that the conversion is safe */ + } + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strcasestr( + const axis2_char_t *haystack, + const axis2_char_t *needle) +{ + axis2_char_t start, current; + size_t len; + + if(!haystack || !needle) + { + return NULL; + } + + if((start = *needle++)) + { + len = strlen(needle); + do + { + do + { + if(!(current = *haystack++)) + { + return NULL; + } + } + while(toupper((int)current) != toupper((int)start)); + } + while(axutil_strncasecmp(haystack, needle, (int)len)); + /* We are sure that the difference lies within the int range */ + haystack--; + } + return (axis2_char_t *)haystack; +} diff --git a/util/src/string_util.c b/util/src/string_util.c new file mode 100644 index 0000000..b89f6fb --- /dev/null +++ b/util/src/string_util.c @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_string_util.h> +#include <string.h> +#include <axutil_utils.h> + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axutil_tokenize( + const axutil_env_t *env, + axis2_char_t *in, + int delim) +{ + axutil_array_list_t *list = NULL; + axis2_char_t *rest = NULL; + axis2_char_t *str = NULL; + axis2_char_t *temp = NULL; + axis2_bool_t loop_state = AXIS2_TRUE; + + axis2_char_t *index = NULL; + + if(!in || !*in) + { + return NULL; + } + list = axutil_array_list_create(env, 10); + if(!list) + { + return NULL; + } + + str = axutil_strdup(env, in); + temp = str; + + do + { + index = strchr(str, delim); + if((!index) && str && *str) + { + axutil_array_list_add(list, env, axutil_strdup(env, str)); + break; + } + + rest = index + 1; + str[index - str] = '\0'; + if(str && *str) + { + axutil_array_list_add(list, env, axutil_strdup(env, str)); + } + + if(!rest || !*rest) + { + break; + } + str = rest; + rest = NULL; + index = NULL; + + } + while(loop_state); + if(temp) + { + AXIS2_FREE(env->allocator, temp); + } + return list; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axutil_first_token( + const axutil_env_t *env, + axis2_char_t *in, + int delim) +{ + axutil_array_list_t *list = NULL; + axis2_char_t *str = NULL; + axis2_char_t *rest = NULL; + axis2_char_t *index = NULL; + + if(!in && !*in) + { + return NULL; + } + + list = axutil_array_list_create(env, 2); + if(!list) + { + return NULL; + } + str = axutil_strdup(env, in); + + index = strchr(str, delim); + if(!index) + { + axutil_array_list_add(list, env, str); + axutil_array_list_add(list, env, axutil_strdup(env, "")); + return list; + } + + rest = index + 1; + str[index - str] = '\0'; + + axutil_array_list_add(list, env, str); + axutil_array_list_add(list, env, axutil_strdup(env, rest)); + return list; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axutil_last_token( + const axutil_env_t *env, + axis2_char_t *in, + int delim) +{ + axutil_array_list_t *list = NULL; + axis2_char_t *str = NULL; + axis2_char_t *rest = NULL; + axis2_char_t *index = NULL; + + if(!in && !*in) + { + return NULL; + } + + list = axutil_array_list_create(env, 2); + if(!list) + { + return NULL; + } + + str = axutil_strdup(env, in); + index = axutil_rindex(str, (axis2_char_t)delim); + /* We are sure that the conversion is safe */ + if(!index) + { + axutil_array_list_add(list, env, axutil_strdup(env, "")); + axutil_array_list_add(list, env, str); + return list; + } + + rest = index + 1; + str[index - str] = '\0'; + + axutil_array_list_add(list, env, str); + axutil_array_list_add(list, env, axutil_strdup(env, rest)); + + return list; +} diff --git a/util/src/thread_pool.c b/util/src/thread_pool.c new file mode 100644 index 0000000..cf1078d --- /dev/null +++ b/util/src/thread_pool.c @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_thread_pool.h> +#include <axutil_env.h> +#include <axutil_error_default.h> + +struct axutil_thread_pool +{ + axutil_allocator_t *allocator; +}; + +AXIS2_EXTERN axutil_thread_pool_t *AXIS2_CALL +axutil_thread_pool_init( + axutil_allocator_t *allocator) +{ + axutil_thread_pool_t *pool = NULL; + + pool = (axutil_thread_pool_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_pool_t)); + + if(!pool) + { + return NULL; + } + pool->allocator = allocator; + + return pool; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_thread_pool_free( + axutil_thread_pool_t *pool) +{ + if(!pool) + { + return; + } + if(!pool->allocator) + { + return; + } + AXIS2_FREE(pool->allocator, pool); + return; +} + +AXIS2_EXTERN axutil_thread_t *AXIS2_CALL +axutil_thread_pool_get_thread( + axutil_thread_pool_t *pool, + axutil_thread_start_t func, + void *data) +{ + if(!pool) + { + return NULL; + } + if(!pool->allocator) + { + return NULL; + } + return axutil_thread_create(pool->allocator, NULL, func, data); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_pool_join_thread( + axutil_thread_pool_t *pool, + axutil_thread_t *thd) +{ + if(!pool || !thd) + { + return AXIS2_FAILURE; + } + return axutil_thread_join(thd); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_pool_exit_thread( + axutil_thread_pool_t *pool, + axutil_thread_t *thd) +{ + if(!pool || !thd) + { + return AXIS2_FAILURE; + } + return axutil_thread_exit(thd, pool->allocator); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_pool_thread_detach( + axutil_thread_pool_t *pool, + axutil_thread_t *thd) +{ + if(!pool || !thd) + { + return AXIS2_FAILURE; + } + return axutil_thread_detach(thd); +} + +AXIS2_EXTERN axutil_env_t *AXIS2_CALL +axutil_init_thread_env( + const axutil_env_t *system_env) +{ + axutil_allocator_t * allocator = NULL; + axutil_error_t *error = NULL; + allocator = axutil_allocator_clone(system_env->allocator); + error = axutil_error_create(allocator); + return axutil_env_create_with_error_log_thread_pool(allocator, error, system_env->log, + system_env-> thread_pool); +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_free_thread_env( + struct axutil_env *thread_env) +{ + if(!thread_env) + { + return; + } + + if(--(thread_env->ref) > 0) + { + return; + } + + /* log, thread_pool and allocator are shared, so do not free them */ + thread_env->log = NULL; + thread_env->thread_pool = NULL; + if(thread_env->error) + { + AXIS2_ERROR_FREE(thread_env->error); + } + AXIS2_FREE(thread_env->allocator, thread_env); +} diff --git a/util/src/types.c b/util/src/types.c new file mode 100644 index 0000000..a47cc67 --- /dev/null +++ b/util/src/types.c @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_types.h> + +AXIS2_EXTERN int AXIS2_CALL +axutil_atoi( + const char *s) +{ + int i, n; + + n = 0; + for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i) + { + n = 10 * n + (s[i] - '0'); + } + return n; +} + +AXIS2_EXTERN int64_t AXIS2_CALL +axutil_atol( + const char *s) +{ + int i; + int64_t n; + + n = 0; + for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i) + { + n = 10 * n + (s[i] - '0'); + } + return n; +} + +AXIS2_EXTERN uint64_t AXIS2_CALL +axutil_strtoul( + const char *s, + char **endptr, + int base) +{ + int i; + uint64_t n; + + n = 0; + for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i) + { + n = 10 * n + (s[i] - '0'); + } + if(endptr != NULL) + { + *endptr = (char *)(s + i); + } + return n; +} + +AXIS2_EXTERN int64_t AXIS2_CALL +axutil_strtol( + const char *s, + char **endptr, + int base) +{ + int i; + int64_t n; + + n = 0; + for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i) + { + n = 10 * n + (s[i] - '0'); + } + if(endptr != NULL) + { + *endptr = (char *)(s + i); + } + return n; +} diff --git a/util/src/uri.c b/util/src/uri.c new file mode 100644 index 0000000..d9e1bd6 --- /dev/null +++ b/util/src/uri.c @@ -0,0 +1,970 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#define AXIS2_WANT_STRFUNC +#include <axutil_uri.h> + +typedef struct schemes_t schemes_t; + +/** Structure to store various schemes and their default ports */ +struct schemes_t +{ + /** The name of the scheme */ + const axis2_char_t *name; + + /** The default port for the scheme */ + axis2_port_t default_port; +}; + +/* Some WWW schemes and their default ports; this is basically /etc/services */ + +/* This will become global when the protocol abstraction comes */ + +/* As the schemes are searched by a linear search, */ + +/* they are sorted by their expected frequency */ +static schemes_t schemes[] = { + {"http", AXIS2_URI_HTTP_DEFAULT_PORT}, + {"ftp", AXIS2_URI_FTP_DEFAULT_PORT}, + {"https", AXIS2_URI_HTTPS_DEFAULT_PORT}, + {"gopher", AXIS2_URI_GOPHER_DEFAULT_PORT}, + {"ldap", AXIS2_URI_LDAP_DEFAULT_PORT}, + {"nntp", AXIS2_URI_NNTP_DEFAULT_PORT}, + {"snews", AXIS2_URI_SNEWS_DEFAULT_PORT}, + {"imap", AXIS2_URI_IMAP_DEFAULT_PORT}, + {"pop", AXIS2_URI_POP_DEFAULT_PORT}, + {"sip", AXIS2_URI_SIP_DEFAULT_PORT}, + {"rtsp", AXIS2_URI_RTSP_DEFAULT_PORT}, + {"wais", AXIS2_URI_WAIS_DEFAULT_PORT}, + {"z39.50r", AXIS2_URI_WAIS_DEFAULT_PORT}, + {"z39.50s", AXIS2_URI_WAIS_DEFAULT_PORT}, + {"prospero", AXIS2_URI_PROSPERO_DEFAULT_PORT}, + {"nfs", AXIS2_URI_NFS_DEFAULT_PORT}, + {"tip", AXIS2_URI_TIP_DEFAULT_PORT}, + {"acap", AXIS2_URI_ACAP_DEFAULT_PORT}, + {"telnet", AXIS2_URI_TELNET_DEFAULT_PORT}, + {"ssh", AXIS2_URI_SSH_DEFAULT_PORT}, + {NULL, 0xFFFF} /* unknown port */ +}; + +/* Here is the hand-optimized parse_uri_components(). There are some wild + * tricks we could pull in assembly language that we don't pull here... like we + * can do word-at-time scans for delimiter characters using the same technique + * that fast axutil_memchr()s use. But that would be way non-portable. -djg + */ + +/* We have a axis2_table_t that we can index by character and it tells us if the + * character is one of the interesting delimiters. Note that we even get + * compares for NUL for free -- it's just another delimiter. + */ + +#define T_COLON 0x01 /* ':' */ +#define T_SLASH 0x02 /* '/' */ +#define T_QUESTION 0x04 /* '?' */ +#define T_HASH 0x08 /* '#' */ +#define T_NUL 0x80 /* '\0' */ + +#if AXIS2_CHARSET_EBCDIC + +/* Delimiter table for the EBCDIC character set */ +static const unsigned char uri_delims[256] = { + T_NUL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, T_SLASH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, T_QUESTION, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, T_COLON, T_HASH, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +#else + +/* Delimiter table for the ASCII character set */ +static const unsigned char uri_delims[256] = { + T_NUL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, T_HASH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, T_SLASH, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, T_COLON, 0, 0, 0, 0, T_QUESTION, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +#endif + +/* it works like this: + if (uri_delims[ch] & NOTEND_foobar) { + then we're not at a delimiter for foobar + } +*/ + +/* Note that we optimize the scheme scanning here, we cheat and let the + * compiler know that it doesn't have to do the & masking. + */ +#define NOTEND_SCHEME (0xff) +#define NOTEND_HOSTINFO (T_SLASH | T_QUESTION | T_HASH | T_NUL) +#define NOTEND_PATH (T_QUESTION | T_HASH | T_NUL) + +/** + * A structure to encompass all of the fields in a uri + */ +struct axutil_uri +{ + /** scheme ("http"/"ftp"/...) */ + axis2_char_t *scheme; + + /** combined [user[:password]\@]host[:port] */ + axis2_char_t *hostinfo; + + /** user name, as in http://user:passwd\@host:port/ */ + axis2_char_t *user; + + /** password, as in http://user:passwd\@host:port/ */ + axis2_char_t *password; + + /** hostname from URI (or from Host: header) */ + axis2_char_t *hostname; + + /** port string (integer representation is in "port") */ + axis2_char_t *port_str; + + /** the request path (or "/" if only scheme://host was given) */ + axis2_char_t *path; + + /** Everything after a '?' in the path, if present */ + axis2_char_t *query; + + /** Trailing "#fragment" string, if present */ + axis2_char_t *fragment; + + /** structure returned from gethostbyname() */ + struct hostent *hostent; + + /** The port number, numeric, valid only if port_str */ + axis2_port_t port; + + /** has the structure been initialized */ + unsigned is_initialized:1; + + /** has the DNS been looked up yet */ + unsigned dns_looked_up:1; + + /** has the dns been resolved yet */ + unsigned dns_resolved:1; + + /** is it an IPv6 URL */ + unsigned is_ipv6:1; +}; + +AXIS2_EXTERN axutil_uri_t *AXIS2_CALL +axutil_uri_create( + const axutil_env_t *env) +{ + axutil_uri_t *uri = NULL; + AXIS2_ENV_CHECK(env, NULL); + + uri = (axutil_uri_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_uri_t)); + + if(!uri) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + uri->scheme = NULL; + uri->hostinfo = NULL; + uri->user = NULL; + uri->password = NULL; + uri->hostname = NULL; + uri->port_str = NULL; + uri->path = NULL; + uri->query = NULL; + uri->fragment = NULL; + uri->hostent = NULL; + uri->port = 0; + uri->is_ipv6 = 0; + + return uri; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_uri_free( + axutil_uri_t *uri, + const axutil_env_t *env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(uri->scheme) + { + AXIS2_FREE(env->allocator, uri->scheme); + uri->scheme = NULL; + } + + if(uri->hostinfo) + { + AXIS2_FREE(env->allocator, uri->hostinfo); + uri->hostinfo = NULL; + } + + if(uri->user) + { + AXIS2_FREE(env->allocator, uri->user); + uri->user = NULL; + } + + if(uri->password) + { + AXIS2_FREE(env->allocator, uri->password); + uri->password = NULL; + } + + if(uri->hostname) + { + AXIS2_FREE(env->allocator, uri->hostname); + uri->hostname = NULL; + } + + if(uri->port_str) + { + AXIS2_FREE(env->allocator, uri->port_str); + uri->port_str = NULL; + } + + if(uri->path) + { + AXIS2_FREE(env->allocator, uri->path); + uri->path = NULL; + } + + if(uri->query) + { + AXIS2_FREE(env->allocator, uri->query); + uri->query = NULL; + } + + if(uri->fragment) + { + AXIS2_FREE(env->allocator, uri->fragment); + uri->fragment = NULL; + } + + AXIS2_FREE(env->allocator, uri); + + return; +} + +/* parse_uri_components(): + * Parse a given URI, fill in all supplied fields of a uri_components + * structure. This eliminates the necessity of extracting host, port, + * path, query info repeatedly in the modules. + * Side effects: + * - fills in fields of uri_components *uptr + * - none on any of the r->* fields + */ + +AXIS2_EXTERN axutil_uri_t *AXIS2_CALL +axutil_uri_parse_string( + const axutil_env_t *env, + const axis2_char_t *uri_str) +{ + axutil_uri_t *uri = NULL; + const axis2_char_t *s; + const axis2_char_t *s1; + const axis2_char_t *hostinfo; + axis2_char_t *endstr; + int port; + int v6_offset1 = 0, v6_offset2 = 0; + + AXIS2_PARAM_CHECK(env->error, uri_str, NULL); + + uri = (axutil_uri_t *)axutil_uri_create(env); + + /* Initialize the structure. parse_uri() and parse_uri_components() + * can be called more than once per request. + */ + uri->is_initialized = 1; + + /* We assume the processor has a branch predictor like most -- + * it assumes forward branches are untaken and backwards are taken. That's + * the reason for the gotos. + */ + if(uri_str[0] == '/') + { + /* RFC2396 #4.3 says that two leading slashes mean we have an + * authority component, not a path! Fixing this looks scary + * with the gotos here. But if the existing logic is valid, + * then presumably a goto pointing to deal_with_authority works. + * + * RFC2396 describes this as resolving an ambiguity. In the + * case of three or more slashes there would seem to be no + * ambiguity, so it is a path after all. + */ + if(uri_str[1] == '/' && uri_str[2] != '/') + { + s = uri_str + 2; + goto deal_with_authority; + } + + deal_with_path: + /* we expect uri to point to first character of path ... remember + * that the path could be empty -- http://foobar?query for example + */ + s = uri_str; + if((!uri->hostinfo && uri_str[0] == '/' && uri_str[1] == '/') || (!uri->scheme + && uri_str[0] == ':')) + { + if(uri) + { + axutil_uri_free(uri, env); + } + uri = NULL; + goto end; + } + while((uri_delims[*(unsigned char *)s] & NOTEND_PATH) == 0) + { + ++s; + } + if(s != uri_str) + { + uri->path = axutil_strmemdup(uri_str, s - uri_str, env); + } + if(*s == 0) + { + goto end; + } + if(*s == '?') + { + ++s; + s1 = strchr(s, '#'); + if(s1) + { + uri->fragment = axutil_strdup(env, s1 + 1); + uri->query = axutil_strmemdup(s, s1 - s, env); + } + else + { + uri->query = axutil_strdup(env, s); + } + goto end; + } + /* otherwise it's a fragment */ + uri->fragment = axutil_strdup(env, s + 1); + + goto end; + } + + /* find the scheme: */ + s = uri_str; + while((uri_delims[*(unsigned char *)s] & NOTEND_SCHEME) == 0) + { + ++s; + } + /* scheme must be non-empty and followed by :// */ + if(s == uri_str || s[0] != ':' || s[1] != '/' || s[2] != '/') + { + if(uri->scheme) + { + AXIS2_FREE(env->allocator, uri->scheme); + uri->scheme = NULL; + } + s = uri_str; /* restart from beginning as the loop must have ended in + * in a wrong place. */ + goto deal_with_authority; + /* backwards predicted taken! */ + } + + uri->scheme = axutil_strmemdup(uri_str, s - uri_str, env); + s += 3; + + deal_with_authority: hostinfo = s; + while((uri_delims[*(unsigned char *)s] & NOTEND_HOSTINFO) == 0) + { + ++s; + } + uri_str = s; /* whatever follows hostinfo is start of uri */ + uri->hostinfo = axutil_strmemdup(hostinfo, uri_str - hostinfo, env); + + /* If there's a username:password@host:port, the @ we want is the last @... + * too bad there's no memrchr()... For the C purists, note that hostinfo + * is definately not the first character of the original uri so therefore + * &hostinfo[-1] < &hostinfo[0] ... and this loop is valid C. + */ + do + { + --s; + } + while(s >= hostinfo && *s != '@'); + if(s < hostinfo) + { + /* again we want the common case to be fall through */ + deal_with_host: + /* We expect hostinfo to point to the first character of + * the hostname. If there's a port it is the first colon, + * except with IPv6. + */ + if(*hostinfo == '[') + { + if(*(hostinfo + 1) == ']') + { + if(uri) + { + axutil_uri_free(uri, env); + } + uri = NULL; + goto end; + } + if((*(hostinfo + 1) >= '0' && *(hostinfo + 1) <= '9') || (*(hostinfo + 1) >= 'a' + && *(hostinfo + 1) <= 'z') || (*(hostinfo + 1) >= 'A' && *(hostinfo + 1) <= 'Z') + || (*(hostinfo + 1) == ':' && *(hostinfo + 2) == ':')) + { + uri->is_ipv6 = 1; + } + else + { + if(uri) + { + axutil_uri_free(uri, env); + } + uri = NULL; + goto end; + } + v6_offset1 = 1; + v6_offset2 = 2; + s = axutil_memchr(hostinfo, ']', uri_str - hostinfo); + if(!s) + { + if(uri) + { + axutil_uri_free(uri, env); + } + uri = NULL; + goto end; + } + if(*++s != ':') + { + s = NULL; /* no port */ + } + } + else if(!*hostinfo || (*hostinfo >= '0' && *hostinfo <= '9') || (*hostinfo >= 'a' + && *hostinfo <= 'z') || (*hostinfo >= 'A' && *hostinfo <= 'Z') || *hostinfo == '?' + || *hostinfo == '/' || *hostinfo == '#') + { + s = axutil_memchr(hostinfo, ':', uri_str - hostinfo); + } + else + { + if(uri) + { + axutil_uri_free(uri, env); + } + uri = NULL; + goto end; + } + if(!s) + { + /* we expect the common case to have no port */ + uri->hostname = axutil_strmemdup(hostinfo + v6_offset1, + uri_str - hostinfo - v6_offset2, env); + goto deal_with_path; + } + uri->hostname = axutil_strmemdup(hostinfo + v6_offset1, s - hostinfo - v6_offset2, env); + ++s; + uri->port_str = axutil_strmemdup(s, uri_str - s, env); + if(uri_str != s) + { + port = strtol(uri->port_str, &endstr, 10); + uri->port = (axis2_port_t)port; + /* We are sure that the conversion is safe */ + if(*endstr == '\0') + { + goto deal_with_path; + } + /* Invalid characters after ':' found */ + if(uri) + { + axutil_uri_free(uri, env); + } + uri = NULL; + goto end; + } + uri->port = axutil_uri_port_of_scheme(uri->scheme); + goto deal_with_path; + } + + /* first colon delimits username:password */ + s1 = axutil_memchr(hostinfo, ':', s - hostinfo); + if(s1) + { + uri->user = axutil_strmemdup(hostinfo, s1 - hostinfo, env); + ++s1; + uri->password = axutil_strmemdup(s1, s - s1, env); + } + else + { + uri->user = axutil_strmemdup(hostinfo, s - hostinfo, env); + } + hostinfo = s + 1; + goto deal_with_host; + + /* End of function call */ + end: return uri; +} + +/* Special case for CONNECT parsing: it comes with the hostinfo part only */ + +/* See the INTERNET-DRAFT document "Tunneling SSL Through a WWW Proxy" + * currently at http://muffin.doit.org/docs/rfc/tunneling_ssl.html + * for the format of the "CONNECT host:port HTTP/1.0" request + */ +AXIS2_EXTERN axutil_uri_t *AXIS2_CALL +axutil_uri_parse_hostinfo( + const axutil_env_t *env, + const axis2_char_t *hostinfo) +{ + axutil_uri_t *uri = NULL; + const axis2_char_t *s; + axis2_char_t *endstr; + const axis2_char_t *rsb; + int v6_offset1 = 0; + + AXIS2_PARAM_CHECK(env->error, hostinfo, NULL); + + uri = (axutil_uri_t *)axutil_uri_create(env); + if(!uri) + { + return NULL; + } + /* Initialize the structure. parse_uri() and parse_uri_components() + * can be called more than once per request. + */ + memset(uri, '\0', sizeof(*uri)); + uri->is_initialized = 1; + uri->hostinfo = axutil_strdup(env, hostinfo); + + /* We expect hostinfo to point to the first character of + * the hostname. There must be a port, separated by a colon + */ + if(*hostinfo == '[') + { + if(*(hostinfo + 1) == ']') + { + axutil_uri_free(uri, env); + return NULL; + } + uri->is_ipv6 = 1; + rsb = strchr(hostinfo, ']'); + if(!rsb || *(rsb + 1) != ':') + { + axutil_uri_free(uri, env); + return NULL; + } + /* literal IPv6 address + * Special allowances has been made according to RFC3986 for + * IPv6 addresses beginning with "::" + */ + s = rsb + 1; + if((*(hostinfo + 1) >= '0' && *(hostinfo + 1) <= '9') || (*(hostinfo + 1) >= 'a' + && *(hostinfo + 1) <= 'z') || (*(hostinfo + 1) >= 'A' && *(hostinfo + 1) <= 'Z') + || (*(hostinfo + 1) == ':' && *(hostinfo + 2) == ':')) + { + ++hostinfo; + } + else + { + axutil_uri_free(uri, env); + return NULL; + } + v6_offset1 = 1; + } + else if((*hostinfo >= '0' && *hostinfo <= '9') || (*hostinfo >= 'a' && *hostinfo <= 'z') + || (*hostinfo >= 'A' && *hostinfo <= 'Z')) + { + s = strchr(hostinfo, ':'); + } + else + { + axutil_uri_free(uri, env); + return NULL; + } + if(!s) + { + axutil_uri_free(uri, env); + return NULL; + } + uri->hostname = axutil_strndup(env, hostinfo, (int)(s - hostinfo - v6_offset1)); + /* We are sure that the difference lies within the int range */ + ++s; + uri->port_str = axutil_strdup(env, s); + if(*s != '\0') + { + uri->port = (unsigned short)strtol(uri->port_str, &endstr, 10); + if(*endstr == '\0') + { + return uri; + } + /* Invalid characters after ':' found */ + } + axutil_uri_free(uri, env); + return NULL; +} + +/* Resolve relative to a base. This means host/etc, and (crucially) path */ +AXIS2_EXTERN axutil_uri_t *AXIS2_CALL +axutil_uri_resolve_relative( + const axutil_env_t *env, + const axutil_uri_t *base, + axutil_uri_t *uri) +{ + AXIS2_PARAM_CHECK(env->error, base, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); + + if(!uri || !base || !base->is_initialized || !uri->is_initialized) + { + return NULL; + } + /* The interesting bit is the path. */ + if(!uri->path) + { + if(!uri->hostname) + { + /* is this compatible with is_initialised? Harmless in any case */ + uri->path = base->path ? base->path : axutil_strdup(env, "/"); + } + else + { + /* deal with the idiosyncracy of APR allowing path==NULL + * without risk of breaking back-compatibility + */ + uri->path = axutil_strdup(env, "/"); + } + } + else if(uri->path[0] != '/') + { + size_t baselen; + const char *basepath = base->path ? base->path : "/"; + char *path = uri->path; + char *temp = NULL; + const char *base_end = strrchr(basepath, '/'); + + temp = path; + + /* if base is nonsensical, bail out */ + if(basepath[0] != '/') + { + return NULL; + } + /* munch "up" components at the start, and chop them from base path */ + while(!strncmp(path, "../", 3)) + { + while(base_end > basepath) + { + if(*--base_end == '/') + { + break; + } + } + path += 3; + } + /* munch "here" components at the start */ + while(!strncmp(path, "./", 2)) + { + path += 2; + } + baselen = base_end - basepath + 1; + uri->path = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * baselen + strlen(path) + 1); + memcpy(uri->path, basepath, baselen); + strcpy(uri->path + baselen, path); + if(temp) + { + AXIS2_FREE(env->allocator, temp); + } + } + + /* The trivial bits are everything-but-path */ + if(!uri->scheme) + { + uri->scheme = axutil_strdup(env, base->scheme); + } + if(!uri->hostinfo) + { + uri->hostinfo = axutil_strdup(env, base->hostinfo); + } + if(!uri->user) + { + uri->user = axutil_strdup(env, base->user); + } + if(!uri->password) + { + uri->password = axutil_strdup(env, base->password); + } + if(!uri->hostname) + { + uri->hostname = axutil_strdup(env, base->hostname); + } + if(!uri->port_str) + { + uri->port_str = axutil_strdup(env, base->port_str); + } + if(!uri->hostent) + { + uri->hostent = base->hostent; + } + if(!uri->port) + { + uri->port = base->port; + } + uri->is_ipv6 = base->is_ipv6; + + return uri; +} + +AXIS2_EXTERN axutil_uri_t *AXIS2_CALL +axutil_uri_parse_relative( + const axutil_env_t *env, + const axutil_uri_t *base, + const char *uri) +{ + axutil_uri_t *uptr = NULL; + axutil_uri_t *temp = NULL; + + uptr = axutil_uri_parse_string(env, uri); + if(!uptr && AXIS2_SUCCESS != AXIS2_ERROR_GET_STATUS_CODE(env->error)) + { + return uptr; + } + temp = uptr; + uptr = axutil_uri_resolve_relative(env, base, uptr); + + if(!uptr) + { + axutil_uri_free(temp, env); + } + + return uptr; +} +AXIS2_EXTERN axis2_port_t AXIS2_CALL +axutil_uri_port_of_scheme( + const axis2_char_t *scheme_str) +{ + schemes_t *scheme; + + if(scheme_str) + { + for(scheme = schemes; scheme->name; ++scheme) + { + if(axutil_strcasecmp(scheme_str, scheme->name) == 0) + { + return scheme->default_port; + } + } + } + return 0; +} + +AXIS2_EXTERN axutil_uri_t *AXIS2_CALL +axutil_uri_clone( + const axutil_uri_t *uri, + const axutil_env_t *env) +{ + axutil_uri_t *new_uri = NULL; + + new_uri = (axutil_uri_t *)axutil_uri_create(env); + + new_uri->scheme = axutil_strdup(env, uri->scheme); + new_uri->hostinfo = axutil_strdup(env, uri->hostinfo); + new_uri->user = axutil_strdup(env, uri->user); + new_uri->password = axutil_strdup(env, uri->password); + new_uri->hostname = axutil_strdup(env, uri->hostname); + new_uri->port_str = axutil_strdup(env, uri->port_str); + new_uri->path = axutil_strdup(env, uri->path); + new_uri->query = axutil_strdup(env, uri->query); + new_uri->fragment = axutil_strdup(env, uri->fragment); + new_uri->hostent = uri->hostent; + new_uri->port = uri->port; + new_uri->is_initialized = uri->is_initialized; + new_uri->dns_looked_up = uri->dns_looked_up; + new_uri->dns_resolved = uri->dns_resolved; + new_uri->is_ipv6 = uri->is_ipv6; + + return new_uri; +} + +/* Unparse a axutil_uri_t structure to an URI string. + * Optionally suppress the password for security reasons. + */ +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_uri_to_string( + const axutil_uri_t *uri, + const axutil_env_t *env, + unsigned flags) +{ + axis2_char_t *ret = ""; + axis2_char_t *temp = NULL; + AXIS2_ENV_CHECK(env, NULL); + + /* If suppressing the site part, omit both user name & scheme://hostname */ + if(!(flags & AXIS2_URI_UNP_OMITSITEPART)) + { + + /* Construct a "user:password@" string, honoring the passed + * AXIS2_URI_UNP_ flags: */ + if(uri->user || uri->password) + { + ret = axutil_strcat(env, (uri->user && !(flags & AXIS2_URI_UNP_OMITUSER)) ? uri-> user + : "", (uri->password && !(flags & AXIS2_URI_UNP_OMITPASSWORD)) ? ":" : "", + (uri->password && !(flags & AXIS2_URI_UNP_OMITPASSWORD)) ? ((flags + & AXIS2_URI_UNP_REVEALPASSWORD) ? uri-> password : "XXXXXXXX") : "", + ((uri->user && !(flags & AXIS2_URI_UNP_OMITUSER)) || (uri->password && !(flags + & AXIS2_URI_UNP_OMITPASSWORD))) ? "@" : "", NULL); + temp = ret; + } + + /* Construct scheme://site string */ + if(uri->hostname) + { + int is_default_port; + const axis2_char_t *lbrk = "", *rbrk = ""; + + if(uri->is_ipv6) + { /* v6 literal */ + lbrk = "["; + rbrk = "]"; + } + + is_default_port = (uri->port_str == NULL || uri->port == 0 || uri->port + == axutil_uri_port_of_scheme(uri->scheme)); + + if(uri->scheme) + { + ret = axutil_strcat(env, uri->scheme, "://", ret, lbrk, uri->hostname, rbrk, + is_default_port ? "" : ":", is_default_port ? "" : uri->port_str, NULL); + if(temp) + { + AXIS2_FREE(env->allocator, temp); + } + temp = ret; + } + else + { + /* Fixed to support Abbreviated URLs as in RFC2396. + * Thus, if no scheme, we omit "//" too, eventhough + * it is a part of authority. + */ + ret = axutil_strcat(env, ret, lbrk, uri->hostname, rbrk, + is_default_port ? "" : ":", is_default_port ? "" : uri->port_str, NULL); + /*ret = + axutil_strcat(env, "//", ret, lbrk, uri->hostname, rbrk, + is_default_port ? "" : ":", + is_default_port ? "" : uri->port_str, NULL);*/ + if(temp) + { + AXIS2_FREE(env->allocator, temp); + } + temp = ret; + } + } + } + + /* Should we suppress all path info? */ + if(!(flags & AXIS2_URI_UNP_OMITPATHINFO)) + { + /* Append path, query and fragment strings: */ + ret = axutil_strcat(env, ret, (uri->path) ? uri->path : "", (uri->query && !(flags + & AXIS2_URI_UNP_OMITQUERY_ONLY)) ? "?" : "", (uri->query && !(flags + & AXIS2_URI_UNP_OMITQUERY_ONLY)) ? uri-> query : "", (uri->fragment && !(flags + & AXIS2_URI_UNP_OMITFRAGMENT_ONLY)) ? "#" : NULL, (uri->fragment && !(flags + & AXIS2_URI_UNP_OMITFRAGMENT_ONLY)) ? uri-> fragment : NULL, NULL); + if(temp) + { + AXIS2_FREE(env->allocator, temp); + } + } + return ret; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_uri_get_protocol( + axutil_uri_t *uri, + const axutil_env_t *env) +{ + return uri->scheme; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_uri_get_server( + axutil_uri_t *uri, + const axutil_env_t *env) +{ + return uri->hostinfo; +} + +AXIS2_EXTERN axis2_port_t AXIS2_CALL +axutil_uri_get_port( + axutil_uri_t *uri, + const axutil_env_t *env) +{ + return uri->port; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_uri_get_host( + axutil_uri_t *uri, + const axutil_env_t *env) +{ + return uri->hostname; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_uri_get_query( + axutil_uri_t *uri, + const axutil_env_t *env) +{ + return uri->query; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_uri_get_fragment( + axutil_uri_t *uri, + const axutil_env_t *env) +{ + return uri->fragment; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_uri_get_path( + axutil_uri_t *uri, + const axutil_env_t *env) +{ + return uri->path; +} diff --git a/util/src/url.c b/util/src/url.c new file mode 100644 index 0000000..e13c87c --- /dev/null +++ b/util/src/url.c @@ -0,0 +1,699 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_url.h> +#include <axutil_string.h> +#include <axutil_string.h> +#include <axutil_file_handler.h> +#include <axutil_network_handler.h> +#include <axutil_types.h> + +struct axutil_url +{ + axis2_char_t *protocol; + axis2_char_t *host; + int port; + axis2_char_t *path; + axis2_char_t *query; + axis2_char_t *server; +}; + +static int +is_safe_or_unreserve( + char c); + +AXIS2_EXTERN axutil_url_t *AXIS2_CALL +axutil_url_create( + const axutil_env_t *env, + const axis2_char_t *protocol, + const axis2_char_t *host, + const int port, + const axis2_char_t *path) +{ + axutil_url_t *url = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, protocol, NULL); + + if(!protocol || !*protocol || strstr(protocol, "://") || (host && strchr(host, '/'))) + { + return NULL; + } + + url = (axutil_url_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_url_t)); + + if(!url) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + url->protocol = axutil_strdup(env, protocol); + url->host = NULL; + url->path = NULL; + url->server = NULL; + url->query = NULL; + + if(host) + { + url->host = (axis2_char_t *)axutil_strdup(env, host); + url->port = port; + } + else + { + url->port = 0; + } + + /** if the path is not starting with / we have to make it so + */ + if(path) + { + axis2_char_t *params = NULL; + axis2_char_t *temp = NULL; + if(path[0] == '/') + { + temp = (axis2_char_t *)axutil_strdup(env, path); + } + else + { + temp = axutil_stracat(env, "/", path); + } + params = strchr(temp, '?'); + if(!params) + { + params = strchr(temp, '#'); + } + if(params) + { + url->query = (axis2_char_t *)axutil_strdup(env, params); + *params = '\0'; + } + url->path = (axis2_char_t *)axutil_strdup(env, temp); + AXIS2_FREE(env->allocator, temp); + } + + return url; +} + +AXIS2_EXTERN axutil_url_t *AXIS2_CALL +axutil_url_parse_string( + const axutil_env_t *env, + const axis2_char_t *str_url) +{ + /** + * Only accepted format is : + * protocol://host:port/path + * Added file:///path + * port is optional and the default port is assumed + * if path is not present / (root) is assumed + */ + axis2_char_t *tmp_url_str = NULL; + axutil_url_t *ret = NULL; + const axis2_char_t *protocol = NULL; + axis2_char_t *path = NULL; + axis2_char_t *port_str = NULL; + axis2_char_t *host = NULL; + int port = 0; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, str_url, NULL); + + tmp_url_str = axutil_strdup(env, str_url); + if(!tmp_url_str) + { + return NULL; + } + protocol = tmp_url_str; + host = strstr(tmp_url_str, "://"); + if(!host) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE); + + AXIS2_FREE(env->allocator, tmp_url_str); + return NULL; + } + if(axutil_strlen(host) < 3 * sizeof(axis2_char_t)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid IP or hostname"); + AXIS2_FREE(env->allocator, tmp_url_str); + return NULL; + } + *host = '\0'; + host += 3 * sizeof(axis2_char_t); /* skip "://" part */ + if(axutil_strlen(host) <= 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid IP or hostname"); + AXIS2_FREE(env->allocator, tmp_url_str); + return NULL; + } + /* if the url is file:// thing we need the protocol and + * path only + */ + if(0 == axutil_strcasecmp(protocol, (const axis2_char_t *)"file")) + { + ret = axutil_url_create(env, protocol, NULL, 0, host); + AXIS2_FREE(env->allocator, tmp_url_str); + return ret; + } + + port_str = strchr(host, ':'); + if(!port_str) + { + path = strchr(host, '/'); + if(!path) + { + path = strchr(host, '?'); + } + else + { + *path++ = '\0'; + } + if(!path) + { + path = strchr(host, '#'); + } + if(!path) + { + /* No path - assume def path ('/') */ + /* here we have protocol + host + def port + def path */ + ret = axutil_url_create(env, protocol, host, port, "/"); + AXIS2_FREE(env->allocator, tmp_url_str); + return ret; + } + else + { + axis2_char_t *path_temp = NULL; + + path_temp = axutil_strdup(env, path); + *path = '\0'; + /* here we have protocol + host + def port + path */ + ret = axutil_url_create(env, protocol, host, port, path_temp); + AXIS2_FREE(env->allocator, tmp_url_str); + AXIS2_FREE(env->allocator, path_temp); + return ret; + } + } + else + { + *port_str++ = '\0'; + path = strchr(port_str, '/'); + if(!path) + { + path = strchr(port_str, '?'); + if(path) + { + *path = '\0'; + port = AXIS2_ATOI(port_str); + *path = '?'; + } + } + else + { + *path++ = '\0'; + port = AXIS2_ATOI(port_str); + } + if(!path) + { + path = strchr(port_str, '#'); + if(path) + { + *path = '\0'; + port = AXIS2_ATOI(port_str); + *path = '#'; + } + } + if(!path) + { + port = AXIS2_ATOI(port_str); + /* here we have protocol + host + port + def path */ + ret = axutil_url_create(env, protocol, host, port, "/"); + AXIS2_FREE(env->allocator, tmp_url_str); + return ret; + } + else + { + if(axutil_strlen(path) > 0) + { + axis2_char_t *path_temp = NULL; + + path_temp = axutil_strdup(env, path); + *path = '\0'; + /* here we have protocol + host + port + path */ + ret = axutil_url_create(env, protocol, host, port, path_temp); + AXIS2_FREE(env->allocator, tmp_url_str); + AXIS2_FREE(env->allocator, path_temp); + return ret; + } + else + { + /* here we have protocol + host + port + def path */ + ret = axutil_url_create(env, protocol, host, port, "/"); + AXIS2_FREE(env->allocator, tmp_url_str); + return ret; + } + } + } +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_url_free( + axutil_url_t *url, + const axutil_env_t *env) +{ + if(url->protocol) + { + AXIS2_FREE(env->allocator, url->protocol); + url->protocol = NULL; + } + if(url->host) + { + AXIS2_FREE(env->allocator, url->host); + url->host = NULL; + } + if(url->server) + { + AXIS2_FREE(env->allocator, url->server); + url->server = NULL; + } + if(url->path) + { + AXIS2_FREE(env->allocator, url->path); + url->path = NULL; + } + if(url->query) + { + AXIS2_FREE(env->allocator, url->query); + url->query = NULL; + } + AXIS2_FREE(env->allocator, url); + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_url_to_external_form( + axutil_url_t *url, + const axutil_env_t *env) +{ + axis2_char_t *external_form = NULL; + axis2_ssize_t len = 0; + axis2_char_t port_str[8]; + axis2_bool_t print_port = AXIS2_FALSE; + AXIS2_PARAM_CHECK(env->error, url, NULL); + + if(!url->protocol) + { + return NULL; + } + + if(url->port != 0 && url->port != axutil_uri_port_of_scheme(url->protocol)) + { + print_port = AXIS2_TRUE; + sprintf(port_str, "%d", url->port); + } + + len = axutil_strlen(url->protocol) + 6; + if(url->host) + { + len += axutil_strlen(url->host); + } + if(url->path) + { + len += axutil_strlen(url->path); + } + if(url->query) + { + len += axutil_strlen(url->query); + } + if(print_port) + { + len += axutil_strlen(port_str) + 1; + } + external_form = (axis2_char_t *)AXIS2_MALLOC(env->allocator, len); + sprintf(external_form, "%s://%s%s%s%s%s", url->protocol, (url->host) ? url->host : "", + (print_port) ? ":" : "", (print_port) ? port_str : "", (url->path) ? url->path : "", + (url->query) ? url->query : ""); + return external_form; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_url_set_protocol( + axutil_url_t *url, + const axutil_env_t *env, + axis2_char_t *protocol) +{ + AXIS2_PARAM_CHECK(env->error, protocol, AXIS2_FAILURE); + if(url->protocol) + { + AXIS2_FREE(env->allocator, url->protocol); + url->protocol = NULL; + } + url->protocol = axutil_strdup(env, protocol); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_url_get_protocol( + axutil_url_t *url, + const axutil_env_t *env) +{ + return url->protocol; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_url_set_host( + axutil_url_t *url, + const axutil_env_t *env, + axis2_char_t *host) +{ + axis2_ssize_t len = 0; + axis2_char_t port_str[8]; + axis2_bool_t print_port = AXIS2_FALSE; + AXIS2_PARAM_CHECK(env->error, host, AXIS2_FAILURE); + + if(url->host) + { + AXIS2_FREE(env->allocator, url->host); + } + url->host = axutil_strdup(env, host); + if(url->server) + { + AXIS2_FREE(env->allocator, url->server); + } + if(!url->host) + { + return AXIS2_SUCCESS; + } + len += axutil_strlen(url->host); + if(url->port != 0 && (!url->protocol || url->port != axutil_uri_port_of_scheme(url->protocol))) + { + print_port = AXIS2_TRUE; + sprintf(port_str, "%d", url->port); + len += axutil_strlen(port_str) + 1; + } + url->server = (axis2_char_t *)AXIS2_MALLOC(env->allocator, len); + sprintf(url->server, "%s%s%s", url->host, (print_port) ? ":" : "", (print_port) ? port_str : ""); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_url_get_host( + axutil_url_t *url, + const axutil_env_t *env) +{ + return url->host; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_url_set_server( + axutil_url_t *url, + const axutil_env_t *env, + axis2_char_t *server) +{ + axis2_char_t *temp = NULL; + axis2_char_t *port_str = NULL; + AXIS2_PARAM_CHECK(env->error, server, AXIS2_FAILURE); + + temp = axutil_strdup(env, server); + if(temp && *temp == ':') + { + AXIS2_FREE(env->allocator, temp); + return AXIS2_FAILURE; + } + + if(strchr(temp, '/')) + { + AXIS2_FREE(env->allocator, temp); + return AXIS2_FAILURE; + } + + if(url->server) + { + AXIS2_FREE(env->allocator, url->server); + } + if(url->host) + { + AXIS2_FREE(env->allocator, url->host); + } + url->port = 0; + + url->server = axutil_strdup(env, server); + + port_str = strchr(temp, ':'); + if(port_str) + { + *port_str++ = '\0'; + url->port = AXIS2_ATOI(port_str); + } + + url->host = axutil_strdup(env, temp); + AXIS2_FREE(env->allocator, temp); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_url_get_server( + axutil_url_t *url, + const axutil_env_t *env) +{ + axis2_ssize_t len = 0; + axis2_char_t port_str[8]; + axis2_bool_t print_port = AXIS2_FALSE; + + if(!url->server && !url->host) + { + return NULL; + } + else if(!url->host) + { + AXIS2_FREE(env->allocator, url->server); + url->server = NULL; + return NULL; + } + else if(url->server) + { + return url->server; + } + len += axutil_strlen(url->host); + if(url->port != 0 && (!url->protocol || url->port != axutil_uri_port_of_scheme(url->protocol))) + { + print_port = AXIS2_TRUE; + sprintf(port_str, "%d", url->port); + len += axutil_strlen(port_str) + 1; /* +1 is for ':' */ + } + url->server = (axis2_char_t *)AXIS2_MALLOC(env->allocator, len + 1); /* +1 is for '/0' */ + sprintf(url->server, "%s%s%s", url->host, (print_port) ? ":" : "", (print_port) ? port_str : ""); + return url->server; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_url_set_port( + axutil_url_t *url, + const axutil_env_t *env, + int port) +{ + axis2_ssize_t len = 0; + axis2_char_t port_str[8]; + axis2_bool_t print_port = AXIS2_FALSE; + if(url->port == port) + { + return AXIS2_SUCCESS; + } + url->port = port; + if(url->server) + { + AXIS2_FREE(env->allocator, url->server); + } + if(!url->host) + { + return AXIS2_SUCCESS; + } + len += axutil_strlen(url->host); + if(url->port != 0 && (!url->protocol || url->port != axutil_uri_port_of_scheme(url->protocol))) + { + print_port = AXIS2_TRUE; + sprintf(port_str, "%d", url->port); + len += axutil_strlen(port_str) + 1; + } + url->server = (axis2_char_t *)AXIS2_MALLOC(env->allocator, len); + sprintf(url->server, "%s%s%s", url->host, (print_port) ? ":" : "", (print_port) ? port_str : ""); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_url_get_port( + axutil_url_t *url, + const axutil_env_t *env) +{ + if(!url->port) + { + return axutil_uri_port_of_scheme(url->protocol); + } + return url->port; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_url_set_path( + axutil_url_t *url, + const axutil_env_t *env, + axis2_char_t * path) +{ + AXIS2_PARAM_CHECK(env->error, path, AXIS2_FAILURE); + if(url->path) + { + AXIS2_FREE(env->allocator, url->path); + } + url->path = axutil_strdup(env, path); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_url_get_path( + axutil_url_t *url, + const axutil_env_t *env) +{ + return url->path; +} + +AXIS2_EXTERN axutil_url_t *AXIS2_CALL +axutil_url_clone( + axutil_url_t *url, + const axutil_env_t *env) +{ + axis2_char_t *temp = NULL; + axutil_url_t *ret = NULL; + + if(url->path && url->query) + { + temp = axutil_stracat(env, url->path, url->query); + } + else if(url->path) + { + temp = axutil_strdup(env, url->path); + } + else if(url->query) + { + temp = axutil_strdup(env, url->query); + } + + ret = axutil_url_create(env, url->protocol, url->host, url->port, url->path); + if(temp) + { + AXIS2_FREE(env->allocator, temp); + } + return ret; +} + +AXIS2_EXTERN axutil_uri_t *AXIS2_CALL +axutil_url_to_uri( + axutil_url_t *url, + const axutil_env_t *env) +{ + axis2_char_t *url_str = NULL; + axutil_uri_t *uri = NULL; + url_str = axutil_url_to_external_form(url, env); + uri = axutil_uri_parse_string(env, url_str); + return uri; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_url_encode( + const axutil_env_t *env, + axis2_char_t *dest, + axis2_char_t *buff, + int len) +{ + axis2_char_t string[4]; + axis2_char_t *expand_buffer = NULL; + axis2_char_t *temp = NULL; + int i; + for(i = 0; i < len && buff[i]; i++) + { + if(isalnum(buff[i]) || is_safe_or_unreserve(buff[i])) + { + sprintf(string, "%c", buff[i]); + } + else + { + /* %%%x is to print % mark with the hex value */ + sprintf(string, "%%%x", buff[i]); + } + + if(((int)strlen(dest) + 4) > len) + { + expand_buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, len * 2); + memset(expand_buffer, 0, len * 2); + len *= 2; + temp = memmove(expand_buffer, dest, strlen(dest)); + if(dest) + { + AXIS2_FREE(env->allocator, dest); + dest = NULL; + } + dest = temp; + } + strcat(dest, string); + } + return dest; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_url_get_query( + axutil_url_t *url, + const axutil_env_t *env) +{ + return url->query; +} + +static int +is_safe_or_unreserve( + char c) +{ + char safe[] = { '-', '_', '.', '~' }; + char reserve[] = { ';', '/', '?', ':', '@', '&', '=', '#', '[', ']', '!', '$', '\'', '(', ')', + '*', '+', ',' }; + + /* These are reserved and safe charaters , got from RFC + * + * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" + * safe = "$" | "-" | "_" | "." | "+" + */ + + int flag = 0; + int i = 0; + + int size = sizeof(safe) / sizeof(safe[0]); + for(i = 0; i < size; i++) + { + if(c == safe[i]) + { + flag = 1; + return flag; + } + } + + size = sizeof(reserve) / sizeof(reserve[0]); + for(i = 0; i < size; i++) + { + if(c == reserve[i]) + { + flag = 0; + return flag; + } + } + return flag; +} diff --git a/util/src/utils.c b/util/src/utils.c new file mode 100644 index 0000000..c69b948 --- /dev/null +++ b/util/src/utils.c @@ -0,0 +1,607 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_utils.h> +#include <stdlib.h> +#include <axutil_string.h> +#include <string.h> +#include <platforms/axutil_platform_auto_sense.h> + +AXIS2_EXPORT axis2_char_t *axis2_request_url_prefix = "services"; + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_parse_rest_url_for_params( + const axutil_env_t *env, + const axis2_char_t *tmpl, + const axis2_char_t *url, + int *match_count, + axis2_char_t ****matches) +{ + axis2_char_t ***ret = NULL; + axis2_char_t *tmp1 = NULL; + axis2_char_t **tmp2 = NULL; + axis2_char_t ***tmp3 = NULL; + axis2_char_t *tmp4 = NULL; + axis2_char_t *resource = NULL; + axis2_char_t *query = NULL; + axis2_char_t *url_tmp = NULL; + axis2_char_t *url_resource = NULL; + axis2_char_t *url_query = NULL; + axis2_bool_t finished = AXIS2_FALSE; + axis2_status_t status = AXIS2_FAILURE; + int ret_count = 0; + int i = 0; + int j = 0; + axis2_bool_t in_tok = AXIS2_FALSE; + + tmp2 = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *))); + memset(tmp2, 0, 2 * sizeof(axis2_char_t *)); + + if(tmpl[0] == '/') + { + tmp1 = (axis2_char_t *)tmpl; + tmp1++; + resource = axutil_strdup(env, tmp1); + } + else + { + resource = axutil_strdup(env, tmpl); + } + i = (int)strlen(resource); + /* We are sure that the difference lies within the int range */ + if(resource[i] == '/') + { + resource[i] = '\0'; + } + tmp1 = strchr(resource, '?'); + if(tmp1) + { + axis2_char_t *tmp4 = NULL; + + tmp4 = tmp1; + tmp1++; + resource[tmp4 - resource] = '\0'; + if(*tmp1 && ((tmp1 - resource) < (int)strlen(resource) - 1)) + /* We are sure that the difference lies within the int range */ + { + query = tmp1; + /* + * Query String based matching is not implemented. This is + * reserved for future implementations. + */ + } + } + + /* Validation of Template */ + i = (int)strlen(resource); + /* We are sure that the difference lies within the int range */ + + if(!strchr(resource, '{') && !strchr(resource, '}')) + { + i = 0; + } + for(j = 0; j < i; j++) + { + if(!in_tok) + { + if(resource[j] == '}') + { + AXIS2_FREE(env->allocator, resource); + return AXIS2_FAILURE; + } + else if(resource[j] == '{') + { + if(j + 1 == i || resource[j + 1] == '}') + { + AXIS2_FREE(env->allocator, resource); + return AXIS2_FAILURE; + } + else if(resource[j + 1] == '{') + { + j++; + } + else + { + in_tok = AXIS2_TRUE; + } + } + } + else + { + if(resource[j] == '{') + { + AXIS2_FREE(env->allocator, resource); + return AXIS2_FAILURE; + } + else if(resource[j] == '}') + { + if(j + 1 < i && resource[j + 1] == '}') + { + j++; + } + else + { + in_tok = AXIS2_FALSE; + } + } + } + } + if(in_tok) + { + AXIS2_FREE(env->allocator, resource); + return AXIS2_FAILURE; + } + + /* Validity of template guaranteed if not returned */ + + if(url[0] == '/') + { + tmp1 = (axis2_char_t *)url; + tmp1++; + url_resource = axutil_strdup(env, tmp1); + } + else + { + url_resource = axutil_strdup(env, url); + } + i = (int)strlen(url_resource); + + /* We are sure that the difference lies within the int range */ + + if(url_resource[i] == '/') + { + url_resource[i] = '\0'; + } + i = 0; + url_tmp = url_resource; + tmp1 = strchr(url_resource, '?'); + if(tmp1) + { + axis2_char_t *tmp4 = NULL; + + tmp4 = tmp1; + tmp1++; + url_resource[tmp4 - url_resource] = '\0'; + if(*tmp1 && ((tmp1 - url_resource) < (int)strlen(url_resource) - 1)) + /* We are sure that the difference lies within the int range */ + { + url_query = tmp1; + } + } + tmp1 = resource; + + /* Simplest case match */ + + if(!strchr(resource, '{')) + { + if(strcmp(resource, url_resource) == 0) + { + finished = AXIS2_TRUE; + } + } + + while(!finished) + { + tmp4 = strchr(tmp1, '{'); + if(tmp4 && tmp4[1]) + { + if(tmp4[1] != '{') + { + axis2_char_t *tmp5 = NULL; + axis2_char_t *tmp6 = NULL; + axis2_char_t *tmp7 = NULL; + axis2_char_t *tmp8 = NULL; + axis2_char_t *tmp9 = NULL; + + /* Logic for finding out constant portion to match */ + i = (int)(tmp4 - tmp1); + tmp2[0] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); + strncpy(tmp2[0], tmp1, i); + tmp2[0][i] = '\0'; + if(url_tmp && *url_tmp) + { + tmp6 = url_tmp; + tmp5 = strstr(tmp6, tmp2[0]); + if(tmp5) + { + tmp5 += strlen(tmp2[0]); + tmp7 = tmp4; + tmp8 = tmp4; + tmp7++; + if(*tmp7) + { + axis2_bool_t finished_tmp = AXIS2_FALSE; + while(!finished_tmp) + { + tmp6 = strchr(tmp8, '}'); + if(tmp6 && *tmp6) + { + if(tmp6[1] != '}') + { + tmp8 = tmp6 + 1; + break; + } + } + else + { + finished_tmp = AXIS2_TRUE; + } + } + if(!finished_tmp && !strchr(tmp8, '{')) + { + tmp7 = tmp8 + strlen(tmp8); + } + else + { + while(!finished_tmp) + { + tmp6 = strchr(tmp8, '{'); + if(tmp6 && tmp6[1]) + { + if(tmp6[1] != '{') + { + tmp7 = tmp6; + break; + } + } + else + { + finished_tmp = AXIS2_TRUE; + } + } + } + if(!finished_tmp) + { + i = (int)(tmp7 - tmp8); + tmp9 = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); + strncpy(tmp9, tmp8, i); + tmp9[i] = '\0'; + } + } + if(tmp9 && *tmp9) + { + tmp6 = strstr(tmp5, tmp9); + AXIS2_FREE(env->allocator, tmp9); + tmp9 = NULL; + } + else + { + tmp6 = strchr(tmp5, '/'); + } + /* Logic for saving the match */ + if(tmp6 && tmp6 != tmp5) + { + i = (int)(tmp6 - tmp5); + url_tmp = tmp6; + tmp2[1] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); + strncpy(tmp2[1], tmp5, i); + tmp2[1][i] = '\0'; + } + else + { + i = (int)strlen(tmp5); + /* We are sure that the difference lies within the int range */ + tmp2[1] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); + strncpy(tmp2[1], tmp5, i); + tmp2[1][i] = '\0'; + url_tmp = NULL; + } + } + } + else + { + break; + } + while(!finished) + { + tmp1 = tmp4 + 1; + tmp4 = strchr(tmp1, '}'); + if(tmp4 && *tmp4) + { + if(tmp4[1] != '}') + { + /* Logic for saving the key for the match */ + i = (int)(tmp4 - tmp1); + if(tmp2[0]) + { + AXIS2_FREE(env->allocator, tmp2[0]); + } + tmp2[0] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); + strncpy(tmp2[0], tmp1, i); + tmp2[0][i] = '\0'; + tmp3 = ret; + ret_count++; + ret = AXIS2_MALLOC(env->allocator, ret_count * 2 + * (sizeof(axis2_char_t *))); + memset(ret, 0, ret_count * 2 * sizeof(axis2_char_t *)); + for(i = 0; i < ret_count - 1; i++) + { + ret[i] = tmp3[i]; + } + ret[i] = tmp2; + tmp2 = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *))); + memset(tmp2, 0, 2 * sizeof(axis2_char_t *)); + tmp3 = NULL; + break; + } + else + { + tmp4++; + } + } + else + { + finished = AXIS2_TRUE; + } + } + } + else + { + tmp4++; + } + } + else + { + /* Result of mismatch at the simplest case */ + if(!strchr(resource, '{')) + { + finished = AXIS2_FALSE; + break; + } + finished = AXIS2_TRUE; + } + tmp1 = tmp4 + 1; + } + if(resource) + { + AXIS2_FREE(env->allocator, resource); + } + if(url_resource) + { + AXIS2_FREE(env->allocator, url_resource); + } + if(tmp2) + { + if(tmp2[0]) + { + AXIS2_FREE(env->allocator, tmp2[0]); + } + if(tmp2[1]) + { + AXIS2_FREE(env->allocator, tmp2[1]); + } + AXIS2_FREE(env->allocator, tmp2); + } + if(finished) + { + status = AXIS2_SUCCESS; + } + *match_count = ret_count; + *matches = ret; + return status; +} + +AXIS2_EXTERN axis2_char_t **AXIS2_CALL +axutil_parse_request_url_for_svc_and_op( + const axutil_env_t *env, + const axis2_char_t *request) +{ + axis2_char_t **ret = NULL; + axis2_char_t *service_str = NULL; + axis2_char_t *tmp = NULL; + int i = 0; + ret = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *))); + memset(ret, 0, 2 * sizeof(axis2_char_t *)); + tmp = (axis2_char_t *)request; + + tmp = strstr(tmp, axis2_request_url_prefix); + if(tmp) + { + service_str = tmp; + tmp += axutil_strlen(axis2_request_url_prefix); + /*break stop on first prefix as user may have prefix in service name */ + } + if(service_str) + { + service_str += axutil_strlen(axis2_request_url_prefix); + if('\0' != *service_str) + { + if(*service_str == '/') + service_str++; /*to remove the leading '/' */ + tmp = strchr(service_str, '/'); + if(tmp) + { + i = (int)(tmp - service_str); + ret[0] = AXIS2_MALLOC(env->allocator, i * sizeof(char) + 1); + strncpy(ret[0], service_str, i); + ret[0][i] = '\0'; + + /* Now search for the op */ + service_str = tmp; + if('\0' != *service_str) + { + service_str++; + tmp = strchr(service_str, '?'); + if(tmp) + { + i = (int)(tmp - service_str); + ret[1] = AXIS2_MALLOC(env->allocator, i * sizeof(char) + 1); + strncpy(ret[1], service_str, i); + ret[1][i] = '\0'; + } + else + { + ret[1] = axutil_strdup(env, service_str); + } + } + } + else + { + ret[0] = axutil_strdup(env, service_str); + } + } + } + return ret; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_xml_quote_string( + const axutil_env_t *env, + const axis2_char_t *s, + axis2_bool_t quotes) +{ + const char *scan; + size_t len = 0; + size_t extra = 0; + char *qstr; + char *qscan; + char c; + + for(scan = s; (c = *scan) != '\0'; ++scan, ++len) + { + if(c == '<' || c == '>') + extra += 3; /* < or > */ + else if(c == '&') + extra += 4; /* & */ + else if(quotes && c == '"') + extra += 5; /* " */ + } + + /* nothing to do */ + if(extra == 0) + return NULL; + + qstr = AXIS2_MALLOC(env->allocator, len + extra + 1); + for(scan = s, qscan = qstr; (c = *scan) != '\0'; ++scan) + { + if(c == '<') + { + *qscan++ = '&'; + *qscan++ = 'l'; + *qscan++ = 't'; + *qscan++ = ';'; + } + else if(c == '>') + { + *qscan++ = '&'; + *qscan++ = 'g'; + *qscan++ = 't'; + *qscan++ = ';'; + } + else if(c == '&') + { + *qscan++ = '&'; + *qscan++ = 'a'; + *qscan++ = 'm'; + *qscan++ = 'p'; + *qscan++ = ';'; + } + else if(quotes && c == '"') + { + *qscan++ = '&'; + *qscan++ = 'q'; + *qscan++ = 'u'; + *qscan++ = 'o'; + *qscan++ = 't'; + *qscan++ = ';'; + } + else + { + *qscan++ = c; + } + } + + *qscan = '\0'; + return qstr; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_url_decode( + const axutil_env_t *env, + axis2_char_t *dest, + axis2_char_t *src) +{ + AXIS2_PARAM_CHECK(env->error, dest, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, src, AXIS2_FAILURE); + + for(; *src != '\0'; ++dest, ++src) + { + if(src[0] == '%' && isxdigit(src[1]) && isxdigit(src[2])) + { + *dest = (axis2_char_t)(axutil_hexit(src[1]) * 16 + axutil_hexit(src[2])); + /* We are sure that the conversion is safe */ + src += 2; + } + else + { + *dest = *src; + } + } + *dest = '\0'; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_hexit( + axis2_char_t c) +{ + if(c >= '0' && c <= '9') + { + return c - '0'; + } + if(c >= 'a' && c <= 'f') + { + return c - 'a' + 10; + } + if(c >= 'A' && c <= 'F') + { + return c - 'A' + 10; + } + return 0; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_char_2_byte( + const axutil_env_t *env, + axis2_char_t *char_buffer, + axis2_byte_t **byte_buffer, + int *byte_buffer_size) +{ + int length = 0; + int i = 0; + axis2_byte_t *bytes = NULL; + + length = (int)axutil_strlen(char_buffer); + bytes = (axis2_byte_t *)AXIS2_MALLOC(env->allocator, length * sizeof(axis2_byte_t)); + + if(!bytes) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create byte buffer"); + return AXIS2_FAILURE; + } + + for(i = 0; i < length; i++) + { + bytes[i] = (axis2_byte_t)char_buffer[i]; + } + *byte_buffer = bytes; + *byte_buffer_size = length; + return AXIS2_SUCCESS; +} + diff --git a/util/src/uuid_gen.c b/util/src/uuid_gen.c new file mode 100644 index 0000000..945b295 --- /dev/null +++ b/util/src/uuid_gen.c @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_uuid_gen.h> + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_uuid_gen( + const axutil_env_t *env) +{ + + axis2_char_t *str = AXIS2_MALLOC(env->allocator, 40 * sizeof(char)); + axutil_platform_uuid_gen(str); + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_UUID_GEN_FAILED, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "AXIS2_ERROR_UUID_GEN_FAILED"); + return NULL; + } + return str; +} diff --git a/util/src/version.c b/util/src/version.c new file mode 100644 index 0000000..9ab586d --- /dev/null +++ b/util/src/version.c @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axutil_version.h> + +AXIS2_EXTERN void AXIS2_CALL +axis2_version( + axis2_version_t *pvsn) +{ + pvsn->major = AXIS2_MAJOR_VERSION; + pvsn->minor = AXIS2_MINOR_VERSION; + pvsn->patch = AXIS2_PATCH_VERSION; +#ifdef AXIS2_IS_DEV_VERSION + pvsn->is_dev = 1; +#else + pvsn->is_dev = 0; +#endif +} + +AXIS2_EXTERN const char *AXIS2_CALL +axis2_version_string( + void) +{ + return AXIS2_VERSION_STRING; +} |