ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data, esl_size_t maxlen) { char *pe, *p, *e, *head = (char *) buffer->head; esl_size_t datalen = 0; esl_assert(buffer != NULL); esl_assert(data != NULL); e = (head + buffer->used); for (p = head; p && *p && p < e; p++) { if (*p == '\n') { pe = p+1; if (*pe == '\r') pe++; if (pe <= e && *pe == '\n') { pe++; datalen = pe - head; if (datalen > maxlen) { datalen = maxlen; } break; } } } return esl_buffer_read(buffer, data, datalen); }
ESL_DECLARE(void) esl_buffer_zero(esl_buffer_t *buffer) { esl_assert(buffer != NULL); esl_assert(buffer->data != NULL); buffer->used = 0; buffer->actually_used = 0; buffer->head = buffer->data; }
ESL_DECLARE(esl_status_t) esl_event_create_subclass(esl_event_t **event, esl_event_types_t event_id, const char *subclass_name) { *event = NULL; if ((event_id != ESL_EVENT_CLONE && event_id != ESL_EVENT_CUSTOM) && subclass_name) { return ESL_FAIL; } *event = ALLOC(sizeof(esl_event_t)); esl_assert(*event); memset(*event, 0, sizeof(esl_event_t)); if (event_id != ESL_EVENT_CLONE) { (*event)->event_id = event_id; esl_event_add_header_string(*event, ESL_STACK_BOTTOM, "Event-Name", esl_event_name((*event)->event_id)); } if (subclass_name) { (*event)->subclass_name = DUP(subclass_name); esl_event_add_header_string(*event, ESL_STACK_BOTTOM, "Event-Subclass", subclass_name); } return ESL_SUCCESS; }
ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer) { esl_assert(buffer != NULL); return buffer->datalen; }
ESL_DECLARE(esl_status_t) esl_event_del_header_val(esl_event_t *event, const char *header_name, const char *val) { esl_event_header_t *hp, *lp = NULL, *tp; esl_status_t status = ESL_FALSE; int x = 0; esl_ssize_t hlen = -1; unsigned long hash = 0; tp = event->headers; while (tp) { hp = tp; tp = tp->next; x++; esl_assert(x < 1000000); hash = esl_ci_hashfunc_default(header_name, &hlen); if ((!hp->hash || hash == hp->hash) && (hp->name && !strcasecmp(header_name, hp->name)) && (esl_strlen_zero(val) || !strcmp(hp->value, val))) { if (lp) { lp->next = hp->next; } else { event->headers = hp->next; } if (hp == event->last_header || !hp->next) { event->last_header = lp; } FREE(hp->name); if (hp->idx) { int i = 0; hp->value = NULL; for (i = 0; i < hp->idx; i++) { FREE(hp->array[i]); } FREE(hp->array); } FREE(hp->value); memset(hp, 0, sizeof(*hp)); #ifdef ESL_EVENT_RECYCLE if (esl_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, hp) != ESL_SUCCESS) { FREE(hp); } #else FREE(hp); #endif status = ESL_SUCCESS; } else { lp = hp; } } return status; }
ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer) { esl_assert(buffer != NULL); if (buffer->max_len) { return (esl_size_t) (buffer->max_len - buffer->used); } return 1000000; }
ESL_DECLARE(esl_size_t) esl_buffer_read(esl_buffer_t *buffer, void *data, esl_size_t datalen) { esl_size_t reading = 0; esl_assert(buffer != NULL); esl_assert(data != NULL); if (buffer->used < 1) { buffer->used = 0; return 0; } else if (buffer->used >= datalen) { reading = datalen; } else { reading = buffer->used; } memcpy(data, buffer->head, reading); buffer->used -= reading; buffer->head += reading; /* if (buffer->id == 4) printf("%u o %d = %d\n", buffer->id, (unsigned)reading, (unsigned)buffer->used); */ return reading; }
ESL_DECLARE(void) esl_event_merge(esl_event_t *event, esl_event_t *tomerge) { esl_event_header_t *hp; esl_assert(tomerge && event); for (hp = tomerge->headers; hp; hp = hp->next) { if (hp->idx) { int i; for(i = 0; i < hp->idx; i++) { esl_event_add_header_string(event, ESL_STACK_PUSH, hp->name, hp->array[i]); } } else { esl_event_add_header_string(event, ESL_STACK_BOTTOM, hp->name, hp->value); } } }
ESL_DECLARE(int) esl_event_add_array(esl_event_t *event, const char *var, const char *val) { char *data; char **array; int max = 0; int len; const char *p; int i; if (strlen(val) < 8) { return -1; } p = val + 7; max = 1; while((p = strstr(p, "|:"))) { max++; p += 2; } if (!max) { return -2; } data = strdup(val + 7); len = (sizeof(char *) * max) + 1; array = malloc(len); esl_assert(array); memset(array, 0, len); esl_separate_string_string(data, "|:", array, max); for(i = 0; i < max; i++) { esl_event_add_header_string(event, ESL_STACK_PUSH, var, array[i]); } free(array); free(data); return 0; }
ESL_DECLARE(char *)esl_event_get_header(esl_event_t *event, const char *header_name) { esl_event_header_t *hp; esl_ssize_t hlen = -1; unsigned long hash = 0; esl_assert(event); if (!header_name) return NULL; hash = esl_ci_hashfunc_default(header_name, &hlen); for (hp = event->headers; hp; hp = hp->next) { if ((!hp->hash || hash == hp->hash) && !strcasecmp(hp->name, header_name) ) { return hp->value; } } return NULL; }
ESL_DECLARE(esl_size_t) esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen) { esl_size_t reading = 0; esl_assert(buffer != NULL); if (buffer->used < 1) { buffer->used = 0; return 0; } else if (buffer->used >= datalen) { reading = datalen; } else { reading = buffer->used; } buffer->used = buffer->actually_used - reading; buffer->head = buffer->data + reading; return reading; }
ESL_DECLARE(esl_size_t) esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen) { esl_size_t reading = 0; esl_assert(buffer != NULL); if (buffer->used < 1) { buffer->used = 0; return 0; } else if (buffer->used >= datalen) { reading = datalen; } else { reading = buffer->used; } buffer->used -= reading; buffer->head += reading; return buffer->used; }
ESL_DECLARE(esl_size_t) esl_buffer_packet_count(esl_buffer_t *buffer) { char *pe, *p, *e, *head = (char *) buffer->head; esl_size_t x = 0; esl_assert(buffer != NULL); e = (head + buffer->used); for (p = head; p && *p && p < e; p++) { if (*p == '\n') { pe = p+1; if (*pe == '\r') pe++; if (pe <= e && *pe == '\n') { p = pe++; x++; } } } return x; }
static esl_event_header_t *new_header(const char *header_name) { esl_event_header_t *header; #ifdef ESL_EVENT_RECYCLE void *pop; if (esl_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == ESL_SUCCESS) { header = (esl_event_header_t *) pop; } else { #endif header = ALLOC(sizeof(*header)); esl_assert(header); #ifdef ESL_EVENT_RECYCLE } #endif memset(header, 0, sizeof(*header)); header->name = DUP(header_name); return header; }
ESL_DECLARE(esl_status_t) esl_event_del_header_val(esl_event_t *event, const char *header_name, const char *val) { esl_event_header_t *hp, *lp = NULL, *tp; esl_status_t status = ESL_FAIL; int x = 0; esl_ssize_t hlen = -1; unsigned long hash = 0; tp = event->headers; while (tp) { hp = tp; tp = tp->next; x++; esl_assert(x < 1000); hash = esl_ci_hashfunc_default(header_name, &hlen); if (hp->name && (!hp->hash || hash == hp->hash) && !strcasecmp(header_name, hp->name) && (esl_strlen_zero(val) || !strcmp(hp->value, val))) { if (lp) { lp->next = hp->next; } else { event->headers = hp->next; } if (hp == event->last_header || !hp->next) { event->last_header = lp; } FREE(hp->name); FREE(hp->value); memset(hp, 0, sizeof(*hp)); FREE(hp); status = ESL_SUCCESS; } else { lp = hp; } } return status; }
static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t stack, const char *header_name, char *data) { esl_event_header_t *header; esl_ssize_t hlen = -1; header = ALLOC(sizeof(*header)); esl_assert(header); if ((event->flags & ESL_UNIQ_HEADERS)) { esl_event_del_header(event, header_name); } memset(header, 0, sizeof(*header)); header->name = DUP(header_name); header->value = data; header->hash = esl_ci_hashfunc_default(header->name, &hlen); if (stack == ESL_STACK_TOP) { header->next = event->headers; event->headers = header; if (!event->last_header) { event->last_header = header; } } else { if (event->last_header) { event->last_header->next = header; } else { event->headers = header; header->next = NULL; } event->last_header = header; } return ESL_SUCCESS; }
static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t stack, const char *header_name, char *data) { esl_event_header_t *header = NULL; esl_ssize_t hlen = -1; int exists = 0, fly = 0; char *index_ptr; int index = 0; char *real_header_name = NULL; if ((index_ptr = strchr(header_name, '['))) { index_ptr++; index = atoi(index_ptr); real_header_name = DUP(header_name); if ((index_ptr = strchr(real_header_name, '['))) { *index_ptr++ = '\0'; } header_name = real_header_name; } if (index_ptr || (stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { if (!(header = esl_event_get_header_ptr(event, header_name)) && index_ptr) { header = new_header(header_name); if (esl_test_flag(event, ESL_EF_UNIQ_HEADERS)) { esl_event_del_header(event, header_name); } fly++; } if ((header = esl_event_get_header_ptr(event, header_name))) { if (index_ptr) { if (index > -1 && index <= 4000) { if (index < header->idx) { FREE(header->array[index]); header->array[index] = DUP(data); } else { int i; char **m; m = realloc(header->array, sizeof(char *) * (index + 1)); esl_assert(m); header->array = m; for (i = header->idx; i < index; i++) { m[i] = DUP(""); } m[index] = DUP(data); header->idx = index + 1; if (!fly) { exists = 1; } goto redraw; } } goto end; } else { if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { exists++; stack &= ~(ESL_STACK_TOP | ESL_STACK_BOTTOM); } else { header = NULL; } } } } if (!header) { if (esl_strlen_zero(data)) { esl_event_del_header(event, header_name); FREE(data); goto end; } if (esl_test_flag(event, ESL_EF_UNIQ_HEADERS)) { esl_event_del_header(event, header_name); } if (strstr(data, "ARRAY::")) { esl_event_add_array(event, header_name, data); FREE(data); goto end; } header = new_header(header_name); } if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { char **m = NULL; esl_size_t len = 0; char *hv; int i = 0, j = 0; if (header->value && !header->idx) { m = malloc(sizeof(char *)); esl_assert(m); m[0] = header->value; header->value = NULL; header->array = m; header->idx++; m = NULL; } i = header->idx + 1; m = realloc(header->array, sizeof(char *) * i); esl_assert(m); if ((stack & ESL_STACK_PUSH)) { m[header->idx] = data; } else if ((stack & ESL_STACK_UNSHIFT)) { for (j = header->idx; j > 0; j--) { m[j] = m[j-1]; } m[0] = data; } header->idx++; header->array = m; redraw: len = 0; for(j = 0; j < header->idx; j++) { len += strlen(header->array[j]) + 2; } if (len) { len += 8; hv = realloc(header->value, len); esl_assert(hv); header->value = hv; esl_snprintf(header->value, len, "ARRAY::"); for(j = 0; j < header->idx; j++) { esl_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "|:", header->array[j]); } } } else { header->value = data; } if (!exists) { header->hash = esl_ci_hashfunc_default(header->name, &hlen); if ((stack & ESL_STACK_TOP)) { header->next = event->headers; event->headers = header; if (!event->last_header) { event->last_header = header; } } else { if (event->last_header) { event->last_header->next = header; } else { event->headers = header; header->next = NULL; } event->last_header = header; } } end: esl_safe_free(real_header_name); return ESL_SUCCESS; }
ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen) { esl_size_t freespace, actual_freespace; esl_assert(buffer != NULL); esl_assert(data != NULL); esl_assert(buffer->data != NULL); if (!datalen) { return buffer->used; } actual_freespace = buffer->datalen - buffer->actually_used; if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) { memmove(buffer->data, buffer->head, buffer->used); buffer->head = buffer->data; buffer->actually_used = buffer->used; } freespace = buffer->datalen - buffer->used; /* if (buffer->data != buffer->head) { memmove(buffer->data, buffer->head, buffer->used); buffer->head = buffer->data; } */ if (freespace < datalen) { esl_size_t new_size, new_block_size; void *data1; new_size = buffer->datalen + datalen; new_block_size = buffer->datalen + buffer->blocksize; if (new_block_size > new_size) { new_size = new_block_size; } buffer->head = buffer->data; data1 = realloc(buffer->data, new_size); if (!data1) { return 0; } buffer->data = data1; buffer->head = buffer->data; buffer->datalen = new_size; } freespace = buffer->datalen - buffer->used; if (freespace < datalen) { return 0; } else { memcpy(buffer->head + buffer->used, data, datalen); buffer->used += datalen; buffer->actually_used += datalen; } /* if (buffer->id == 4) printf("%u i %d = %d\n", buffer->id, (unsigned)datalen, (unsigned)buffer->used); */ return buffer->used; }
static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t stack, const char *header_name, char *data) { esl_event_header_t *header = NULL; esl_ssize_t hlen = -1; int exists = 0; if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT) || esl_test_flag(event, ESL_EF_CONTAINS_ARRAYS)) { if ((header = esl_event_get_header_ptr(event, header_name))) { if (!(stack & ESL_STACK_PUSH) && !(stack & ESL_STACK_UNSHIFT) && header->idx) { stack |= ESL_STACK_PUSH; } if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { exists++; stack &= ~(ESL_STACK_TOP | ESL_STACK_BOTTOM); } else { header = NULL; } } } if (!header) { #ifdef ESL_EVENT_RECYCLE void *pop; if (esl_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == ESL_SUCCESS) { header = (esl_event_header_t *) pop; } else { #endif header = ALLOC(sizeof(*header)); esl_assert(header); #ifdef ESL_EVENT_RECYCLE } #endif if (esl_test_flag(event, ESL_EF_UNIQ_HEADERS)) { esl_event_del_header(event, header_name); } memset(header, 0, sizeof(*header)); header->name = DUP(header_name); } if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { char **m = NULL; esl_size_t len = 0; char *hv; int i = 0, j = 0; esl_set_flag(event, ESL_EF_CONTAINS_ARRAYS); if (header->value && !header->idx) { m = malloc(sizeof(char *)); esl_assert(m); m[0] = header->value; header->value = NULL; header->array = m; header->idx++; m = NULL; } i = header->idx + 1; m = realloc(header->array, sizeof(char *) * i); esl_assert(m); if ((stack & ESL_STACK_PUSH)) { m[header->idx] = data; } else if ((stack & ESL_STACK_UNSHIFT)) { for (j = header->idx; j > 0; j--) { m[j] = m[j-1]; } m[0] = data; } header->idx++; header->array = m; for(j = 0; j < header->idx; j++) { len += strlen(header->array[j]) + 2; } if (len) { len += 8; hv = realloc(header->value, len); esl_assert(hv); header->value = hv; esl_snprintf(header->value, len, "ARRAY::"); for(j = 0; j < header->idx; j++) { esl_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "::", header->array[j]); } } } else { header->value = data; } if (!exists) { header->hash = esl_ci_hashfunc_default(header->name, &hlen); if ((stack & ESL_STACK_TOP)) { header->next = event->headers; event->headers = header; if (!event->last_header) { event->last_header = header; } } else { if (event->last_header) { event->last_header->next = header; } else { event->headers = header; header->next = NULL; } event->last_header = header; } } return ESL_SUCCESS; }
ESL_DECLARE(esl_size_t) esl_buffer_inuse(esl_buffer_t *buffer) { esl_assert(buffer != NULL); return buffer->used; }