wi_boolean_t wi_cipher_decrypt_bytes(wi_cipher_t *cipher, const void *encrypted_buffer, wi_uinteger_t encrypted_length, void **out_buffer, wi_uinteger_t *out_length) { void *decrypted_buffer; int decrypted_length, padded_length; decrypted_buffer = wi_malloc(encrypted_length + EVP_CIPHER_block_size(cipher->cipher)); if(EVP_DecryptUpdate(&cipher->decrypt_ctx, decrypted_buffer, &decrypted_length, encrypted_buffer, encrypted_length) != 1) { wi_error_set_openssl_error(); wi_free(decrypted_buffer); return false; } if(EVP_DecryptFinal_ex(&cipher->decrypt_ctx, decrypted_buffer + decrypted_length, &padded_length) != 1) { wi_error_set_openssl_error(); wi_free(decrypted_buffer); return false; } if(EVP_DecryptInit_ex(&cipher->decrypt_ctx, NULL, NULL, NULL, NULL) != 1) { wi_error_set_openssl_error(); wi_free(decrypted_buffer); return false; } *out_buffer = decrypted_buffer; *out_length = decrypted_length + padded_length; return true; }
static void _wi_pool_remove_poolstack(_wi_pool_stack_t *stack, uint32_t stack_index) { _wi_pool_stack_t **stacks; uint32_t index, length; index = wi_hash_pointer(wi_thread_current_thread()) % _WI_POOL_STACKS_BUCKETS; wi_lock_lock(_wi_pool_stacks_lock); length = _wi_pool_stacks_lengths[index] - 1; stacks = _wi_pool_stacks[index]; stacks[stack_index] = NULL; _wi_pool_stacks_lengths[index] = length; if(stack_index < length) { memmove(&stacks[stack_index], &stacks[stack_index + 1], sizeof(_wi_pool_stack_t **) * length); } if(stack->pools) wi_free(stack->pools); wi_free(stack); wi_lock_unlock(_wi_pool_stacks_lock); }
int32_t wi_p7_socket_read_oobdata(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout, void *out_buffer, uint32_t out_size) { void *receive_buffer = NULL, *decrypted_buffer, *decompressed_buffer; char length_buffer[_WI_P7_SOCKET_LENGTH_SIZE]; uint32_t receive_size, decompressed_size, decrypted_size; int32_t result = -1; if(wi_socket_read_buffer(p7_socket->socket, timeout, length_buffer, sizeof(length_buffer)) <= 0) goto end; receive_size = wi_read_swap_big_to_host_int32(length_buffer, 0); receive_buffer = wi_malloc(receive_size); result = wi_socket_read_buffer(p7_socket->socket, timeout, receive_buffer, receive_size); if(result <= 0) goto end; if(p7_socket->encryption_enabled) { if(!wi_cipher_decrypt_bytes(p7_socket->cipher, receive_buffer, receive_size, &decrypted_buffer, &decrypted_size)) { goto end; } wi_free(receive_buffer); receive_size = decrypted_size; receive_buffer = decrypted_buffer; } if(p7_socket->compression_enabled) { if(!_wi_p7_socket_xcompress_buffer(p7_socket, _WI_P7_SOCKET_DECOMPRESS, receive_buffer, receive_size, &decompressed_buffer, &decompressed_size)) { goto end; } wi_free(receive_buffer); receive_size = decompressed_size; receive_buffer = decompressed_buffer; } memcpy(out_buffer, receive_buffer, receive_size); result = receive_size; end: wi_free(receive_buffer); return result; }
int32_t wi_p7_socket_write_oobdata(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout, const void *buffer, uint32_t size) { const void *send_buffer; void *compressed_buffer = NULL, *encrypted_buffer = NULL; char length_buffer[_WI_P7_SOCKET_LENGTH_SIZE]; uint32_t send_size, compressed_size, encrypted_size; int32_t result = -1; send_size = size; send_buffer = buffer; if(p7_socket->compression_enabled) { if(!_wi_p7_socket_xcompress_buffer(p7_socket, _WI_P7_SOCKET_COMPRESS, send_buffer, send_size, &compressed_buffer, &compressed_size)) { goto end; } send_size = compressed_size; send_buffer = compressed_buffer; } if(p7_socket->encryption_enabled) { if(!wi_cipher_encrypt_bytes(p7_socket->cipher, send_buffer, send_size, &encrypted_buffer, &encrypted_size)) { goto end; } send_size = encrypted_size; send_buffer = encrypted_buffer; } wi_write_swap_host_to_big_int32(length_buffer, 0, send_size); if(wi_socket_write_buffer(p7_socket->socket, timeout, length_buffer, sizeof(length_buffer)) < 0) goto end; result = wi_socket_write_buffer(p7_socket->socket, timeout, send_buffer, send_size); end: wi_free(compressed_buffer); wi_free(encrypted_buffer); return result; }
static void _wi_list_dealloc(wi_runtime_instance_t *instance) { wi_list_t *list = instance; uint32_t i; wi_list_remove_all_data(list); if(list->node_chunks) { for(i = 0; i < list->node_chunks_count; i++) wi_free(list->node_chunks[i]); wi_free(list->node_chunks); } wi_release(list->lock); }
int wi_delfile(wi_file * delfile) { wi_sess * sess; wi_file * tmpfi; wi_file * last; /* unlink file from session list */ sess = delfile->wf_sess; last = NULL; for(tmpfi = sess->ws_filelist; tmpfi; tmpfi = tmpfi->wf_next) { if(tmpfi == delfile) { if(last) last->wf_next = delfile->wf_next; else sess->ws_filelist = delfile->wf_next; break; } last = tmpfi; } wi_free(delfile); return 0; }
void wi_txfree(txbuf * oldtx) { wi_sess * websess; txbuf * tmptx; txbuf * last; /* This has most likely been unlinked already, but try to find it * in the sesion queue just in case. */ websess = oldtx->tb_session; last = NULL; for(tmptx = websess->ws_txbufs; tmptx; tmptx = tmptx->tb_next) { if(tmptx == oldtx) { if(last) last->tb_next = oldtx->tb_next; else websess->ws_txbufs = oldtx->tb_next; break; } } wi_free(oldtx); return; }
int em_fclose(void * voidfd) { EOFILE * passedfd; EOFILE * tmpfd; EOFILE * last; passedfd = (EOFILE *)voidfd; /* verify file pointer is valid */ last = NULL; for(tmpfd = em_openlist; tmpfd; tmpfd = tmpfd->eo_next) { if(tmpfd == passedfd) /* If we found it, unlink */ { if(last) last->eo_next = passedfd->eo_next; else em_openlist = passedfd->eo_next; break; } last = tmpfd; } if(tmpfd == NULL) /* fd not in list? */ return WIE_BADFILE; wi_free(passedfd); return 0; }
static void _wi_set_dealloc(wi_runtime_instance_t *instance) { wi_set_t *set = instance; wi_uinteger_t i; _wi_set_remove_all_data(set); if(set->bucket_chunks) { for(i = 0; i < set->bucket_chunks_count; i++) wi_free(set->bucket_chunks[i]); wi_free(set->bucket_chunks); } wi_free(set->buckets); wi_release(set->lock); }
static void _wi_array_dealloc(wi_runtime_instance_t *instance) { wi_array_t *array = instance; wi_uinteger_t i; wi_array_remove_all_data(array); if(array->item_chunks) { for(i = 0; i < array->item_chunks_count; i++) wi_free(array->item_chunks[i]); wi_free(array->item_chunks); } wi_release(array->lock); wi_free(array->items); }
static void _wi_dictionary_dealloc(wi_runtime_instance_t *instance) { wi_dictionary_t *dictionary = instance; wi_uinteger_t i; _wi_dictionary_remove_all_data(dictionary); if(dictionary->bucket_chunks) { for(i = 0; i < dictionary->bucket_chunks_count; i++) wi_free(dictionary->bucket_chunks[i]); wi_free(dictionary->bucket_chunks); } wi_free(dictionary->buckets); wi_release(dictionary->lock); }
static void _wi_dictionary_dealloc(wi_runtime_instance_t *instance) { wi_dictionary_t *dictionary = instance; _wi_dictionary_bucket_t *bucket; wi_uinteger_t i; for(i = 0; i < dictionary->buckets_count; i++) { for(bucket = dictionary->buckets[i]; bucket; bucket = bucket->next) { _WI_DICTIONARY_VALUE_RELEASE(dictionary, bucket->data); _WI_DICTIONARY_KEY_RELEASE(dictionary, bucket->key); } } if(dictionary->bucket_chunks) { for(i = 0; i < dictionary->bucket_chunks_count; i++) wi_free(dictionary->bucket_chunks[i]); wi_free(dictionary->bucket_chunks); } wi_free(dictionary->buckets); }
static void _wi_pool_dealloc(wi_runtime_instance_t *instance) { wi_pool_t *pool = (wi_pool_t *) instance; _wi_pool_array_t *array, *next_array; _wi_pool_remove_pool(pool); _wi_pool_pop_pool(pool); for(array = pool->array; array; array = next_array) { next_array = array->next; wi_free(array); } }
wi_data_t * wi_string_encoding_data_from_utf8_bytes(wi_string_encoding_t *encoding, const char *buffer, wi_uinteger_t size) { wi_data_t *data; char *inbuffer, *outbuffer, *outbufferp; wi_uinteger_t inbytes, outbytes; size_t bytes, inbytesleft, outbytesleft; iconv_t iconvd; iconvd = iconv_open(wi_string_utf8_string(encoding->target_encoding), wi_string_utf8_string(encoding->utf8_encoding)); if(iconvd == (iconv_t) -1) { wi_error_set_errno(errno); return NULL; } inbytes = inbytesleft = size; outbytes = outbytesleft = size * 4; inbuffer = (char *) buffer; outbuffer = outbufferp = wi_malloc(outbytes); bytes = iconv(iconvd, &inbuffer, &inbytesleft, &outbuffer, &outbytesleft); if(bytes == (size_t) -1) { wi_free(outbufferp); iconv_close(iconvd); wi_error_set_errno(errno); return NULL; } data = wi_data_init_with_bytes(wi_data_alloc(), outbufferp, outbytes - outbytesleft); wi_free(outbufferp); iconv_close(iconvd); return wi_autorelease(data); }
wi_boolean_t wi_thread_create_thread_with_priority(wi_thread_func_t *function, wi_runtime_instance_t *argument, double priority) { #ifdef WI_PTHREADS #if defined(HAVE_PTHREAD_ATTR_SETSCHEDPOLICY) && defined(HAVE_SCHED_GET_PRIORITY_MIN) && defined(HAVE_SCHED_GET_PRIORITY_MAX) struct sched_param param; int min, max; #endif pthread_t thread; pthread_attr_t attr; void **vector; int err; vector = wi_malloc(2 * sizeof(void *)); vector[0] = function; vector[1] = wi_retain(argument); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); #if defined(HAVE_PTHREAD_ATTR_SETSCHEDPOLICY) && defined(HAVE_SCHED_GET_PRIORITY_MIN) && defined(HAVE_SCHED_GET_PRIORITY_MAX) min = sched_get_priority_min(SCHED_OTHER); max = sched_get_priority_max(SCHED_OTHER); if(min > 0 && max > 0) param.sched_priority = min + ((max - min) * priority); else param.sched_priority = 0; pthread_attr_setschedpolicy(&attr, SCHED_OTHER); pthread_attr_setschedparam(&attr, ¶m); #endif err = pthread_create(&thread, &attr, _wi_thread_trampoline, vector); pthread_attr_destroy(&attr); if(err != 0) { wi_error_set_errno(err); wi_release(vector[1]); wi_free(vector); return false; } return true; #else wi_error_set_errno(WI_ERROR_THREADS_NOTSUPP); return false; #endif }
static void _wi_p7_message_dealloc(wi_runtime_instance_t *instance) { wi_p7_message_t *p7_message = instance; wi_release(p7_message->spec); wi_release(p7_message->name); if(p7_message->binary_buffer) wi_free(p7_message->binary_buffer); if(p7_message->xml_buffer) xmlFree(p7_message->xml_buffer); wi_release(p7_message->xml_string); }
wi_array_t * wi_dictionary_keys_sorted_by_value(wi_dictionary_t *dictionary, wi_compare_func_t *compare) { wi_mutable_array_t *array, *buckets; _wi_dictionary_bucket_t *bucket; wi_array_callbacks_t callbacks; void **data; wi_uinteger_t i; if(dictionary->key_count == 0) return wi_autorelease(wi_array_init(wi_array_alloc())); callbacks.retain = NULL; callbacks.release = NULL; callbacks.is_equal = NULL; callbacks.description = NULL; buckets = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->buckets_count; i++) { for(bucket = dictionary->buckets[i]; bucket; bucket = bucket->next) wi_mutable_array_add_data(buckets, bucket); } data = wi_malloc(sizeof(void *) * dictionary->key_count); wi_array_get_data(buckets, data); #ifdef _WI_DICTIONARY_USE_QSORT_R qsort_r(data, dictionary->key_count, sizeof(void *), compare, _wi_dictionary_compare_buckets); #else wi_lock_lock(_wi_dictionary_sort_lock); _wi_dictionary_sort_function = compare; qsort(data, dictionary->key_count, sizeof(void *), _wi_dictionary_compare_buckets); wi_lock_unlock(_wi_dictionary_sort_lock); #endif callbacks.retain = dictionary->key_callbacks.retain; callbacks.release = dictionary->key_callbacks.release; callbacks.is_equal = dictionary->key_callbacks.is_equal; callbacks.description = dictionary->key_callbacks.description; array = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->key_count; i++) wi_mutable_array_add_data(array, ((_wi_dictionary_bucket_t *) data[i])->key); wi_free(data); wi_release(buckets); wi_runtime_make_immutable(array); return wi_autorelease(array); }
int32_t wi_socket_recvfrom(wi_socket_t *socket, wi_socket_context_t *context, char *buffer, size_t length, wi_address_t **address) { struct sockaddr_storage ss; char *inbuffer = NULL; socklen_t sslength; int bytes; sslength = sizeof(ss); #ifdef WI_SSL if(context && context->priv_rsa) { inbuffer = wi_malloc(length); bytes = recvfrom(socket->sd, inbuffer, length, 0, (struct sockaddr *) &ss, &sslength); if(bytes < 0) { wi_error_set_errno(errno); goto end; } bytes = RSA_private_decrypt(bytes, (unsigned char *) inbuffer, (unsigned char *) buffer, context->priv_rsa, RSA_PKCS1_OAEP_PADDING); if(bytes < 0) { wi_error_set_ssl_error(); goto end; } } else { #endif bytes = recvfrom(socket->sd, buffer, length, 0, (struct sockaddr *) &ss, &sslength); if(bytes < 0) { wi_error_set_errno(errno); goto end; } #ifdef WI_SSL } #endif end: *address = (sslength > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL; if(inbuffer) wi_free(inbuffer); return bytes; }
static wi_boolean_t _wi_p7_socket_xcompress_buffer(wi_p7_socket_t *p7_socket, _wi_p7_socket_compression_t compression, const void *in_buffer, uint32_t in_size, void **out_buffer, uint32_t *out_size) { const void *input; void *output, *working_buffer; z_stream *stream; uint32_t offset, input_size, input_processed, output_size, working_size, total_working_size; int err; stream = (compression == _WI_P7_SOCKET_COMPRESS) ? &p7_socket->compression_stream : &p7_socket->decompression_stream; working_size = (compression == _WI_P7_SOCKET_COMPRESS) ? in_size : 4 * in_size; working_buffer = wi_malloc(working_size); input = in_buffer; input_size = in_size; output = working_buffer; output_size = working_size; total_working_size = 0; while(true) { err = _wi_p7_socket_xflate_buffer(stream, compression, input, input_size, &input_processed, output, &output_size); if(err != Z_OK) { wi_error_set_zlib_error(err); wi_free(working_buffer); return false; } total_working_size += output_size; if(stream->avail_out > 0) break; offset = (output - working_buffer) + output_size; working_size *= 4; working_buffer = wi_realloc(working_buffer, working_size); output = working_buffer + offset; output_size = working_size - offset; input += input_processed; input_size -= input_processed; } *out_buffer = working_buffer; *out_size = total_working_size; return true; }
void wi_delsess(wi_sess * oldsess) { wi_sess * tmpsess; wi_sess * lastsess; if(oldsess->ws_socket != INVALID_SOCKET) { closesocket(oldsess->ws_socket); oldsess->ws_socket = 0; } /* Unlink from master session list */ lastsess = NULL; for(tmpsess = wi_sessions; tmpsess; tmpsess = tmpsess->ws_next) { if(tmpsess == oldsess) /* Found session to unlink? */ { if(lastsess) lastsess->ws_next = tmpsess->ws_next; else wi_sessions = tmpsess->ws_next; break; } lastsess= tmpsess; } /* Make sure there are no dangling resources */ if(oldsess->ws_txbufs) { while(oldsess->ws_txbufs) { wi_txfree(oldsess->ws_txbufs); } } if(oldsess->ws_filelist) { if(oldsess->ws_filelist) { wi_fclose( oldsess->ws_filelist); } } wi_free(oldsess); /* free the actual memory */ return; }
wi_t wi_new(bool is_sim) { wi_t self = (wi_t)malloc(sizeof(struct wi_struct)); if (!self) { return NULL; } memset(self, 0, sizeof(struct wi_struct)); self->on_recv = wi_on_recv; self->send_plist = wi_send_plist; self->recv_packet = wi_recv_packet; self->on_error = wi_on_error; self->private_state = wi_private_new(); if (!self->private_state) { wi_free(self); return NULL; } self->private_state->is_sim = is_sim; return self; }
static void * _wi_thread_trampoline(void *arg) { void **vector = (void **) arg; wi_thread_func_t *function; wi_runtime_instance_t *argument; function = vector[0]; argument = vector[1]; wi_free(vector); wi_thread_enter_thread(); (*function)(argument); wi_thread_exit_thread(); wi_release(argument); return NULL; }
wi_boolean_t wi_rsa_decrypt_bytes(wi_rsa_t *rsa, const void *encrypted_buffer, wi_uinteger_t encrypted_length, void **out_buffer, wi_uinteger_t *out_length) { void *decrypted_buffer; int32_t decrypted_length; decrypted_buffer = wi_malloc(RSA_size(rsa->rsa)); decrypted_length = RSA_private_decrypt(encrypted_length, encrypted_buffer, decrypted_buffer, rsa->rsa, RSA_PKCS1_PADDING); if(decrypted_length == -1) { wi_error_set_openssl_error(); wi_free(decrypted_buffer); return false; } *out_buffer = decrypted_buffer; *out_length = decrypted_length; return true; }
int32_t wi_socket_sendto_buffer(wi_socket_t *socket, wi_socket_context_t *context, const char *buffer, size_t length) { wi_address_t *address; char *outbuffer = NULL; int bytes; address = wi_socket_address(socket); #ifdef WI_SSL if(context && context->pub_rsa) { outbuffer = wi_malloc(RSA_size(context->pub_rsa)); bytes = RSA_public_encrypt(length, (unsigned char *) buffer, (unsigned char *) outbuffer, context->pub_rsa, RSA_PKCS1_OAEP_PADDING); if(bytes < 0) { wi_error_set_ssl_error(); goto end; } bytes = sendto(socket->sd, outbuffer, bytes, 0, wi_address_sa(address), wi_address_sa_length(address)); } else { #endif bytes = sendto(socket->sd, buffer, length, 0, wi_address_sa(address), wi_address_sa_length(address)); #ifdef WI_SSL } #endif if(bytes < 0) { wi_error_set_errno(errno); goto end; } end: if(outbuffer) wi_free(outbuffer); return bytes; }
wi_integer_t wi_socket_sendto_buffer(wi_socket_t *socket, const char *buffer, size_t length) { wi_address_t *address; char *outbuffer = NULL; wi_integer_t bytes; address = wi_socket_address(socket); bytes = sendto(socket->sd, buffer, length, 0, wi_address_sa(address), wi_address_sa_length(address)); if(bytes < 0) { wi_error_set_errno(errno); goto end; } end: if(outbuffer) wi_free(outbuffer); return bytes; }
static int wi_pccard_attach(device_t dev) { struct wi_softc *sc; int error; sc = device_get_softc(dev); sc->wi_gone = 0; sc->wi_bus_type = WI_BUS_PCCARD; error = wi_alloc(dev, 0); if (error == 0) { /* Make sure interrupts are disabled. */ CSR_WRITE_2(sc, WI_INT_EN, 0); CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); error = wi_attach(dev); if (error != 0) wi_free(dev); } return error; }
static void _wi_set_resize(wi_set_t *set) { _wi_set_bucket_t **buckets, *bucket, *next_bucket; wi_uinteger_t i, index, capacity, buckets_count; capacity = wi_exp2m1(wi_log2(set->data_count) + 1); buckets_count = WI_CLAMP(capacity, set->min_count, _WI_SET_MAX_COUNT); buckets = wi_malloc(buckets_count * sizeof(_wi_set_bucket_t *)); for(i = 0; i < set->buckets_count; i++) { for(bucket = set->buckets[i]; bucket; bucket = next_bucket) { next_bucket = bucket->next; index = _WI_SET_HASH(set, bucket->data) % buckets_count; bucket->next = buckets[index]; buckets[index] = bucket; } } wi_free(set->buckets); set->buckets = buckets; set->buckets_count = buckets_count; }
static void _wi_dictionary_optimize(wi_dictionary_t *dictionary) { _wi_dictionary_bucket_t **buckets, *bucket, *next_bucket; wi_uinteger_t i, index, capacity, buckets_count; capacity = wi_exp2m1(wi_log2(dictionary->key_count) + 1); buckets_count = WI_CLAMP(capacity, dictionary->min_count, _WI_DICTIONARY_MAX_COUNT); buckets = wi_malloc(buckets_count * sizeof(_wi_dictionary_bucket_t *)); for(i = 0; i < dictionary->buckets_count; i++) { for(bucket = dictionary->buckets[i]; bucket; bucket = next_bucket) { next_bucket = bucket->next; index = _WI_DICTIONARY_KEY_HASH(dictionary, bucket->key) % buckets_count; bucket->next = buckets[index]; buckets[index] = bucket; } } wi_free(dictionary->buckets); dictionary->buckets = buckets; dictionary->buckets_count = buckets_count; }
wi_integer_t wi_socket_recvfrom(wi_socket_t *socket, char *buffer, size_t length, wi_address_t **address) { struct sockaddr_storage ss; char *inbuffer = NULL; socklen_t sslength; wi_integer_t bytes; sslength = sizeof(ss); bytes = recvfrom(socket->sd, buffer, length, 0, (struct sockaddr *) &ss, &sslength); if(bytes < 0) { wi_error_set_errno(errno); goto end; } end: *address = (sslength > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL; if(inbuffer) wi_free(inbuffer); return bytes; }
void wi_array_sort(wi_array_t *array, wi_compare_func_t *compare) { void **data; wi_uinteger_t i; if(array->data_count == 0) return; data = wi_malloc(sizeof(void *) * array->data_count); wi_array_get_data(array, data); #ifdef HAVE_QSORT_R qsort_r(data, array->data_count, sizeof(void *), compare, _wi_array_compare_data); #else wi_lock_lock(_wi_array_sort_lock); _wi_array_sort_function = compare; qsort(data, array->data_count, sizeof(void *), _wi_array_compare_data); wi_lock_unlock(_wi_array_sort_lock); #endif for(i = 0; i < array->data_count; i++) array->items[i]->data = data[i]; wi_free(data); }