/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "httpd.h"
#include "http_log.h"
#include "http_request.h"
#include "http_protocol.h"
#include "http_config.h"
#include "mpm_common.h"
#include "mod_status.h"

#include "apr.h"
#include "apr_strings.h"
#include "apr_time.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"
#include "apr_dbm.h"

#if APR_HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "ap_socache.h"

#if AP_NEED_SET_MUTEX_PERMS
#include "unixd.h"
#endif

/* Use of the context structure must be thread-safe after the initial
 * create/init; callers must hold the mutex. */
struct ap_socache_instance_t {
    const char *data_file;
    /* Pool must only be used with the mutex held. */
    apr_pool_t *pool;
    apr_time_t last_expiry;
    apr_interval_time_t expiry_interval;
};

/**
 * Support for DBM library
 */
#define DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )

#define DEFAULT_DBM_PREFIX "socache-dbm-"

/* ### this should use apr_dbm_usednames. */
#if !defined(DBM_FILE_SUFFIX_DIR) && !defined(DBM_FILE_SUFFIX_PAG)
#if defined(DBM_SUFFIX)
#define DBM_FILE_SUFFIX_DIR DBM_SUFFIX
#define DBM_FILE_SUFFIX_PAG DBM_SUFFIX
#elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM))
#define DBM_FILE_SUFFIX_DIR ".db"
#define DBM_FILE_SUFFIX_PAG ".db"
#else
#define DBM_FILE_SUFFIX_DIR ".dir"
#define DBM_FILE_SUFFIX_PAG ".pag"
#endif
#endif

static void socache_dbm_expire(ap_socache_instance_t *ctx, server_rec *s);

static apr_status_t socache_dbm_remove(ap_socache_instance_t *ctx,
                                       server_rec *s, const unsigned char *id,
                                       unsigned int idlen, apr_pool_t *p);

static const char *socache_dbm_create(ap_socache_instance_t **context,
                                      const char *arg,
                                      apr_pool_t *tmp, apr_pool_t *p)
{
    ap_socache_instance_t *ctx;

    *context = ctx = apr_pcalloc(p, sizeof *ctx);

    if (arg && *arg) {
        ctx->data_file = ap_server_root_relative(p, arg);
        if (!ctx->data_file) {
            return apr_psprintf(tmp, "Invalid cache file path %s", arg);
        }
    }

    apr_pool_create(&ctx->pool, p);
    apr_pool_tag(ctx->pool, "socache_dbm_instance");

    return NULL;
}

#if AP_NEED_SET_MUTEX_PERMS
static int try_chown(apr_pool_t *p, server_rec *s,
                     const char *name, const char *suffix)
{
    if (suffix)
        name = apr_pstrcat(p, name, suffix, NULL);
    if (-1 == chown(name, ap_unixd_config.user_id,
                    (gid_t)-1 /* no gid change */ ))
    {
        if (errno != ENOENT)
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(errno), s, APLOGNO(00802)
                         "Can't change owner of %s", name);
        return -1;
    }
    return 0;
}
#endif


static apr_status_t socache_dbm_init(ap_socache_instance_t *ctx,
                                     const char *namespace,
                                     const struct ap_socache_hints *hints,
                                     server_rec *s, apr_pool_t *p)
{
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    const apr_dbm_driver_t *driver;
    const apu_err_t *err;
#endif
    apr_dbm_t *dbm;
    apr_status_t rv;

    /* for the DBM we need the data file */
    if (ctx->data_file == NULL) {
        const char *path = apr_pstrcat(p, DEFAULT_DBM_PREFIX, namespace,
                                       NULL);

        ctx->data_file = ap_runtime_dir_relative(p, path);

        if (ctx->data_file == NULL) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00803)
                         "could not use default path '%s' for DBM socache",
                         path);
            return APR_EINVAL;
        }
    }

    /* open it once to create it and to make sure it _can_ be created */
    apr_pool_clear(ctx->pool);

#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
            ctx->pool) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10277)
                "Cannot load socache DBM library '%s': %s",
                     err->reason, err->msg);
        return rv;
    }
    if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file,
            APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00804)
                     "Cannot create socache DBM file `%s'",
                     ctx->data_file);
        return DECLINED;
    }
#else
    if ((rv = apr_dbm_open(&dbm, ctx->data_file,
            APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00804)
                     "Cannot create socache DBM file `%s'",
                     ctx->data_file);
        return rv;
    }
#endif
    apr_dbm_close(dbm);

    ctx->expiry_interval = (hints && hints->expiry_interval
                            ? hints->expiry_interval : apr_time_from_sec(30));

#if AP_NEED_SET_MUTEX_PERMS
    /*
     * We have to make sure the Apache child processes have access to
     * the DBM file. But because there are brain-dead platforms where we
     * cannot exactly determine the suffixes we try all possibilities.
     */
    if (geteuid() == 0 /* is superuser */) {
        try_chown(p, s, ctx->data_file, NULL);
        if (try_chown(p, s, ctx->data_file, DBM_FILE_SUFFIX_DIR))
            if (try_chown(p, s, ctx->data_file, ".db"))
                try_chown(p, s, ctx->data_file, ".dir");
        if (try_chown(p, s, ctx->data_file, DBM_FILE_SUFFIX_PAG))
            if (try_chown(p, s, ctx->data_file, ".db"))
                try_chown(p, s, ctx->data_file, ".pag");
    }
#endif
    socache_dbm_expire(ctx, s);

    return APR_SUCCESS;
}

static void socache_dbm_destroy(ap_socache_instance_t *ctx, server_rec *s)
{
    /* the correct way */
    unlink(apr_pstrcat(ctx->pool, ctx->data_file, DBM_FILE_SUFFIX_DIR, NULL));
    unlink(apr_pstrcat(ctx->pool, ctx->data_file, DBM_FILE_SUFFIX_PAG, NULL));
    /* the additional ways to be sure */
    unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".dir", NULL));
    unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".pag", NULL));
    unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".db", NULL));
    unlink(ctx->data_file);
}

static apr_status_t socache_dbm_store(ap_socache_instance_t *ctx,
                                      server_rec *s, const unsigned char *id,
                                      unsigned int idlen, apr_time_t expiry,
                                      unsigned char *ucaData,
                                      unsigned int nData, apr_pool_t *pool)
{
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    const apr_dbm_driver_t *driver;
    const apu_err_t *err;
#endif
    apr_dbm_t *dbm;
    apr_datum_t dbmkey;
    apr_datum_t dbmval;
    apr_status_t rv;

    /* be careful: do not try to store too much bytes in a DBM file! */
#ifdef PAIRMAX
    if ((idlen + nData) >= PAIRMAX) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00805)
                 "data size too large for DBM socache: %d >= %d",
                 (idlen + nData), PAIRMAX);
        return APR_ENOSPC;
    }
#else
    if ((idlen + nData) >= 950 /* at least less than approx. 1KB */) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00806)
                 "data size too large for DBM socache: %d >= %d",
                 (idlen + nData), 950);
        return APR_ENOSPC;
    }
#endif

    /* create DBM key */
    dbmkey.dptr  = (char *)id;
    dbmkey.dsize = idlen;

    /* create DBM value */
    dbmval.dsize = sizeof(apr_time_t) + nData;
    dbmval.dptr  = (char *)ap_malloc(dbmval.dsize);
    memcpy((char *)dbmval.dptr, &expiry, sizeof(apr_time_t));
    memcpy((char *)dbmval.dptr+sizeof(apr_time_t), ucaData, nData);

    /* and store it to the DBM file */
    apr_pool_clear(ctx->pool);

#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
            ctx->pool) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10278)
                "Cannot load socache DBM library '%s' (store): %s",
                     err->reason, err->msg);
        free(dbmval.dptr);
        return rv;
    }
    if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file,
            APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00807)
                     "Cannot open socache DBM file `%s' for writing "
                     "(store)",
                     ctx->data_file);
        free(dbmval.dptr);
        return rv;
    }
#else
    if ((rv = apr_dbm_open(&dbm, ctx->data_file,
                           APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00807)
                     "Cannot open socache DBM file `%s' for writing "
                     "(store)",
                     ctx->data_file);
        free(dbmval.dptr);
        return rv;
    }
#endif
    if ((rv = apr_dbm_store(dbm, dbmkey, dbmval)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00808)
                     "Cannot store socache object to DBM file `%s'",
                     ctx->data_file);
        apr_dbm_close(dbm);
        free(dbmval.dptr);
        return rv;
    }
    apr_dbm_close(dbm);

    /* free temporary buffers */
    free(dbmval.dptr);

    /* allow the regular expiring to occur */
    socache_dbm_expire(ctx, s);

    return APR_SUCCESS;
}

static apr_status_t socache_dbm_retrieve(ap_socache_instance_t *ctx, server_rec *s,
                                         const unsigned char *id, unsigned int idlen,
                                         unsigned char *dest, unsigned int *destlen,
                                         apr_pool_t *p)
{
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    const apr_dbm_driver_t *driver;
    const apu_err_t *err;
#endif
    apr_dbm_t *dbm;
    apr_datum_t dbmkey;
    apr_datum_t dbmval;
    unsigned int nData;
    apr_time_t expiry;
    apr_time_t now;
    apr_status_t rc;

    /* allow the regular expiring to occur */
    socache_dbm_expire(ctx, s);

    /* create DBM key and values */
    dbmkey.dptr  = (char *)id;
    dbmkey.dsize = idlen;

    /* and fetch it from the DBM file
     * XXX: Should we open the dbm against r->pool so the cleanup will
     * do the apr_dbm_close? This would make the code a bit cleaner.
     */
    apr_pool_clear(ctx->pool);
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
            ctx->pool) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10279)
                "Cannot load socache DBM library '%s' (fetch): %s",
                     err->reason, err->msg);
        return rc;
    }
    if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file,
            APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, APLOGNO(00809)
                     "Cannot open socache DBM file `%s' for reading "
                     "(fetch)",
                     ctx->data_file);
        return rc;
    }
#else
    if ((rc = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                           DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, APLOGNO(00809)
                     "Cannot open socache DBM file `%s' for reading "
                     "(fetch)",
                     ctx->data_file);
        return rc;
    }
#endif
    rc = apr_dbm_fetch(dbm, dbmkey, &dbmval);
    if (rc != APR_SUCCESS) {
        apr_dbm_close(dbm);
        return APR_NOTFOUND;
    }
    if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(apr_time_t)) {
        apr_dbm_close(dbm);
        return APR_EGENERAL;
    }

    /* parse resulting data */
    nData = dbmval.dsize-sizeof(apr_time_t);
    if (nData > *destlen) {
        apr_dbm_close(dbm);
        return APR_ENOSPC;
    }

    *destlen = nData;
    memcpy(&expiry, dbmval.dptr, sizeof(apr_time_t));
    memcpy(dest, (char *)dbmval.dptr + sizeof(apr_time_t), nData);

    apr_dbm_close(dbm);

    /* make sure the stuff is still not expired */
    now = apr_time_now();
    if (expiry <= now) {
        socache_dbm_remove(ctx, s, id, idlen, p);
        return APR_NOTFOUND;
    }

    return APR_SUCCESS;
}

static apr_status_t socache_dbm_remove(ap_socache_instance_t *ctx,
                                       server_rec *s, const unsigned char *id,
                                       unsigned int idlen, apr_pool_t *p)
{
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    const apr_dbm_driver_t *driver;
    const apu_err_t *err;
#endif
    apr_dbm_t *dbm;
    apr_datum_t dbmkey;
    apr_status_t rv;

    /* create DBM key and values */
    dbmkey.dptr  = (char *)id;
    dbmkey.dsize = idlen;

    /* and delete it from the DBM file */
    apr_pool_clear(ctx->pool);

#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
            ctx->pool) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10280)
                "Cannot load socache DBM library '%s' (delete): %s",
                     err->reason, err->msg);
        return rv;
    }
    if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file,
            APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00810)
                     "Cannot open socache DBM file `%s' for writing "
                     "(delete)",
                     ctx->data_file);
        return rv;
    }
#else
    if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                           DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00810)
                     "Cannot open socache DBM file `%s' for writing "
                     "(delete)",
                     ctx->data_file);
        return rv;
    }
#endif
    apr_dbm_delete(dbm, dbmkey);
    apr_dbm_close(dbm);

    return APR_SUCCESS;
}

static void socache_dbm_expire(ap_socache_instance_t *ctx, server_rec *s)
{
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    const apr_dbm_driver_t *driver;
    const apu_err_t *err;
#endif
    apr_dbm_t *dbm;
    apr_datum_t dbmkey;
    apr_datum_t dbmval;
    apr_time_t expiry;
    int elts = 0;
    int deleted = 0;
    int expired;
    apr_datum_t *keylist;
    int keyidx;
    int i;
    apr_time_t now;
    apr_status_t rv;

    /*
     * make sure the expiration for still not-accessed
     * socache entries is done only from time to time
     */
    now = apr_time_now();

    if (now < ctx->last_expiry + ctx->expiry_interval) {
        return;
    }

    ctx->last_expiry = now;

#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
            ctx->pool) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10281)
                "Cannot load socache DBM library '%s' (expire): %s",
                     err->reason, err->msg);
        return rv;
    }
#endif

    /*
     * Here we have to be very carefully: Not all DBM libraries are
     * smart enough to allow one to iterate over the elements and at the
     * same time delete expired ones. Some of them get totally crazy
     * while others have no problems. So we have to do it the slower but
     * more safe way: we first iterate over all elements and remember
     * those which have to be expired. Then in a second pass we delete
     * all those expired elements. Additionally we reopen the DBM file
     * to be really safe in state.
     */

#define KEYMAX 1024

    for (;;) {
        /* allocate the key array in a memory sub pool */
        apr_pool_clear(ctx->pool);

        if ((keylist = apr_palloc(ctx->pool, sizeof(dbmkey)*KEYMAX)) == NULL) {
            break;
        }

        /* pass 1: scan DBM database */
        keyidx = 0;
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file, APR_DBM_RWCREATE,
                               DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00811)
                         "Cannot open socache DBM file `%s' for "
                         "scanning",
                         ctx->data_file);
            break;
        }
#else
        if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                               DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00811)
                         "Cannot open socache DBM file `%s' for "
                         "scanning",
                         ctx->data_file);
            break;
        }
#endif
        apr_dbm_firstkey(dbm, &dbmkey);
        while (dbmkey.dptr != NULL) {
            elts++;
            expired = FALSE;
            apr_dbm_fetch(dbm, dbmkey, &dbmval);
            if (dbmval.dsize <= sizeof(apr_time_t) || dbmval.dptr == NULL)
                expired = TRUE;
            else {
                memcpy(&expiry, dbmval.dptr, sizeof(apr_time_t));
                if (expiry <= now)
                    expired = TRUE;
            }
            if (expired) {
                if ((keylist[keyidx].dptr = apr_pmemdup(ctx->pool, dbmkey.dptr, dbmkey.dsize)) != NULL) {
                    keylist[keyidx].dsize = dbmkey.dsize;
                    keyidx++;
                    if (keyidx == KEYMAX)
                        break;
                }
            }
            apr_dbm_nextkey(dbm, &dbmkey);
        }
        apr_dbm_close(dbm);

        /* pass 2: delete expired elements */
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if (apr_dbm_open2(&dbm, driver, ctx->data_file, APR_DBM_RWCREATE,
                         DBM_FILE_MODE, ctx->pool) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00812)
                         "Cannot re-open socache DBM file `%s' for "
                         "expiring",
                         ctx->data_file);
            break;
        }
#else
        if (apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                         DBM_FILE_MODE, ctx->pool) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00812)
                         "Cannot re-open socache DBM file `%s' for "
                         "expiring",
                         ctx->data_file);
            break;
        }
#endif
        for (i = 0; i < keyidx; i++) {
            apr_dbm_delete(dbm, keylist[i]);
            deleted++;
        }
        apr_dbm_close(dbm);

        if (keyidx < KEYMAX)
            break;
    }

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00813)
                 "DBM socache expiry: "
                 "old: %d, new: %d, removed: %d",
                 elts, elts-deleted, deleted);
}

static void socache_dbm_status(ap_socache_instance_t *ctx, request_rec *r,
                               int flags)
{
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    const apr_dbm_driver_t *driver;
    const apu_err_t *err;
#endif
    apr_dbm_t *dbm;
    apr_datum_t dbmkey;
    apr_datum_t dbmval;
    int elts;
    long size;
    int avg;
    apr_status_t rv;

    elts = 0;
    size = 0;

    apr_pool_clear(ctx->pool);
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
            ctx->pool) != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10282)
                "Cannot load socache DBM library '%s' (status retrieval): %s",
                     err->reason, err->msg);
        return;
    }
    if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file, APR_DBM_RWCREATE,
                           DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00814)
                     "Cannot open socache DBM file `%s' for status "
                     "retrieval",
                     ctx->data_file);
        return;
    }
#else
    if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                           DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00814)
                     "Cannot open socache DBM file `%s' for status "
                     "retrieval",
                     ctx->data_file);
        return;
    }
#endif
    /*
     * XXX - Check the return value of apr_dbm_firstkey, apr_dbm_fetch - TBD
     */
    apr_dbm_firstkey(dbm, &dbmkey);
    for ( ; dbmkey.dptr != NULL; apr_dbm_nextkey(dbm, &dbmkey)) {
        apr_dbm_fetch(dbm, dbmkey, &dbmval);
        if (dbmval.dptr == NULL)
            continue;
        elts += 1;
        size += dbmval.dsize;
    }
    apr_dbm_close(dbm);
    if (size > 0 && elts > 0)
        avg = (int)(size / (long)elts);
    else
        avg = 0;
    if (!(flags & AP_STATUS_SHORT)) {
        ap_rprintf(r, "cache type: <b>DBM</b>, maximum size: <b>unlimited</b><br>");
        ap_rprintf(r, "current entries: <b>%d</b>, current size: <b>%ld</b> bytes<br>", elts, size);
        ap_rprintf(r, "average entry size: <b>%d</b> bytes<br>", avg);
    }
    else {
        ap_rputs("CacheType: DBM\n", r);
        ap_rputs("CacheMaximumSize: unlimited\n", r);
        ap_rprintf(r, "CacheCurrentEntries: %d\n", elts);
        ap_rprintf(r, "CacheCurrentSize: %ld\n", size);
        ap_rprintf(r, "CacheAvgEntrySize: %d\n", avg);
    }
}

static apr_status_t socache_dbm_iterate(ap_socache_instance_t *ctx,
                                        server_rec *s, void *userctx,
                                        ap_socache_iterator_t *iterator,
                                        apr_pool_t *pool)
{
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    const apr_dbm_driver_t *driver;
    const apu_err_t *err;
#endif
    apr_dbm_t *dbm;
    apr_datum_t dbmkey;
    apr_datum_t dbmval;
    apr_time_t expiry;
    int expired;
    apr_time_t now;
    apr_status_t rv;

    /*
     * make sure the expired records are omitted
     */
    now = apr_time_now();
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
    if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
            ctx->pool) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10283)
                "Cannot load socache DBM library '%s' (iterating): %s",
                     err->reason, err->msg);
        return rv;
    }
    if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file, APR_DBM_RWCREATE,
                           DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00815)
                     "Cannot open socache DBM file `%s' for "
                     "iterating", ctx->data_file);
        return rv;
    }
#else
    if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                           DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00815)
                     "Cannot open socache DBM file `%s' for "
                     "iterating", ctx->data_file);
        return rv;
    }
#endif
    rv = apr_dbm_firstkey(dbm, &dbmkey);
    while (rv == APR_SUCCESS && dbmkey.dptr != NULL) {
        expired = FALSE;
        apr_dbm_fetch(dbm, dbmkey, &dbmval);
        if (dbmval.dsize <= sizeof(apr_time_t) || dbmval.dptr == NULL)
            expired = TRUE;
        else {
            memcpy(&expiry, dbmval.dptr, sizeof(apr_time_t));
            if (expiry <= now)
                expired = TRUE;
        }
        if (!expired) {
            rv = iterator(ctx, s, userctx,
                             (unsigned char *)dbmkey.dptr, dbmkey.dsize,
                             (unsigned char *)dbmval.dptr + sizeof(apr_time_t),
                             dbmval.dsize - sizeof(apr_time_t), pool);
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00816)
                         "dbm `%s' entry iterated", ctx->data_file);
            if (rv != APR_SUCCESS)
                return rv;
        }
        rv = apr_dbm_nextkey(dbm, &dbmkey);
    }
    apr_dbm_close(dbm);

    if (rv != APR_SUCCESS && rv != APR_EOF) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00817)
                     "Failure reading first/next socache DBM file `%s' record",
                     ctx->data_file);
        return rv;
    }
    return APR_SUCCESS;
}

static const ap_socache_provider_t socache_dbm = {
    "dbm",
    AP_SOCACHE_FLAG_NOTMPSAFE,
    socache_dbm_create,
    socache_dbm_init,
    socache_dbm_destroy,
    socache_dbm_store,
    socache_dbm_retrieve,
    socache_dbm_remove,
    socache_dbm_status,
    socache_dbm_iterate
};

static void register_hooks(apr_pool_t *p)
{
    ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "dbm",
                         AP_SOCACHE_PROVIDER_VERSION,
                         &socache_dbm);
}

AP_DECLARE_MODULE(socache_dbm) = {
    STANDARD20_MODULE_STUFF,
    NULL, NULL, NULL, NULL, NULL,
    register_hooks
};
