ib_status_t ib_dso_open( ib_dso_t **dso, const char *file, ib_mpool_t *pool ) { void *handle; /// @todo Probably need to do this portably someday handle = dlopen(file, RTLD_LAZY); if (handle == NULL) { ib_util_log_error("%s", dlerror()); return IB_EINVAL; } *dso = ib_mpool_alloc(pool, sizeof(**dso)); if (*dso == NULL) { dlclose(handle); return IB_EALLOC; } (*dso)->mp = pool; (*dso)->handle = handle; return IB_OK; }
ib_status_t ib_dso_open( ib_dso_t **dso, const char *file, ib_mm_t mm ) { assert(dso != NULL); assert(file != NULL); void *handle; /// @todo Probably need to do this portably someday handle = dlopen(file, RTLD_GLOBAL|RTLD_LAZY); if (handle == NULL) { ib_util_log_error("%s", dlerror()); return IB_EINVAL; } *dso = ib_mm_alloc(mm, sizeof(**dso)); if (*dso == NULL) { dlclose(handle); return IB_EALLOC; } (*dso)->mm = mm; (*dso)->handle = handle; return IB_OK; }
ib_status_t ibpp_caught_boost_exception( ib_engine_t* engine, const boost::exception& e ) { std::string message; int level = 1; message = "Unknown boost::exception thrown: "; if (boost::get_error_info<boost::throw_function>(e)) { message += *boost::get_error_info<boost::throw_function>(e); } else { message += "No information provided. Please report as bug."; } if (boost::get_error_info<errinfo_level>(e)) { level = *boost::get_error_info<errinfo_level>(e); } if (engine) { ib_log(engine, level, "%s", message.c_str()); ib_log_debug(engine, "%s", diagnostic_information(e).c_str() ); } else { ib_util_log_error("%s", message.c_str()); ib_util_log_debug("%s", diagnostic_information(e).c_str() ); } return IB_EUNKNOWN; }
ib_status_t ibpp_caught_ib_exception( ib_engine_t* engine, ib_status_t status, const error& e ) { std::string message; int level = 1; message = std::string(ib_status_to_string(status)) + ":"; if (boost::get_error_info<errinfo_what>(e)) { message += *boost::get_error_info<errinfo_what>(e); } else { message += "IronBee++ Exception but no explanation provided. " "Please report as bug."; } if (boost::get_error_info<errinfo_level>(e)) { level = *boost::get_error_info<errinfo_level>(e); } if (engine) { ib_log(engine, level, "%s", message.c_str()); ib_log_debug(engine, "%s", diagnostic_information(e).c_str() ); } else { ib_util_log_error("%s", message.c_str()); ib_util_log_debug("%s", diagnostic_information(e).c_str() ); } return status; }
ib_status_t ibpp_caught_std_exception( ib_engine_t* engine, ib_status_t status, const std::exception& e ) { if (status == IB_EALLOC) { return status; } std::string message; if (status == IB_EINVAL) { message = "Invalid argument: "; } else { message = "Unknown std::exception thrown: "; } message += e.what(); if (engine) { ib_log_error(engine, "%s", message.c_str()); } else { ib_util_log_error("%s", message.c_str()); } return status; }
ib_status_t ib_util_mkpath(const char *path, mode_t mode) { char *ppath = NULL; char *cpath = NULL; ib_status_t rc; if (strcmp(path, ".") == 0 || strcmp(path, "/") == 0) { return IB_OK; } /* Attempt to create the dir. If it returns ENOENT, then * recursivly attempt to create the parent dir(s) until * they are all created. */ if ((mkdir(path, mode) == -1) && (errno == ENOENT)) { int ec; /* Some implementations may modify the path argument, * so make a copy first. */ if ((cpath = strdup(path)) == NULL) { return IB_EALLOC; } if ((ppath = dirname(cpath)) == NULL) { rc = IB_EINVAL; goto cleanup; } rc = ib_util_mkpath(ppath, mode); if (rc != IB_OK) { goto cleanup; } /* Parent path was created, so try again. */ ec = mkdir(path, mode); if (ec == -1) { ec = errno; ib_util_log_error(3, "Failed to create path \"%s\": %s (%d)", path, strerror(ec), ec); rc = IB_EINVAL; goto cleanup; } } rc = IB_OK; cleanup: if (cpath != NULL) { free(cpath); } return rc; }
ib_status_t ibpp_caught_unknown_exception( ib_engine_t* engine ) { if (engine) { ib_log_error(engine, "%s", "Completely unknown exception thrown. " "Please report as bug." ); } else { ib_util_log_error("%s", "Completely unknown exception thrown. " "Please report as bug." ); } return IB_EUNKNOWN; }
ib_status_t DLL_PUBLIC ib_dso_sym_find( ib_dso_sym_t **psym, ib_dso_t *dso, const char *name ) { char *err; if (dso == NULL || psym == NULL) { return IB_EINVAL; } dlerror(); /* Clear any errors */ *psym = dlsym(dso->handle, name); err = dlerror(); if (err != NULL) { ib_util_log_error("%s", err); return IB_ENOENT; } return IB_OK; }
/** * Internal compilation of the modpcre pattern. * * @param[in] ib IronBee engine for logging. * @param[in] pool The memory pool to allocate memory out of. * @param[out] pcre_cpatt Struct containing the compilation. * @param[in] patt The uncompiled pattern to match. * @param[out] errptr Pointer to an error message describing the failure. * @param[out] errorffset The location of the failure, if this fails. * @returns IronBee status. IB_EINVAL if the pattern is invalid, * IB_EALLOC if memory allocation fails or IB_OK. */ static ib_status_t pcre_compile_internal(ib_engine_t *ib, ib_mpool_t *pool, modpcre_cpatt_t **pcre_cpatt, const char *patt, const char **errptr, int *erroffset) { IB_FTRACE_INIT(); /* Compiled pattern. */ pcre *cpatt = NULL; /* Compiled pattern size. Used to copy cpatt. */ size_t cpatt_sz; /* Extra data structure. This contains the study_data pointer. */ pcre_extra *edata = NULL; /* Size of edata->study_data. */ size_t study_data_sz; /* Is the compiled regex jit-compiled? This impacts how it is executed. */ int is_jit; /* How cpatt is produced. */ const int compile_flags = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY; #ifdef PCRE_HAVE_JIT /* Determine the success of a call. */ int rc; /* Determines if the pcre compilation was successful with pcre_jit. */ int pcre_jit_ret; /* How edata is produced if we are using JIT. */ const int study_flags = PCRE_STUDY_JIT_COMPILE; #else /* How edata is produced if we are not using JIT. */ const int study_flags = 0; #endif /* PCRE_HAVE_JIT */ cpatt = pcre_compile(patt, compile_flags, errptr, erroffset, NULL); if (*errptr != NULL) { ib_util_log_error("PCRE compile error for \"%s\": %s at offset %d", patt, *errptr, *erroffset); IB_FTRACE_RET_STATUS(IB_EINVAL); } edata = pcre_study(cpatt, study_flags, errptr); #ifdef PCRE_HAVE_JIT if(*errptr != NULL) { pcre_free(cpatt); ib_util_log_error("PCRE-JIT study failed: %s", *errptr); IB_FTRACE_RET_STATUS(IB_EINVAL); } /* The check to see if JIT compilation was a success changed in 8.20RC1 now uses pcre_fullinfo see doc/pcrejit.3 */ rc = pcre_fullinfo(cpatt, edata, PCRE_INFO_JIT, &pcre_jit_ret); if (rc != 0) { ib_log_error(ib, "PCRE-JIT failed to get pcre_fullinfo"); is_jit = 0; } else if (pcre_jit_ret != 1) { ib_log_info(ib, "PCRE-JIT compiler does not support: %s", patt); ib_log_info(ib, "It will fallback to the normal PCRE"); is_jit = 0; } else { /* Assume pcre_jit_ret == 1. */ is_jit = 1; } #else if(*errptr != NULL) { pcre_free(cpatt); ib_log_info(ib, "PCRE study failed: %s", *errptr); } is_jit = 0; #endif /*PCRE_HAVE_JIT*/ /* Compute the size of the populated values of cpatt. */ pcre_fullinfo(cpatt, edata, PCRE_INFO_SIZE, &cpatt_sz); if (edata != NULL) { pcre_fullinfo(cpatt, edata, PCRE_INFO_STUDYSIZE, &study_data_sz); } else { study_data_sz = 0; } /** * Below is only allocation and copy operations to pass the PCRE results * back to the output variable pcre_cpatt. */ *pcre_cpatt = (modpcre_cpatt_t *)ib_mpool_alloc(pool, sizeof(**pcre_cpatt)); if (*pcre_cpatt == NULL) { pcre_free(cpatt); pcre_free(edata); ib_log_error(ib, "Failed to allocate pcre_cpatt of size: %zd", sizeof(**pcre_cpatt)); IB_FTRACE_RET_STATUS(IB_EALLOC); } (*pcre_cpatt)->is_jit = is_jit; (*pcre_cpatt)->cpatt_sz = cpatt_sz; (*pcre_cpatt)->study_data_sz = study_data_sz; /* Copy pattern. */ (*pcre_cpatt)->patt = ib_mpool_strdup(pool, patt); if ((*pcre_cpatt)->patt == NULL) { pcre_free(cpatt); pcre_free(edata); ib_log_error(ib, "Failed to duplicate pattern string: %s", patt); IB_FTRACE_RET_STATUS(IB_EALLOC); } /* Copy compiled pattern. */ (*pcre_cpatt)->cpatt = ib_mpool_memdup(pool, cpatt, cpatt_sz); pcre_free(cpatt); if ((*pcre_cpatt)->cpatt == NULL) { pcre_free(edata); ib_log_error(ib, "Failed to duplicate pattern of size: %zd", cpatt_sz); IB_FTRACE_RET_STATUS(IB_EALLOC); } /* Copy extra data (study data). */ if (edata != NULL) { /* Copy edata. */ (*pcre_cpatt)->edata = ib_mpool_memdup(pool, edata, sizeof(*edata)); if ((*pcre_cpatt)->edata == NULL) { pcre_free(edata); ib_log_error(ib, "Failed to duplicate edata."); IB_FTRACE_RET_STATUS(IB_EALLOC); } /* Copy edata->study_data. */ (*pcre_cpatt)->edata->study_data = ib_mpool_memdup(pool, edata->study_data, study_data_sz); pcre_free(edata); if ((*pcre_cpatt)->edata->study_data == NULL) { ib_log_error(ib, "Failed to study data of size: %zd", study_data_sz); IB_FTRACE_RET_STATUS(IB_EALLOC); } } else { (*pcre_cpatt)->edata = NULL; } IB_FTRACE_RET_STATUS(IB_OK); }
/** * Internal compilation of the dfa pattern. * * The major difference in this compilation from that of a normal pcre pattern * is that it does not use PCRE_JIT because it is intended for use * on streaming data. Streaming data is delivered in chunks * and partial matches are found. Doing partial matches and resumes * disable JIT optimizations and some a few other normal optimizations. * * @param[in] pool The memory pool to allocate memory out of. * @param[out] pcre_cpatt Struct containing the compilation. * @param[in] patt The uncompiled pattern to match. * @param[out] errptr Pointer to an error message describing the failure. * @param[out] errorffset The location of the failure, if this fails. * @returns IronBee status. IB_EINVAL if the pattern is invalid, * IB_EALLOC if memory allocation fails or IB_OK. */ static ib_status_t dfa_compile_internal(ib_mpool_t *pool, dfa_rule_data_t **dfa_cpatt, const char *patt, const char **errptr, int *erroffset) { IB_FTRACE_INIT(); /* Compiled pattern. */ pcre *cpatt = NULL; /* Compiled pattern size. Used to copy cpatt. */ size_t cpatt_sz; /* Extra data structure. This contains the study_data pointer. */ pcre_extra *edata = NULL; /* Size of edata->study_data. */ size_t study_data_sz; /* How cpatt is produced. */ const int compile_flags = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY; /* How edata is produced if we are not using JIT. */ const int study_flags = 0; cpatt = pcre_compile(patt, compile_flags, errptr, erroffset, NULL); if (*errptr != NULL) { ib_util_log_error("PCRE compile error for \"%s\": %s at offset %d", patt, *errptr, *erroffset); IB_FTRACE_RET_STATUS(IB_EINVAL); } edata = pcre_study(cpatt, study_flags, errptr); if(*errptr != NULL) { pcre_free(cpatt); ib_util_log_error("PCRE study failed: %s", *errptr); } /* Compute the size of the populated values of cpatt. */ pcre_fullinfo(cpatt, edata, PCRE_INFO_SIZE, &cpatt_sz); if (edata != NULL) { pcre_fullinfo(cpatt, edata, PCRE_INFO_STUDYSIZE, &study_data_sz); } else { study_data_sz = 0; } /** * Below is only allocation and copy operations to pass the PCRE results * back to the output variable dfa_cpatt. */ *dfa_cpatt = (dfa_rule_data_t *)ib_mpool_alloc(pool, sizeof(**dfa_cpatt)); if (*dfa_cpatt == NULL) { pcre_free(cpatt); pcre_free(edata); IB_FTRACE_RET_STATUS(IB_EALLOC); } (*dfa_cpatt)->cpatt_sz = cpatt_sz; (*dfa_cpatt)->study_data_sz = study_data_sz; /* Copy pattern. */ (*dfa_cpatt)->patt = ib_mpool_strdup(pool, patt); if ((*dfa_cpatt)->patt == NULL) { pcre_free(cpatt); pcre_free(edata); IB_FTRACE_RET_STATUS(IB_EALLOC); } /* Copy compiled pattern. */ (*dfa_cpatt)->cpatt = ib_mpool_memdup(pool, cpatt, cpatt_sz); pcre_free(cpatt); if ((*dfa_cpatt)->cpatt == NULL) { pcre_free(edata); IB_FTRACE_RET_STATUS(IB_EALLOC); } /* Copy extra data (study data). */ if (edata != NULL) { /* Copy edata. */ (*dfa_cpatt)->edata = ib_mpool_memdup(pool, edata, sizeof(*edata)); if ((*dfa_cpatt)->edata == NULL) { pcre_free(edata); IB_FTRACE_RET_STATUS(IB_EALLOC); } /* Copy edata->study_data. */ (*dfa_cpatt)->edata->study_data = ib_mpool_memdup(pool, edata->study_data, study_data_sz); pcre_free(edata); if ((*dfa_cpatt)->edata->study_data == NULL) { IB_FTRACE_RET_STATUS(IB_EALLOC); } } else { (*dfa_cpatt)->edata = NULL; } IB_FTRACE_RET_STATUS(IB_OK); }