ib_status_t ib_cfgparser_create(ib_cfgparser_t **pcp, ib_engine_t *ib) { IB_FTRACE_INIT(ib_cfgparser_create); ib_mpool_t *pool; ib_status_t rc; /* Create parser memory pool */ rc = ib_mpool_create(&pool, ib->mp); if (rc != IB_OK) { rc = IB_EALLOC; goto failed; } /* Create the main structure in the memory pool */ *pcp = (ib_cfgparser_t *)ib_mpool_calloc(pool, 1, sizeof(**pcp)); if (*pcp == NULL) { rc = IB_EALLOC; goto failed; } (*pcp)->ib = ib; (*pcp)->mp = pool; /* Create the stack */ rc = ib_list_create(&((*pcp)->stack), pool); if (rc != IB_OK) { goto failed; } (*pcp)->cur_ctx = ib_context_main(ib); ib_list_push((*pcp)->stack, (*pcp)->cur_ctx); /* Create the block tracking list */ rc = ib_list_create(&((*pcp)->block), pool); if (rc != IB_OK) { goto failed; } /* Other fields are NULLed via calloc */ ib_log_debug(ib, 9, "Stack: ctx=%p site=%p(%s) loc=%p(%s)", (*pcp)->cur_ctx, (*pcp)->cur_site, (*pcp)->cur_site?(*pcp)->cur_site->name:"NONE", (*pcp)->cur_loc, (*pcp)->cur_loc?(*pcp)->cur_loc->path:"/"); IB_FTRACE_RET_STATUS(rc); failed: /* Make sure everything is cleaned up on failure */ if (pool != NULL) { ib_mpool_destroy(pool); } *pcp = NULL; IB_FTRACE_RET_STATUS(rc); }
static ib_status_t dyn_get( const ib_field_t *f, void *out_value, const void *arg, size_t alen, void *data ) { ib_mpool_t *mp = (ib_mpool_t *)data; ib_num_t numval = 5; ib_field_t *newf; ib_status_t rc; ib_list_t *l; const char* carg = (const char *)arg; rc = ib_list_create(&l, mp); if (rc != IB_OK) { return rc; } rc = ib_field_create(&newf, mp, carg, alen, IB_FTYPE_NUM, ib_ftype_num_in(&numval)); if (rc != IB_OK) { return rc; } rc = ib_list_push(l, newf); *(void**)out_value = l; return IB_OK; }
void RunTest(size_t bufsize, ib_status_t expected_rc, ib_flags_t expected_result, const char *expected, bool quote, const char *join, size_t num, ...) { va_list va; const char *s; ib_status_t rc; ib_list_t *slist; size_t n; rc = ib_list_create(&slist, m_pool); if (rc != IB_OK) { throw std::runtime_error("Error creating string list"); } va_start(va, num); for (n = 0; n < num; ++n) { s = va_arg(va, char *); rc = ib_list_push(slist, (void *)s); if (rc != IB_OK) { throw std::runtime_error("Error creating string list"); } } va_end(va); RunTest(slist, quote, join, bufsize, expected_rc, expected_result, expected); }
/// @test Test util list library - IB_LIST_LOOP() TEST_F(TestIBUtilList, test_list_loop) { ib_list_t *list; ib_list_node_t *node; ib_status_t rc; int init[] = { 0, 1, 2, 3, 4 }; int *val; int i; rc = ib_list_create(&list, MemPool()); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(list); ASSERT_EQ(0UL, ib_list_elements(list)); for (i = 0; i < 5; i++) { rc = ib_list_push(list, &init[i]); ASSERT_EQ(IB_OK, rc); } ASSERT_EQ(5UL, ib_list_elements(list)); i = 0; IB_LIST_LOOP(list, node) { val = (int *)ib_list_node_data(node); ASSERT_EQ(init[i], *val); i++; }
/// @test Test util list library - ib_htree_list() and ib_list_destroy() TEST_F(TestIBUtilList, test_list_create_and_destroy) { ib_list_t *list; ib_status_t rc; rc = ib_list_create(&list, MemPool()); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(list); ASSERT_EQ(0UL, ib_list_elements(list)); }
/****************************************************************//** Create a new work queue. @return work queue */ UNIV_INTERN ib_wqueue_t* ib_wqueue_create(void) /*===================*/ { ib_wqueue_t* wq = mem_alloc(sizeof(ib_wqueue_t)); mutex_create(&wq->mutex, SYNC_WORK_QUEUE); wq->items = ib_list_create(); wq->event = os_event_create(NULL); return(wq); }
static ib_status_t cpy_psntsfw_cfg( ib_engine_t *ib, ib_mpool_t *mp, ib_mpool_t *local_mp, const ib_persist_fw_cfg_t *persist_fw_src, ib_persist_fw_cfg_t **persist_fw_dst ) { assert(ib != NULL); assert(mp != NULL); assert(local_mp != NULL); assert(persist_fw_src != NULL); assert(persist_fw_dst != NULL); ib_list_t *list = NULL; ib_list_node_t *list_node; ib_status_t rc; ib_persist_fw_cfg_t *persist_fw_out; rc = ib_persist_fw_cfg_create(mp, &persist_fw_out); if (rc != IB_OK) { ib_log_error(ib, "Failed to create new persist_fw_cfg."); return rc; } rc = ib_list_create(&list, local_mp); if (rc != IB_OK) { return rc; } /* Copy the src store hash to the dst store hash. */ if (ib_hash_size(persist_fw_src->stores) > 0) { rc = ib_hash_get_all(persist_fw_src->stores, list); if (rc != IB_OK) { ib_log_error(ib, "Failed to get entries from hash."); return rc; } IB_LIST_LOOP(list, list_node) { ib_persist_fw_store_t *store = (ib_persist_fw_store_t *)ib_list_node_data_const(list_node); rc = ib_hash_set(persist_fw_out->stores, store->name, store); if (rc != IB_OK) { ib_log_error(ib, "Failed to set store %s", store->name); return rc; } }
ib_status_t ib_site_hostname_add(ib_site_t *site, const char *host) { IB_FTRACE_INIT(ib_site_hostname_add); ib_status_t rc; /* Create a list if this is the first item. */ if (site->hosts == NULL) { rc = ib_list_create(&site->hosts, site->mp); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } /// @todo: use regex rc = ib_list_push(site->hosts, (void *)host); IB_FTRACE_RET_STATUS(rc); }
ib_status_t DLL_PUBLIC ib_logevent_field_add(ib_logevent_t *le, const char *name) { IB_FTRACE_INIT(); char *name_copy; ib_status_t rc; assert(le != NULL); if (le->fields == NULL) { rc = ib_list_create(&le->fields, le->mp); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } name_copy = ib_mpool_memdup(le->mp, name, strlen(name) + 1); rc = ib_list_push(le->fields, name_copy); IB_FTRACE_RET_STATUS(rc); }
ib_status_t DLL_PUBLIC ib_logevent_tag_add(ib_logevent_t *le, const char *tag) { IB_FTRACE_INIT(); char *tag_copy; ib_status_t rc; assert(le != NULL); if (le->tags == NULL) { rc = ib_list_create(&le->tags, le->mp); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } tag_copy = ib_mpool_memdup(le->mp, tag, strlen(tag) + 1); rc = ib_list_push(le->tags, tag_copy); IB_FTRACE_RET_STATUS(rc); }
ib_status_t ib_site_loc_create(ib_site_t *site, ib_loc_t **ploc, const char *path) { IB_FTRACE_INIT(ib_site_loc_create); ib_loc_t *loc; ib_status_t rc; if (ploc != NULL) { *ploc = NULL; } /* Create a list if this is the first item. */ if (site->locations == NULL) { rc = ib_list_create(&site->locations, site->mp); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } /* Create the location structure in the site memory pool */ loc = (ib_loc_t *)ib_mpool_calloc(site->mp, 1, sizeof(*loc)); if (loc == NULL) { rc = IB_EALLOC; IB_FTRACE_RET_STATUS(rc); } loc->site = site; loc->path = path; loc->path = (const char *)ib_mpool_memdup(site->mp, path, strlen(path)+1); if (ploc != NULL) { *ploc = loc; } rc = ib_list_push(site->locations, (void *)loc); IB_FTRACE_RET_STATUS(rc); }
/********************************* * Helper Functions *********************************/ static ib_status_t sqli_create_pattern_set_from_file( sqli_pattern_set_t **out_ps, const char *path, ib_mpool_t *mp ) { assert(out_ps != NULL); assert(path != NULL); assert(mp != NULL); ib_status_t rc; FILE *fp = NULL; char *buffer = NULL; size_t buffer_size = 0; ib_list_t *items = NULL; ib_list_node_t *n = NULL; ib_mpool_t *tmp = NULL; sqli_pattern_set_t *ps = NULL; size_t i = 0; /* Temporary memory pool for this function only. */ rc = ib_mpool_create(&tmp, "sqli tmp", NULL); assert(rc == IB_OK); assert(tmp != NULL); fp = fopen(path, "r"); if (fp == NULL) { goto fail; } rc = ib_list_create(&items, tmp); assert(rc == IB_OK); assert(items != NULL); for (;;) { char *buffer_copy; int read = getline(&buffer, &buffer_size, fp); if (read == -1) { if (! feof(fp)) { fclose(fp); goto fail; } else { break; } } buffer_copy = ib_mpool_memdup(mp, buffer, read); assert(buffer_copy != NULL); while (buffer_copy[read-1] == '\n' || buffer_copy[read-1] == '\r') { buffer_copy[read-1] = '\0'; --read; } rc = ib_list_push(items, (void *)buffer_copy); assert(rc == IB_OK); } fclose(fp); ps = ib_mpool_alloc(mp, sizeof(*ps)); assert(ps != NULL); ps->num_patterns = ib_list_elements(items); ps->patterns = ib_mpool_alloc(mp, ps->num_patterns * sizeof(*ps->patterns)); assert(ps->patterns != NULL); i = 0; IB_LIST_LOOP(items, n) { ps->patterns[i] = ib_list_node_data(n); ++i; }
/********************************* * Helper Functions *********************************/ static ib_status_t sqli_create_fingerprint_set_from_file( sqli_fingerprint_set_t **out_ps, const char *path, ib_mm_t mm ) { assert(out_ps != NULL); assert(path != NULL); ib_status_t rc; FILE *fp = NULL; char *buffer = NULL; size_t buffer_size = 0; ib_list_t *items = NULL; ib_list_node_t *n = NULL; ib_mpool_lite_t *tmp = NULL; ib_mm_t tmp_mm; sqli_fingerprint_set_t *ps = NULL; size_t i = 0; /* Temporary memory pool for this function only. */ rc = ib_mpool_lite_create(&tmp); assert(rc == IB_OK); assert(tmp != NULL); tmp_mm = ib_mm_mpool_lite(tmp); fp = fopen(path, "r"); if (fp == NULL) { goto fail; } rc = ib_list_create(&items, tmp_mm); assert(rc == IB_OK); assert(items != NULL); for (;;) { char *buffer_copy; int read = getline(&buffer, &buffer_size, fp); char *space = NULL; ib_num_t confidence = 0; sqli_fingerprint_entry_t *entry = ib_mm_alloc(tmp_mm, sizeof(*entry)); if (read == -1) { if (! feof(fp)) { fclose(fp); goto fail; } else { break; } } while (buffer[read-1] == '\n' || buffer[read-1] == '\r') { buffer[read-1] = '\0'; --read; } space = strstr(buffer, " "); if (space != NULL) { rc = ib_type_atoi(space + 1, 10, &confidence); if (rc != IB_OK || confidence > 100) { return IB_EINVAL; } *space = '\0'; } buffer_copy = ib_mm_strdup(mm, buffer); assert(buffer_copy != NULL); entry->confidence = confidence; entry->fingerprint = buffer_copy; rc = ib_list_push(items, (void *)entry); assert(rc == IB_OK); } fclose(fp); ps = ib_mm_alloc(mm, sizeof(*ps)); assert(ps != NULL); ps->num_fingerprints = ib_list_elements(items); ps->fingerprints = ib_mm_alloc(mm, ps->num_fingerprints * sizeof(*ps->fingerprints)); assert(ps->fingerprints != NULL); i = 0; IB_LIST_LOOP(items, n) { const sqli_fingerprint_entry_t *entry = (const sqli_fingerprint_entry_t *)ib_list_node_data(n); ps->fingerprints[i] = *entry; ++i; } assert(i == ps->num_fingerprints); ib_mpool_lite_destroy(tmp); qsort( ps->fingerprints, ps->num_fingerprints, sizeof(*ps->fingerprints), &sqli_cmp ); *out_ps = ps; return IB_OK; fail: ib_mpool_lite_destroy(tmp); return IB_EINVAL; }
/** * Create new list. * * Creates a new empty list using @a memory_manager for memory. * * @param[in] memory_manager Memory manager to use. * @return Empty List. **/ static List create(MemoryManager memory_manager) { ib_list_t* ib_list; throw_if_error(ib_list_create(&ib_list, memory_manager.ib())); return List(ib_list); }
ib_status_t ib_tfn_execute( ib_mpool_t *mp, const ib_tfn_t *tfn, const ib_field_t *fin, const ib_field_t **fout ) { assert(mp != NULL); assert(tfn != NULL); assert(fin != NULL); assert(fout != NULL); ib_status_t rc; const ib_field_t *out = NULL; if (fin->type == IB_FTYPE_LIST && ! ib_tfn_handle_list(tfn)) { /* Unroll list */ const ib_list_t *value_list; const ib_list_node_t *node; ib_list_t *out_list; ib_field_t *fnew; rc = ib_field_value(fin, ib_ftype_list_out(&value_list)); if (rc != IB_OK) { return rc; } rc = ib_list_create(&out_list, mp); if (rc != IB_OK) { return rc; } IB_LIST_LOOP_CONST(value_list, node) { const ib_field_t *in; const ib_field_t *tfn_out; in = (const ib_field_t *)ib_list_node_data_const(node); assert(in != NULL); rc = ib_tfn_execute(mp, tfn, in, &tfn_out); if (rc != IB_OK) { return rc; } if (tfn_out == NULL) { return IB_EINVAL; } rc = ib_list_push(out_list, (void *)tfn_out); if (rc != IB_OK) { return rc; } } /* Finally, create the output field (list) and return it */ rc = ib_field_create(&fnew, mp, fin->name, fin->nlen, IB_FTYPE_LIST, ib_ftype_list_in(out_list)); if (rc != IB_OK) { return rc; } out = fnew; } else {
/** * Constructs fail links of branches (the failure transition function) * * @param ac_tree the ac tree matcher * * @return ib_status_t status of the operation */ static ib_status_t ib_ac_link_fail_states(ib_ac_t *ac_tree) { ib_status_t rc; ib_ac_state_t *child = NULL; ib_ac_state_t *state = NULL; ib_ac_state_t *goto_state = NULL; ib_list_t *iter_queue = NULL; if (ac_tree->flags & IB_AC_FLAG_PARSER_COMPILED) { return IB_OK; } ac_tree->root->pattern = 0; rc = ib_list_create(&iter_queue, ac_tree->mp); if (rc != IB_OK) { return rc; } ac_tree->root->fail = ac_tree->root; /* All first-level children will fail back to root state */ for (child = ac_tree->root->child; child != NULL; child = child->sibling) { child->fail = ac_tree->root; rc = ib_list_enqueue(iter_queue, (void *) child); if (rc != IB_OK) { return rc; } } while (ib_list_elements(iter_queue) > 0) { rc = ib_list_dequeue(iter_queue, (void *) &state); if (rc != IB_OK) { return rc; } state->fail = ac_tree->root; if (state->parent != ac_tree->root) { goto_state = ib_ac_child_for_code(state->parent->fail, state->letter); if (goto_state != NULL) { state->fail = goto_state; } } for (child = state->child; child != NULL; child = child->sibling) { rc = ib_list_enqueue(iter_queue, (void *) child); if (rc != IB_OK) { return rc; } } } /* Link common outputs of subpatterns present in the branch*/ ib_ac_link_outputs(ac_tree, ac_tree->root); /* Unlink invalid fail transitions. This guarantees that there will * be at least one letter with transition in each fail state*/ ib_ac_unlink_unuseful(ac_tree, ac_tree->root); if (ac_tree->root->child != NULL) { ib_ac_build_bintree(ac_tree, ac_tree->root); } ac_tree->flags |= IB_AC_FLAG_PARSER_COMPILED; return IB_OK; }
/* * Recursive function that return a list of all the datas found under this cidr * * @param node the node to check * @param prefix the prefix we are searching * @param offset, the number of bits already compared +1 (cur possition) * @param rlist reference to a pointer where the list will be allocated * @param mp pool where we should allocate the list * * @returns Status code */ static ib_status_t ib_radix_match_all(ib_radix_node_t *node, ib_radix_prefix_t *prefix, int offset, ib_list_t **rlist, ib_mpool_t *mp) { IB_FTRACE_INIT(ib_radix_match_all); ib_status_t ret = IB_OK; uint8_t inserted = 0; if (node == NULL) { IB_FTRACE_RET_STATUS(IB_ENOENT); } if (offset >= prefix->prefixlen && node->data != NULL) { if (*rlist == NULL) { ret = ib_list_create(rlist, mp); if (ret != IB_OK) { IB_FTRACE_RET_STATUS(ret); } } ret = ib_list_push(*rlist, node->data); if (ret != IB_OK) { IB_FTRACE_RET_STATUS(ret); } inserted = 1; } else { int i = 0; for (; i < node->prefix->prefixlen && offset < prefix->prefixlen; i++, offset++) { if (IB_READ_BIT(node->prefix->rawbits[i / 8], i % 8) != IB_READ_BIT(prefix->rawbits[offset / 8], offset % 8)) { IB_FTRACE_RET_STATUS(IB_ENOENT); } if (offset >= prefix->prefixlen && node->data != NULL) { if (*rlist == NULL) { ret = ib_list_create(rlist, mp); if (ret != IB_OK) { IB_FTRACE_RET_STATUS(ret); } } ret = ib_list_push(*rlist, node->data); if (ret != IB_OK) { IB_FTRACE_RET_STATUS(ret); } inserted = 1; break; } } } if (inserted == 0 && offset >= prefix->prefixlen && node->data != NULL) { if (*rlist == NULL) { ret = ib_list_create(rlist, mp); if (ret != IB_OK) { IB_FTRACE_RET_STATUS(ret); } } ret = ib_list_push(*rlist, node->data); if (ret != IB_OK) { IB_FTRACE_RET_STATUS(ret); } } if (offset >= prefix->prefixlen) { ret = ib_radix_match_all(node->zero, prefix, offset, rlist, mp); if (ret != IB_OK && ret != IB_ENOENT) { IB_FTRACE_RET_STATUS(ret); } ret = ib_radix_match_all(node->one, prefix, offset, rlist, mp); if (ret != IB_OK && ret != IB_ENOENT) { IB_FTRACE_RET_STATUS(ret); } } else { if (IB_READ_BIT(prefix->rawbits[offset / 8], offset % 8) == 0) { ret = ib_radix_match_all(node->zero, prefix, offset, rlist, mp); } else { ret = ib_radix_match_all(node->one, prefix, offset, rlist, mp); } } IB_FTRACE_RET_STATUS(ret); }
/* * Function that return a list of all the datas with a prefix that start like * the provided prefix arg * * Example: insert data in 192.168.1.27, as well as 192.168.1.28, * as well as 192.168.10.0/24 and 10.0.0.0/8 and then search 192.168.0.0/16 * it should return a list containing all the datas except the associated to * 10.0.0.0/8 * * @param node the node to check * @param prefix the prefix we are searching * @param offset, the number of bits already compared +1 (cur possition) * @param rlist reference to the pointer that will be linked to the list, if any * @param mp pool where we should allocate the list * * @returns Status code */ ib_status_t ib_radix_match_all_data(ib_radix_t *radix, ib_radix_prefix_t *prefix, ib_list_t **rlist, ib_mpool_t *mp) { IB_FTRACE_INIT(ib_radix_match_all_data); ib_status_t ret; if (rlist == NULL) { IB_FTRACE_RET_STATUS(IB_EINVAL); } if (radix->start == NULL) { IB_FTRACE_RET_STATUS(IB_ENOENT); } if (radix->start->data != NULL && prefix->prefixlen == 0) { if (*rlist == NULL) { ret = ib_list_create(rlist, mp); if (ret != IB_OK) { IB_FTRACE_RET_STATUS(ret); } } ret = ib_list_push(*rlist, radix->start->data); if (ret != IB_OK) { IB_FTRACE_RET_STATUS(ret); } } if (prefix->prefixlen == 0) { // Append data of both branches ret = ib_radix_match_all(radix->start->zero, prefix, 0, rlist, mp); if (ret != IB_OK && ret != IB_ENOENT) { IB_FTRACE_RET_STATUS(ret); } ret = ib_radix_match_all(radix->start->one, prefix, 0, rlist, mp); if (ret != IB_OK && ret != IB_ENOENT) { IB_FTRACE_RET_STATUS(ret); } } else { // Follow it's path until we reach the correct offset if (IB_GET_DIR(prefix->rawbits[0]) == 0) { ret = ib_radix_match_all(radix->start->zero, prefix, 0, rlist, mp); } else { ret = ib_radix_match_all(radix->start->one, prefix, 0, rlist, mp); } } if (ret == IB_ENOENT && *rlist != NULL && ib_list_elements(*rlist) > 0) { IB_FTRACE_RET_STATUS(IB_OK); } IB_FTRACE_RET_STATUS(ret); }
ib_status_t ib_field_setv_ex( ib_field_t *f, void *in_pval, const void *arg, size_t alen ) { ib_status_t rc; if (ib_field_is_dynamic(f)) { if (f->val->fn_set == NULL) { return IB_EINVAL; } return f->val->fn_set(f, arg, alen, in_pval, f->val->cbdata_set); } /* No dynamic setter */ if (arg != NULL) { return IB_EINVAL; } /* What and how it is stored depends on the field type. */ switch (f->type) { case IB_FTYPE_BYTESTR: { const ib_bytestr_t *bs = (const ib_bytestr_t *)in_pval; if (bs != NULL) { rc = ib_bytestr_dup((ib_bytestr_t **)f->val->pval, f->mp, bs); if (rc != IB_OK) { goto failed; } } break; } case IB_FTYPE_LIST: { /// @todo Fix const once lists are const aware/copying. ib_list_t *l = (ib_list_t *)in_pval; if (l != NULL) { /// @todo Should do shallow copy *(ib_list_t **)f->val->pval = l; } else { rc = ib_list_create((ib_list_t **)f->val->pval, f->mp); if (rc != IB_OK) { goto failed; } } break; } case IB_FTYPE_SBUFFER: { /// @todo Fix once stream is const aware/copying ib_stream_t *s = (ib_stream_t *)in_pval; if (s != NULL) { /// @todo Should do shallow copy *(ib_stream_t **)f->val->pval = s; } else { rc = ib_stream_create((ib_stream_t **)f->val->pval, f->mp); if (rc != IB_OK) { goto failed; } } break; } case IB_FTYPE_NULSTR: { const char *s = (const char *)in_pval; if (s != NULL) { *(char **)(f->val->pval) = ib_mpool_strdup(f->mp, s); if (*(void **)(f->val->pval) == NULL) { rc = IB_EALLOC; goto failed; } } break; } case IB_FTYPE_NUM: { ib_num_t n = (in_pval != NULL) ? *(ib_num_t *)in_pval : 0; *(ib_num_t *)(f->val->pval) = n; break; } case IB_FTYPE_FLOAT: { ib_float_t fl = (in_pval != NULL) ? *(ib_float_t *)in_pval : 0; *(ib_float_t *)(f->val->pval) = fl; break; } case IB_FTYPE_GENERIC: default: { void *p = in_pval; *(void **)(f->val->pval) = p; break; } } ib_field_util_log_debug("FIELD_SETV", f); return IB_OK; failed: return rc; }
/// @test Test util list library - ib_list_push() and ib_list_pop() TEST_F(TestIBUtilList, test_list_push_and_pop) { ib_list_t *list; ib_status_t rc; int v0 = 0; int v1 = 1; int v2 = 2; int v3 = 3; int v4 = 4; int *val; rc = ib_list_create(&list, MemPool()); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(list); ASSERT_EQ(0UL, ib_list_elements(list)); /* Pop invalid. */ rc = ib_list_pop(list,(void *)&val); ASSERT_EQ(IB_ENOENT, rc); ASSERT_FALSE(val); ASSERT_EQ(0UL, ib_list_elements(list)); /* Simple pushes followed by pops. */ rc = ib_list_push(list, &v0); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(1UL, ib_list_elements(list)); rc = ib_list_push(list, &v1); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(2UL, ib_list_elements(list)); rc = ib_list_push(list, &v2); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(3UL, ib_list_elements(list)); rc = ib_list_push(list, &v3); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(4UL, ib_list_elements(list)); rc = ib_list_push(list, &v4); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(5UL, ib_list_elements(list)); ASSERT_EQ(v0, *(int *)(ib_list_node_data(ib_list_first(list)))); ASSERT_EQ(v4, *(int *)(ib_list_node_data(ib_list_last(list)))); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v4, *val); ASSERT_EQ(4UL, ib_list_elements(list)); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v3, *val); ASSERT_EQ(3UL, ib_list_elements(list)); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v2, *val); ASSERT_EQ(2UL, ib_list_elements(list)); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v1, *val); ASSERT_EQ(1UL, ib_list_elements(list)); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v0, *val); ASSERT_EQ(0UL, ib_list_elements(list)); }
/** * Search patterns of the ac_tree matcher in the given buffer using a * matching context. The matching context stores offsets used to process * a search over multiple data segments. The function has option flags to * specify to return where the first pattern is found, or after all the * data is consumed, using a user specified callback and/or building a * list of patterns matched * * @param ac_ctx pointer to the matching context * @param data pointer to the buffer to search in * @param len the length of the data * @param flags options to use while matching * @param mp memory pool to use * * @returns Status code */ ib_status_t ib_ac_consume(ib_ac_context_t *ac_ctx, const char *data, size_t len, uint8_t flags, ib_mpool_t *mp) { const char *end; ib_ac_state_t *state = NULL; ib_ac_state_t *fgoto = NULL; int flag_match = 0; ib_ac_t *ac_tree = ac_ctx->ac_tree; ac_ctx->current_offset = 0; if ((ac_ctx->ac_tree->flags & IB_AC_FLAG_PARSER_COMPILED) == 0) { ib_ac_build_links(ac_tree); } ac_tree = ac_ctx->ac_tree; if (ac_ctx->current == NULL) { ac_ctx->current = ac_tree->root; } state = ac_ctx->current; end = data + len; while (data < end) { ib_ac_char_t letter = (unsigned char)*data++; ++ac_ctx->processed; ++ac_ctx->current_offset; if (ac_tree->flags & IB_AC_FLAG_PARSER_NOCASE) { letter = tolower(letter); } fgoto = NULL; while (fgoto == NULL) { fgoto = ib_ac_bintree_goto(state, letter); if (fgoto != NULL) { if (fgoto->flags & IB_AC_FLAG_STATE_OUTPUT) { flag_match = 1; ++fgoto->match_cnt; ++ac_ctx->match_cnt; ac_ctx->current = fgoto; state = fgoto; if (flags & IB_AC_FLAG_CONSUME_DOCALLBACK) { ib_ac_do_callback(ac_ctx, state); } if (flags & IB_AC_FLAG_CONSUME_DOLIST) { /* If list is not created yet, create it */ if (ac_ctx->match_list == NULL) { ib_status_t rc; rc = ib_list_create(&ac_ctx->match_list, mp); if (rc != IB_OK) { return rc; } } ib_ac_match_t *mt = NULL; mt = (ib_ac_match_t *)ib_mpool_calloc(mp, 1, sizeof(ib_ac_match_t)); if (mt == NULL) { return IB_EALLOC; } mt->pattern = state->pattern; mt->data = state->data; mt->pattern_len = state->level + 1; mt->offset = ac_ctx->processed - (fgoto->level + 1); mt->relative_offset = ac_ctx->current_offset - (fgoto->level + 1); ib_list_enqueue(ac_ctx->match_list, (void *) mt); } if ( !(flags & IB_AC_FLAG_CONSUME_MATCHALL)) { return IB_OK; } ib_ac_state_t *outs = NULL; for (outs = state->outputs; outs != NULL; outs = outs->outputs) { /* This are subpatterns of the current walked branch * that are present as independent patterns as well * in the tree */ ++outs->match_cnt; ++ac_ctx->match_cnt; if (flags & IB_AC_FLAG_CONSUME_DOCALLBACK) { ib_ac_do_callback(ac_ctx, outs); } if (flags & IB_AC_FLAG_CONSUME_DOLIST) { /* If list is not created yet, create it */ if (ac_ctx->match_list == NULL) { ib_status_t rc; rc = ib_list_create(&ac_ctx->match_list, mp); if (rc != IB_OK) { return rc; } } ib_ac_match_t *mt = NULL; mt = (ib_ac_match_t *)ib_mpool_calloc(mp, 1, sizeof(ib_ac_match_t)); if (mt == NULL) { return IB_EALLOC; } mt->pattern = outs->pattern; mt->data = state->data; mt->pattern_len = outs->level + 1; mt->offset = ac_ctx->processed - (outs->level + 1); mt->relative_offset = ac_ctx->current_offset - (outs->level + 1); ib_list_enqueue(ac_ctx->match_list, (void *) mt); } } } } else { /* if goto() failed, look at the fail states */ if (state != NULL && state->fail != NULL) { if (state == ac_tree->root) { break; } state = state->fail; } else { state = ac_tree->root; } } } if (fgoto != NULL) { state = fgoto; } ac_ctx->current = state; } ac_ctx->current = state; /* If we have a match, return ok. Otherwise return IB_ENOENT */ if (flag_match == 1) { return IB_OK; } return IB_ENOENT; }
/** * @internal * Handle a PocSig directive. * * @param cp Config parser * @param name Directive name * @param args List of directive arguments * @param cbdata Callback data (from directive registration) * * @returns Status code */ static ib_status_t pocsig_dir_signature(ib_cfgparser_t *cp, const char *name, ib_list_t *args, void *cbdata) { IB_FTRACE_INIT(pocsig_dir_signature); ib_engine_t *ib = cp->ib; ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib); ib_list_t *list; const char *target; const char *op; const char *action; pocsig_cfg_t *cfg; pocsig_phase_t phase; pocsig_sig_t *sig; const char *errptr; int erroff; ib_status_t rc; /* Get the pocsig configuration for this context. */ rc = ib_context_module_config(ctx, IB_MODULE_STRUCT_PTR, (void *)&cfg); if (rc != IB_OK) { ib_log_error(ib, 1, "Failed to fetch %s config: %d", MODULE_NAME_STR, rc); } /* Setup the PCRE matcher. */ if (cfg->pcre == NULL) { rc = ib_matcher_create(ib, ib_engine_pool_config_get(ib), "pcre", &cfg->pcre); if (rc != IB_OK) { ib_log_error(ib, 2, "Could not create a PCRE matcher: %d", rc); IB_FTRACE_RET_STATUS(rc); } } /* Determine phase and initialize the phase list if required. */ if (strcasecmp("PocSigPreTx", name) == 0) { phase = POCSIG_PRE; if (cfg->phase[phase] == NULL) { rc = ib_list_create(cfg->phase + POCSIG_PRE, ib_engine_pool_config_get(ib)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } } else if (strcasecmp("PocSigReqHead", name) == 0) { phase = POCSIG_REQHEAD; if (cfg->phase[phase] == NULL) { ib_log_debug(ib, 4, "Creating list for phase=%d", phase); rc = ib_list_create(&list, ib_engine_pool_config_get(ib)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } ib_log_debug(ib, 4, "List for phase=%d list=%p", phase, list); cfg->phase[phase] = list; } } else if (strcasecmp("PocSigReq", name) == 0) { phase = POCSIG_REQ; if (cfg->phase[phase] == NULL) { rc = ib_list_create(&cfg->phase[phase], ib_engine_pool_config_get(ib)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } } else if (strcasecmp("PocSigResHead", name) == 0) { phase = POCSIG_RESHEAD; if (cfg->phase[phase] == NULL) { rc = ib_list_create(&cfg->phase[phase], ib_engine_pool_config_get(ib)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } } else if (strcasecmp("PocSigRes", name) == 0) { phase = POCSIG_RES; if (cfg->phase[POCSIG_RES] == NULL) { rc = ib_list_create(&cfg->phase[POCSIG_RES], ib_engine_pool_config_get(ib)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } } else if (strcasecmp("PocSigPostTx", name) == 0) { phase = POCSIG_POST; if (cfg->phase[phase] == NULL) { rc = ib_list_create(&cfg->phase[phase], ib_engine_pool_config_get(ib)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } } else { ib_log_error(ib, 2, "Invalid signature: %s", name); IB_FTRACE_RET_STATUS(IB_EINVAL); } /* Target */ rc = ib_list_shift(args, &target); if (rc != IB_OK) { ib_log_error(ib, 1, "No PocSig target"); IB_FTRACE_RET_STATUS(IB_EINVAL); } /* Operator */ rc = ib_list_shift(args, &op); if (rc != IB_OK) { ib_log_error(ib, 1, "No PocSig operator"); IB_FTRACE_RET_STATUS(IB_EINVAL); } /* Action */ rc = ib_list_shift(args, &action); if (rc != IB_OK) { ib_log_debug(ib, 4, "No PocSig action"); action = ""; } /* Signature */ sig = (pocsig_sig_t *)ib_mpool_alloc(ib_engine_pool_config_get(ib), sizeof(*sig)); if (sig == NULL) { IB_FTRACE_RET_STATUS(IB_EALLOC); } sig->target = ib_mpool_strdup(ib_engine_pool_config_get(ib), target); sig->patt = ib_mpool_strdup(ib_engine_pool_config_get(ib), op); sig->emsg = ib_mpool_strdup(ib_engine_pool_config_get(ib), action); /* Compile the PCRE patt. */ if (cfg->pcre == NULL) { ib_log_error(ib, 2, "No PCRE matcher available (load the pcre module?)"); IB_FTRACE_RET_STATUS(IB_EINVAL); } sig->cpatt = ib_matcher_compile(cfg->pcre, sig->patt, &errptr, &erroff); if (sig->cpatt == NULL) { ib_log_error(ib, 2, "Error at offset=%d of PCRE patt=\"%s\": %s", erroff, sig->patt, errptr); IB_FTRACE_RET_STATUS(IB_EINVAL); } ib_log_debug(ib, 4, "POCSIG: \"%s\" \"%s\" \"%s\" phase=%d ctx=%p", target, op, action, phase, ctx); /* Add the signature to the phase list. */ rc = ib_list_push(cfg->phase[phase], sig); if (rc != IB_OK) { ib_log_error(ib, 1, "Failed to add signature"); IB_FTRACE_RET_STATUS(rc); } IB_FTRACE_RET_STATUS(IB_OK); }
/** * Create new list. * * Creates a new empty list using @a memory_pool for memory. * * @param[in] memory_pool Memory pool to use. * @return Empty List. **/ static List create(MemoryPool memory_pool) { ib_list_t* ib_list; Internal::throw_if_error(ib_list_create(&ib_list, memory_pool.ib())); return List(ib_list); }
/** * Handle managed collection registration for vars "name=value" parameters * * @param[in] ib Engine * @param[in] module Collection manager's module object (unused) * @param[in] manager The collection manager object to register with (unused) * @param[in] mp Memory pool to use for allocations * @param[in] collection_name Name of the collection * @param[in] uri Full collection URI (unused) * @param[in] uri_scheme URI scheme (unused) * @param[in] uri_data Hierarchical/data part of the URI * @param[in] params List of parameter strings * @param[in] register_data Register callback data (unused) * @param[out] pmanager_inst_data Pointer to manager specific collection data * * @returns Status code: * - IB_OK All OK * - IB_Exxx Other error */ static ib_status_t core_managed_collection_vars_register_fn( const ib_engine_t *ib, const ib_module_t *module, const ib_collection_manager_t *manager, ib_mpool_t *mp, const char *collection_name, const char *uri, const char *uri_scheme, const char *uri_data, const ib_list_t *params, void *register_data, void **pmanager_inst_data) { assert(ib != NULL); assert(module != NULL); assert(mp != NULL); assert(collection_name != NULL); assert(params != NULL); assert(pmanager_inst_data != NULL); const ib_list_node_t *node; ib_list_t *vars_list; ib_list_t *field_list; ib_mpool_t *tmp = ib_engine_pool_temp_get(ib); ib_status_t rc; if (strlen(uri_data) != 0) { return IB_DECLINED; } if (ib_list_elements(params) < 1) { return IB_EINVAL; } /* Create a temporary list */ rc = ib_list_create(&vars_list, tmp); if (rc != IB_OK) { return rc; } /* First pass; walk through all params, look for "a=b" type syntax */ IB_LIST_LOOP_CONST(params, node) { static const int ovecsize = 9; int ovector[ovecsize]; const char *param = (const char *)node->data; core_vars_t *vars; int pcre_rc; pcre_rc = pcre_exec(core_vars_manager.pattern, NULL, param, strlen(param), 0, 0, ovector, ovecsize); if (pcre_rc < 0) { return IB_DECLINED; } vars = ib_mpool_alloc(tmp, sizeof(*vars)); if (vars == NULL) { return IB_EALLOC; } vars->name = ib_mpool_memdup_to_str(tmp, param + ovector[2], ovector[3] - ovector[2]); vars->value = ib_mpool_memdup_to_str(tmp, param + ovector[4], ovector[5] - ovector[4]); if ( (vars->name == NULL) || (vars->value == NULL) ) { return IB_EALLOC; } rc = ib_list_push(vars_list, vars); if (rc != IB_OK) { return rc; } } /* Build the list of fields */ rc = ib_list_create(&field_list, mp); if (rc != IB_OK) { return rc; } /* Now walk though the list, creating a field for each one */ IB_LIST_LOOP_CONST(vars_list, node) { const core_vars_t *vars = (const core_vars_t *)node->data; ib_field_t *field; ib_field_val_union_t fval; rc = ib_field_from_string(mp, IB_FIELD_NAME(vars->name), vars->value, &field, &fval); if (rc != IB_OK) { ib_log_error(ib, "Error creating field (\"%s\", \"%s\"): %s", vars->name, vars->value, ib_status_to_string(rc)); return rc; } rc = ib_list_push(field_list, field); if (rc != IB_OK) { return rc; } if (field->type == IB_FTYPE_NUM) { ib_log_trace(ib, "Created numeric field \"%s\" %"PRId64" in \"%s\"", vars->name, fval.num, collection_name); } else if (field->type == IB_FTYPE_FLOAT) { ib_log_trace(ib, "Created float field \"%s\" %f in \"%s\"", vars->name, (double)fval.fnum, collection_name); } else { ib_log_trace(ib, "Created string field \"%s\" \"%s\" in \"%s\"", vars->name, fval.nulstr, collection_name); } } /* Finally, store the list as the manager specific collection data */ *pmanager_inst_data = field_list; return IB_OK; }