Beispiel #1
0
 //! Pop first element off list.
 void pop_front() const
 {
     Internal::throw_if_error(ib_list_shift(m_ib, NULL));
 }
Beispiel #2
0
/// @test Test util list library - ib_list_unshift() and ib_list_shift()
TEST_F(TestIBUtilList, test_list_unshift_and_shift)
{
    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));

    /* shift invalid. */
    rc = ib_list_shift(list,(void *)&val);
    ASSERT_EQ(IB_ENOENT, rc);
    ASSERT_FALSE(val);
    ASSERT_EQ(0UL, ib_list_elements(list));

    /* Simple unshifts followed by shifts. */
    rc = ib_list_unshift(list, &v0);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(1UL, ib_list_elements(list));
    rc = ib_list_unshift(list, &v1);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(2UL, ib_list_elements(list));
    rc = ib_list_unshift(list, &v2);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(3UL, ib_list_elements(list));
    rc = ib_list_unshift(list, &v3);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(4UL, ib_list_elements(list));
    rc = ib_list_unshift(list, &v4);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(5UL, ib_list_elements(list));
    ASSERT_EQ(v4, *(int *)(ib_list_node_data(ib_list_first(list))));
    ASSERT_EQ(v0, *(int *)(ib_list_node_data(ib_list_last(list))));
    rc = ib_list_shift(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_shift(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_shift(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_shift(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_shift(list, (void *)&val);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(val);
    ASSERT_EQ(v0, *val);
    ASSERT_EQ(0UL, ib_list_elements(list));
}
Beispiel #3
0
/**
 * @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);
}
Beispiel #4
0
ib_status_t ib_config_directive_process(ib_cfgparser_t *cp,
                                        const char *name,
                                        ib_list_t *args)
{
    IB_FTRACE_INIT(ib_config_directive_process);
    ib_engine_t *ib = cp->ib;
    ib_dirmap_init_t *rec;
    ib_list_node_t *node;
    size_t nargs = ib_list_elements(args);
    const char *p1;
    const char *p2;
    ib_flags_t flags;
    ib_flags_t fmask;
    ib_status_t rc;
    int i;

    rc = ib_hash_get(ib->dirmap, name, (void *)&rec);
    if (rc != IB_OK) {
        IB_FTRACE_RET_STATUS(rc);
    }

    switch (rec->type) {
        case IB_DIRTYPE_ONOFF:
            if (nargs != 1) {
                ib_log_error(ib, 1, "OnOff directive \"%s\" takes one parameter, not %d",
                             name, nargs);
                rc = IB_EINVAL;
                break;
            }
            ib_list_shift(args, &p1);
            if (   (strcasecmp("on", p1) == 0)
                || (strcasecmp("yes", p1) == 0)
                || (strcasecmp("true", p1) == 0))
            {
                rc = rec->cb.fn_onoff(cp, name, 1, rec->cbdata);
            }
            else {
                rc = rec->cb.fn_onoff(cp, name, 0, rec->cbdata);
            }
            break;
        case IB_DIRTYPE_PARAM1:
            if (nargs != 1) {
                ib_log_error(ib, 1, "Param1 directive \"%s\" takes one parameter, not %d",
                             name, nargs);
                rc = IB_EINVAL;
                break;
            }
            ib_list_shift(args, &p1);
            rc = rec->cb.fn_param1(cp, name, p1, rec->cbdata);
            break;
        case IB_DIRTYPE_PARAM2:
            if (nargs != 2) {
                ib_log_error(ib, 1, "Param2 directive \"%s\" takes two parameters, not %d",
                             name, nargs);
                rc = IB_EINVAL;
                break;
            }
            ib_list_shift(args, &p1);
            ib_list_shift(args, &p2);
            rc = rec->cb.fn_param2(cp, name, p1, p2, rec->cbdata);
            break;
        case IB_DIRTYPE_LIST:
            rc = rec->cb.fn_list(cp, name, args, rec->cbdata);
            break;
        case IB_DIRTYPE_OPFLAGS:
            i = 0;
            flags = 0;
            fmask = 0;

            IB_LIST_LOOP(args, node) {
                const char *opname = (const char *)ib_list_node_data(node);
                int oper = (*opname == '-') ? -1 : ((*opname == '+') ? 1 : 0);
                ib_num_t val;

                /* If the first option does not use an operator, then
                 * this is setting all flags so set all the mask bits.
                 */
                if ((i == 0) && (oper == 0)) {
                    fmask = ~0;
                }

                ib_log_debug(ib, 9, "Processing %s option: %s", name, opname);

                /* Remove the operator from the name if required.
                 * and determine the numeric value of the option
                 * by using the value map.
                 */
                if (oper != 0) {
                    opname++;
                }

                rc = cfgp_opval(opname, rec->valmap, &val);
                if (rc != IB_OK) {
                    ib_log_error(ib, 3, "Invalid %s option: %s", name, opname);
                    IB_FTRACE_RET_STATUS(rc);
                }

                /* Mark which bit(s) we are setting. */
                fmask |= val;

                /* Set/Unset the appropriate bits. */
                if (oper == -1) {
                    flags = flags & ~val;
                }
                else {
                    flags |= val;
                }

                i++;
            }

            rc = rec->cb.fn_opflags(cp, name, flags, fmask, rec->cbdata);
            break;
        case IB_DIRTYPE_SBLK1:
            if (nargs != 1) {
                ib_log_error(ib, 1, "SBlk1 directive \"%s\" takes one parameter, not %d",
                             name, nargs);
                rc = IB_EINVAL;
                break;
            }
            ib_list_shift(args, &p1);
            rc = rec->cb.fn_sblk1(cp, name, p1, rec->cbdata);
            break;
        default:
            rc = IB_EINVAL;
    }

    IB_FTRACE_RET_STATUS(rc);
}