summaryrefslogtreecommitdiff
path: root/dbm/apr_dbm.c
diff options
context:
space:
mode:
Diffstat (limited to 'dbm/apr_dbm.c')
-rw-r--r--dbm/apr_dbm.c61
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);