diff options
Diffstat (limited to 'dbm/apr_dbm.c')
-rw-r--r-- | dbm/apr_dbm.c | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/dbm/apr_dbm.c b/dbm/apr_dbm.c index 71ba113ec..0147e0ab1 100644 --- a/dbm/apr_dbm.c +++ b/dbm/apr_dbm.c @@ -57,6 +57,8 @@ #error a DBM implementation was not specified #endif +#define ERROR_SIZE 1024 + #if APR_HAVE_MODULAR_DSO static apr_hash_t *drivers = NULL; @@ -75,12 +77,15 @@ static apr_status_t dbm_term(void *ptr) #endif /* APR_HAVE_MODULAR_DSO */ -static apr_status_t dbm_open_type(apr_dbm_type_t const* * vtable, - const char *type, - apr_pool_t *pool) +APR_DECLARE(apr_status_t) apr_dbm_get_driver(const apr_dbm_driver_t **vtable, + const char *type, const apu_err_t **result, apr_pool_t *pool) { #if !APR_HAVE_MODULAR_DSO + if (result) { + *result = NULL; /* until further notice */ + } + *vtable = NULL; if (!strcasecmp(type, "default")) *vtable = &DBM_VTABLE; #if APU_HAVE_DB @@ -98,18 +103,36 @@ static apr_status_t dbm_open_type(apr_dbm_type_t const* * vtable, #endif /* avoid empty block */ ; } - if (*vtable) + if (*vtable) { return APR_SUCCESS; + } + + if (result && !*result) { + char *buffer = apr_pcalloc(pool, ERROR_SIZE); + apu_err_t *err = apr_pcalloc(pool, sizeof(apu_err_t)); + if (err && buffer) { + apr_strerror(APR_ENOTIMPL, buffer, ERROR_SIZE - 1); + err->msg = buffer; + err->reason = apr_pstrdup(pool, type); + *result = err; + } + } + return APR_ENOTIMPL; #else /* APR_HAVE_MODULAR_DSO */ char modname[32]; char symname[34]; + apr_dso_handle_t *dso; apr_dso_handle_sym_t symbol; apr_status_t rv; int usertype = 0; + if (result) { + *result = NULL; /* until further notice */ + } + if (!strcasecmp(type, "default")) type = DBM_NAME; else if (!strcasecmp(type, "db")) type = "db"; else if (*type && !strcasecmp(type + 1, "dbm")) { @@ -173,7 +196,7 @@ static apr_status_t dbm_open_type(apr_dbm_type_t const* * vtable, #endif apr_snprintf(symname, sizeof(symname), "apr_dbm_type_%s", type); - rv = apu_dso_load(NULL, &symbol, modname, symname, pool); + rv = apu_dso_load(&dso, &symbol, modname, symname, pool); if (rv == APR_SUCCESS || rv == APR_EINIT) { /* previously loaded?!? */ *vtable = symbol; if (usertype) @@ -185,6 +208,18 @@ static apr_status_t dbm_open_type(apr_dbm_type_t const* * vtable, *vtable = NULL; apu_dso_mutex_unlock(); + + if (APR_SUCCESS != rv && result && !*result) { + char *buffer = apr_pcalloc(pool, ERROR_SIZE); + apu_err_t *err = apr_pcalloc(pool, sizeof(apu_err_t)); + if (err && buffer) { + apr_dso_error(dso, buffer, ERROR_SIZE - 1); + err->msg = buffer; + err->reason = apr_pstrdup(pool, modname); + *result = err; + } + } + return rv; #endif /* APR_HAVE_MODULAR_DSO */ @@ -196,8 +231,8 @@ APR_DECLARE(apr_status_t) apr_dbm_open_ex(apr_dbm_t **pdb, const char *type, apr_fileperms_t perm, apr_pool_t *pool) { - apr_dbm_type_t const* vtable = NULL; - apr_status_t rv = dbm_open_type(&vtable, type, pool); + apr_dbm_driver_t const* vtable = NULL; + apr_status_t rv = apr_dbm_get_driver(&vtable, type, NULL, pool); if (rv == APR_SUCCESS) { rv = (vtable->open)(pdb, pathname, mode, perm, pool); @@ -212,6 +247,14 @@ APR_DECLARE(apr_status_t) apr_dbm_open(apr_dbm_t **pdb, const char *pathname, return apr_dbm_open_ex(pdb, DBM_NAME, pathname, mode, perm, pool); } +APR_DECLARE(apr_status_t) apr_dbm_open2(apr_dbm_t **pdb, + const apr_dbm_driver_t *vtable, + const char *pathname, apr_int32_t mode, + apr_fileperms_t perm, apr_pool_t *pool) +{ + return (vtable->open)(pdb, pathname, mode, perm, pool); +} + APR_DECLARE(void) apr_dbm_close(apr_dbm_t *dbm) { (*dbm->type->close)(dbm); @@ -275,8 +318,8 @@ APR_DECLARE(apr_status_t) apr_dbm_get_usednames_ex(apr_pool_t *p, const char **used1, const char **used2) { - apr_dbm_type_t const* vtable; - apr_status_t rv = dbm_open_type(&vtable, type, p); + apr_dbm_driver_t const* vtable; + apr_status_t rv = apr_dbm_get_driver(&vtable, type, NULL, p); if (rv == APR_SUCCESS) { (vtable->getusednames)(p, pathname, used1, used2); |