mirror of
https://github.com/apache/httpd.git
synced 2025-08-07 04:02:58 +03:00
Move util_ldap out of experimental and into ldap.
See Attic in experimental directory for previous change history. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@104718 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
740
modules/ldap/util_ldap_cache_mgr.c
Normal file
740
modules/ldap/util_ldap_cache_mgr.c
Normal file
@@ -0,0 +1,740 @@
|
||||
/* Copyright 2001-2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* util_ldap_cache_mgr.c: LDAP cache manager things
|
||||
*
|
||||
* Original code from auth_ldap module for Apache v1.3:
|
||||
* Copyright 1998, 1999 Enbridge Pipelines Inc.
|
||||
* Copyright 1999-2001 Dave Carrigan
|
||||
*/
|
||||
|
||||
#include <apr_ldap.h>
|
||||
#include "util_ldap.h"
|
||||
#include "util_ldap_cache.h"
|
||||
#include <apr_strings.h>
|
||||
|
||||
#if APR_HAS_LDAP
|
||||
|
||||
/* only here until strdup is gone */
|
||||
#include <string.h>
|
||||
|
||||
/* here till malloc is gone */
|
||||
#include <stdlib.h>
|
||||
|
||||
static const unsigned long primes[] =
|
||||
{
|
||||
11,
|
||||
19,
|
||||
37,
|
||||
73,
|
||||
109,
|
||||
163,
|
||||
251,
|
||||
367,
|
||||
557,
|
||||
823,
|
||||
1237,
|
||||
1861,
|
||||
2777,
|
||||
4177,
|
||||
6247,
|
||||
9371,
|
||||
14057,
|
||||
21089,
|
||||
31627,
|
||||
47431,
|
||||
71143,
|
||||
106721,
|
||||
160073,
|
||||
240101,
|
||||
360163,
|
||||
540217,
|
||||
810343,
|
||||
1215497,
|
||||
1823231,
|
||||
2734867,
|
||||
4102283,
|
||||
6153409,
|
||||
9230113,
|
||||
13845163,
|
||||
0
|
||||
};
|
||||
|
||||
void util_ald_free(util_ald_cache_t *cache, const void *ptr)
|
||||
{
|
||||
#if APR_HAS_SHARED_MEMORY
|
||||
if (cache->rmm_addr) {
|
||||
if (ptr)
|
||||
/* Free in shared memory */
|
||||
apr_rmm_free(cache->rmm_addr, apr_rmm_offset_get(cache->rmm_addr, (void *)ptr));
|
||||
}
|
||||
else {
|
||||
if (ptr)
|
||||
/* Cache shm is not used */
|
||||
free((void *)ptr);
|
||||
}
|
||||
#else
|
||||
if (ptr)
|
||||
free((void *)ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size)
|
||||
{
|
||||
if (0 == size)
|
||||
return NULL;
|
||||
#if APR_HAS_SHARED_MEMORY
|
||||
if (cache->rmm_addr) {
|
||||
/* allocate from shared memory */
|
||||
apr_rmm_off_t block = apr_rmm_calloc(cache->rmm_addr, size);
|
||||
return block ? (void *)apr_rmm_addr_get(cache->rmm_addr, block) : NULL;
|
||||
}
|
||||
else {
|
||||
/* Cache shm is not used */
|
||||
return (void *)calloc(sizeof(char), size);
|
||||
}
|
||||
#else
|
||||
return (void *)calloc(sizeof(char), size);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *util_ald_strdup(util_ald_cache_t *cache, const char *s)
|
||||
{
|
||||
#if APR_HAS_SHARED_MEMORY
|
||||
if (cache->rmm_addr) {
|
||||
/* allocate from shared memory */
|
||||
apr_rmm_off_t block = apr_rmm_calloc(cache->rmm_addr, strlen(s)+1);
|
||||
char *buf = block ? (char *)apr_rmm_addr_get(cache->rmm_addr, block) : NULL;
|
||||
if (buf) {
|
||||
strcpy(buf, s);
|
||||
return buf;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
/* Cache shm is not used */
|
||||
return strdup(s);
|
||||
}
|
||||
#else
|
||||
return strdup(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Computes the hash on a set of strings. The first argument is the number
|
||||
* of strings to hash, the rest of the args are strings.
|
||||
* Algorithm taken from glibc.
|
||||
*/
|
||||
unsigned long util_ald_hash_string(int nstr, ...)
|
||||
{
|
||||
int i;
|
||||
va_list args;
|
||||
unsigned long h=0, g;
|
||||
char *str, *p;
|
||||
|
||||
va_start(args, nstr);
|
||||
for (i=0; i < nstr; ++i) {
|
||||
str = va_arg(args, char *);
|
||||
for (p = str; *p; ++p) {
|
||||
h = ( h << 4 ) + *p;
|
||||
if ( ( g = h & 0xf0000000 ) ) {
|
||||
h = h ^ (g >> 24);
|
||||
h = h ^ g;
|
||||
}
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Purges a cache that has gotten full. We keep track of the time that we
|
||||
added the entry that made the cache 3/4 full, then delete all entries
|
||||
that were added before that time. It's pretty simplistic, but time to
|
||||
purge is only O(n), which is more important.
|
||||
*/
|
||||
void util_ald_cache_purge(util_ald_cache_t *cache)
|
||||
{
|
||||
unsigned long i;
|
||||
util_cache_node_t *p, *q;
|
||||
apr_time_t t;
|
||||
|
||||
if (!cache)
|
||||
return;
|
||||
|
||||
cache->last_purge = apr_time_now();
|
||||
cache->npurged = 0;
|
||||
cache->numpurges++;
|
||||
|
||||
for (i=0; i < cache->size; ++i) {
|
||||
p = cache->nodes[i];
|
||||
while (p != NULL) {
|
||||
if (p->add_time < cache->marktime) {
|
||||
q = p->next;
|
||||
(*cache->free)(cache, p->payload);
|
||||
util_ald_free(cache, p);
|
||||
cache->numentries--;
|
||||
cache->npurged++;
|
||||
p = q;
|
||||
}
|
||||
else {
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t = apr_time_now();
|
||||
cache->avg_purgetime =
|
||||
((t - cache->last_purge) + (cache->avg_purgetime * (cache->numpurges-1))) /
|
||||
cache->numpurges;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* create caches
|
||||
*/
|
||||
util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url)
|
||||
{
|
||||
util_url_node_t curl, *newcurl;
|
||||
util_ald_cache_t *search_cache;
|
||||
util_ald_cache_t *compare_cache;
|
||||
util_ald_cache_t *dn_compare_cache;
|
||||
|
||||
/* create the three caches */
|
||||
search_cache = util_ald_create_cache(st,
|
||||
util_ldap_search_node_hash,
|
||||
util_ldap_search_node_compare,
|
||||
util_ldap_search_node_copy,
|
||||
util_ldap_search_node_free,
|
||||
util_ldap_search_node_display);
|
||||
compare_cache = util_ald_create_cache(st,
|
||||
util_ldap_compare_node_hash,
|
||||
util_ldap_compare_node_compare,
|
||||
util_ldap_compare_node_copy,
|
||||
util_ldap_compare_node_free,
|
||||
util_ldap_compare_node_display);
|
||||
dn_compare_cache = util_ald_create_cache(st,
|
||||
util_ldap_dn_compare_node_hash,
|
||||
util_ldap_dn_compare_node_compare,
|
||||
util_ldap_dn_compare_node_copy,
|
||||
util_ldap_dn_compare_node_free,
|
||||
util_ldap_dn_compare_node_display);
|
||||
|
||||
/* check that all the caches initialised successfully */
|
||||
if (search_cache && compare_cache && dn_compare_cache) {
|
||||
|
||||
/* The contents of this structure will be duplicated in shared
|
||||
memory during the insert. So use stack memory rather than
|
||||
pool memory to avoid a memory leak. */
|
||||
memset (&curl, 0, sizeof(util_url_node_t));
|
||||
curl.url = url;
|
||||
curl.search_cache = search_cache;
|
||||
curl.compare_cache = compare_cache;
|
||||
curl.dn_compare_cache = dn_compare_cache;
|
||||
|
||||
newcurl = util_ald_cache_insert(st->util_ldap_cache, &curl);
|
||||
|
||||
}
|
||||
|
||||
return newcurl;
|
||||
}
|
||||
|
||||
|
||||
util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st,
|
||||
unsigned long (*hashfunc)(void *),
|
||||
int (*comparefunc)(void *, void *),
|
||||
void * (*copyfunc)(util_ald_cache_t *cache, void *),
|
||||
void (*freefunc)(util_ald_cache_t *cache, void *),
|
||||
void (*displayfunc)(request_rec *r, util_ald_cache_t *cache, void *))
|
||||
{
|
||||
util_ald_cache_t *cache;
|
||||
unsigned long i;
|
||||
|
||||
if (st->search_cache_size <= 0)
|
||||
return NULL;
|
||||
|
||||
#if APR_HAS_SHARED_MEMORY
|
||||
if (!st->cache_rmm) {
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
apr_rmm_off_t block = apr_rmm_calloc(st->cache_rmm, sizeof(util_ald_cache_t));
|
||||
cache = block ? (util_ald_cache_t *)apr_rmm_addr_get(st->cache_rmm, block) : NULL;
|
||||
}
|
||||
#else
|
||||
cache = (util_ald_cache_t *)calloc(sizeof(util_ald_cache_t), 1);
|
||||
#endif
|
||||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
#if APR_HAS_SHARED_MEMORY
|
||||
cache->rmm_addr = st->cache_rmm;
|
||||
cache->shm_addr = st->cache_shm;
|
||||
#endif
|
||||
cache->maxentries = st->search_cache_size;
|
||||
cache->numentries = 0;
|
||||
cache->size = st->search_cache_size / 3;
|
||||
if (cache->size < 64) cache->size = 64;
|
||||
for (i = 0; primes[i] && primes[i] < cache->size; ++i) ;
|
||||
cache->size = primes[i]? primes[i] : primes[i-1];
|
||||
|
||||
cache->nodes = (util_cache_node_t **)util_ald_alloc(cache, cache->size * sizeof(util_cache_node_t *));
|
||||
if (!cache->nodes) {
|
||||
util_ald_free(cache, cache);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < cache->size; ++i)
|
||||
cache->nodes[i] = NULL;
|
||||
|
||||
cache->hash = hashfunc;
|
||||
cache->compare = comparefunc;
|
||||
cache->copy = copyfunc;
|
||||
cache->free = freefunc;
|
||||
cache->display = displayfunc;
|
||||
|
||||
cache->fullmark = cache->maxentries / 4 * 3;
|
||||
cache->marktime = 0;
|
||||
cache->avg_purgetime = 0.0;
|
||||
cache->numpurges = 0;
|
||||
cache->last_purge = 0;
|
||||
cache->npurged = 0;
|
||||
|
||||
cache->fetches = 0;
|
||||
cache->hits = 0;
|
||||
cache->inserts = 0;
|
||||
cache->removes = 0;
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
void util_ald_destroy_cache(util_ald_cache_t *cache)
|
||||
{
|
||||
unsigned long i;
|
||||
util_cache_node_t *p, *q;
|
||||
|
||||
if (cache == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < cache->size; ++i) {
|
||||
p = cache->nodes[i];
|
||||
q = NULL;
|
||||
while (p != NULL) {
|
||||
q = p->next;
|
||||
(*cache->free)(cache, p->payload);
|
||||
util_ald_free(cache, p);
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
util_ald_free(cache, cache->nodes);
|
||||
util_ald_free(cache, cache);
|
||||
}
|
||||
|
||||
void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload)
|
||||
{
|
||||
int hashval;
|
||||
util_cache_node_t *p;
|
||||
|
||||
if (cache == NULL)
|
||||
return NULL;
|
||||
|
||||
cache->fetches++;
|
||||
|
||||
hashval = (*cache->hash)(payload) % cache->size;
|
||||
for (p = cache->nodes[hashval];
|
||||
p && !(*cache->compare)(p->payload, payload);
|
||||
p = p->next) ;
|
||||
|
||||
if (p != NULL) {
|
||||
cache->hits++;
|
||||
return p->payload;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert an item into the cache.
|
||||
* *** Does not catch duplicates!!! ***
|
||||
*/
|
||||
void *util_ald_cache_insert(util_ald_cache_t *cache, void *payload)
|
||||
{
|
||||
int hashval;
|
||||
util_cache_node_t *node;
|
||||
|
||||
/* sanity check */
|
||||
if (cache == NULL || payload == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check if we are full - if so, try purge */
|
||||
if (cache->numentries >= cache->maxentries) {
|
||||
util_ald_cache_purge(cache);
|
||||
if (cache->numentries >= cache->maxentries) {
|
||||
/* if the purge was not effective, we leave now to avoid an overflow */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* should be safe to add an entry */
|
||||
if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* populate the entry */
|
||||
cache->inserts++;
|
||||
hashval = (*cache->hash)(payload) % cache->size;
|
||||
node->add_time = apr_time_now();
|
||||
node->payload = (*cache->copy)(cache, payload);
|
||||
node->next = cache->nodes[hashval];
|
||||
cache->nodes[hashval] = node;
|
||||
|
||||
/* if we reach the full mark, note the time we did so
|
||||
* for the benefit of the purge function
|
||||
*/
|
||||
if (++cache->numentries == cache->fullmark) {
|
||||
cache->marktime=apr_time_now();
|
||||
}
|
||||
|
||||
return node->payload;
|
||||
}
|
||||
|
||||
void util_ald_cache_remove(util_ald_cache_t *cache, void *payload)
|
||||
{
|
||||
int hashval;
|
||||
util_cache_node_t *p, *q;
|
||||
|
||||
if (cache == NULL)
|
||||
return;
|
||||
|
||||
cache->removes++;
|
||||
hashval = (*cache->hash)(payload) % cache->size;
|
||||
for (p = cache->nodes[hashval], q=NULL;
|
||||
p && !(*cache->compare)(p->payload, payload);
|
||||
p = p->next) {
|
||||
q = p;
|
||||
}
|
||||
|
||||
/* If p is null, it means that we couldn't find the node, so just return */
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
if (q == NULL) {
|
||||
/* We found the node, and it's the first in the list */
|
||||
cache->nodes[hashval] = p->next;
|
||||
}
|
||||
else {
|
||||
/* We found the node and it's not the first in the list */
|
||||
q->next = p->next;
|
||||
}
|
||||
(*cache->free)(cache, p->payload);
|
||||
util_ald_free(cache, p);
|
||||
cache->numentries--;
|
||||
}
|
||||
|
||||
char *util_ald_cache_display_stats(request_rec *r, util_ald_cache_t *cache, char *name, char *id)
|
||||
{
|
||||
unsigned long i;
|
||||
int totchainlen = 0;
|
||||
int nchains = 0;
|
||||
double chainlen;
|
||||
util_cache_node_t *n;
|
||||
char *buf, *buf2;
|
||||
apr_pool_t *p = r->pool;
|
||||
|
||||
if (cache == NULL) {
|
||||
return "";
|
||||
}
|
||||
|
||||
for (i=0; i < cache->size; ++i) {
|
||||
if (cache->nodes[i] != NULL) {
|
||||
nchains++;
|
||||
for (n = cache->nodes[i]; n != NULL; n = n->next)
|
||||
totchainlen++;
|
||||
}
|
||||
}
|
||||
chainlen = nchains? (double)totchainlen / (double)nchains : 0;
|
||||
|
||||
if (id) {
|
||||
buf2 = apr_psprintf(p,
|
||||
"<a href=\"%s?%s\">%s</a>",
|
||||
r->uri,
|
||||
id,
|
||||
name);
|
||||
}
|
||||
else {
|
||||
buf2 = name;
|
||||
}
|
||||
|
||||
buf = apr_psprintf(p,
|
||||
"<tr valign='top'>"
|
||||
"<td nowrap>%s</td>"
|
||||
"<td align='right' nowrap>%lu (%.0f%% full)</td>"
|
||||
"<td align='right'>%.1f</td>"
|
||||
"<td align='right'>%lu/%lu</td>"
|
||||
"<td align='right'>%.0f%%</td>"
|
||||
"<td align='right'>%lu/%lu</td>",
|
||||
buf2,
|
||||
cache->numentries,
|
||||
(double)cache->numentries / (double)cache->maxentries * 100.0,
|
||||
chainlen,
|
||||
cache->hits,
|
||||
cache->fetches,
|
||||
(cache->fetches > 0 ? (double)(cache->hits) / (double)(cache->fetches) * 100.0 : 100.0),
|
||||
cache->inserts,
|
||||
cache->removes);
|
||||
|
||||
if (cache->numpurges) {
|
||||
char str_ctime[APR_CTIME_LEN];
|
||||
|
||||
apr_ctime(str_ctime, cache->last_purge);
|
||||
buf = apr_psprintf(p,
|
||||
"%s"
|
||||
"<td align='right'>%lu</td>\n"
|
||||
"<td align='right' nowrap>%s</td>\n",
|
||||
buf,
|
||||
cache->numpurges,
|
||||
str_ctime);
|
||||
}
|
||||
else {
|
||||
buf = apr_psprintf(p,
|
||||
"%s<td colspan='2' align='center'>(none)</td>\n",
|
||||
buf);
|
||||
}
|
||||
|
||||
buf = apr_psprintf(p, "%s<td align='right'>%.2g</td>\n</tr>", buf, cache->avg_purgetime);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *util_ald_cache_display(request_rec *r, util_ldap_state_t *st)
|
||||
{
|
||||
unsigned long i,j;
|
||||
char *buf, *t1, *t2, *t3;
|
||||
char *id1, *id2, *id3;
|
||||
char *argfmt = "cache=%s&id=%d&off=%d";
|
||||
char *scanfmt = "cache=%4s&id=%u&off=%u%1s";
|
||||
apr_pool_t *pool = r->pool;
|
||||
util_cache_node_t *p = NULL;
|
||||
util_url_node_t *n = NULL;
|
||||
|
||||
util_ald_cache_t *util_ldap_cache = st->util_ldap_cache;
|
||||
|
||||
|
||||
if (!util_ldap_cache) {
|
||||
return "<tr valign='top'><td nowrap colspan=7>Cache has not been enabled/initialised.</td></tr>";
|
||||
}
|
||||
|
||||
if (r->args && strlen(r->args)) {
|
||||
char cachetype[5], lint[2];
|
||||
unsigned int id, off;
|
||||
char date_str[APR_CTIME_LEN+1];
|
||||
|
||||
if ((3 == sscanf(r->args, scanfmt, cachetype, &id, &off, lint)) &&
|
||||
(id < util_ldap_cache->size)) {
|
||||
|
||||
if ((p = util_ldap_cache->nodes[id]) != NULL) {
|
||||
n = (util_url_node_t *)p->payload;
|
||||
buf = (char*)n->url;
|
||||
}
|
||||
else {
|
||||
buf = "";
|
||||
}
|
||||
|
||||
ap_rputs(apr_psprintf(r->pool,
|
||||
"<p>\n"
|
||||
"<table border='0'>\n"
|
||||
"<tr>\n"
|
||||
"<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Cache Name:</b></font></td>"
|
||||
"<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%s (%s)</b></font></td>"
|
||||
"</tr>\n"
|
||||
"</table>\n</p>\n",
|
||||
buf,
|
||||
cachetype[0] == 'm'? "Main" :
|
||||
(cachetype[0] == 's' ? "Search" :
|
||||
(cachetype[0] == 'c' ? "Compares" : "DNCompares"))), r);
|
||||
|
||||
switch (cachetype[0]) {
|
||||
case 'm':
|
||||
if (util_ldap_cache->marktime) {
|
||||
apr_ctime(date_str, util_ldap_cache->marktime);
|
||||
}
|
||||
else
|
||||
date_str[0] = 0;
|
||||
|
||||
ap_rputs(apr_psprintf(r->pool,
|
||||
"<p>\n"
|
||||
"<table border='0'>\n"
|
||||
"<tr>\n"
|
||||
"<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Size:</b></font></td>"
|
||||
"<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%ld</b></font></td>"
|
||||
"</tr>\n"
|
||||
"<tr>\n"
|
||||
"<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Max Entries:</b></font></td>"
|
||||
"<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%ld</b></font></td>"
|
||||
"</tr>\n"
|
||||
"<tr>\n"
|
||||
"<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b># Entries:</b></font></td>"
|
||||
"<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%ld</b></font></td>"
|
||||
"</tr>\n"
|
||||
"<tr>\n"
|
||||
"<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Full Mark:</b></font></td>"
|
||||
"<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%ld</b></font></td>"
|
||||
"</tr>\n"
|
||||
"<tr>\n"
|
||||
"<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Full Mark Time:</b></font></td>"
|
||||
"<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%s</b></font></td>"
|
||||
"</tr>\n"
|
||||
"</table>\n</p>\n",
|
||||
util_ldap_cache->size,
|
||||
util_ldap_cache->maxentries,
|
||||
util_ldap_cache->numentries,
|
||||
util_ldap_cache->fullmark,
|
||||
date_str), r);
|
||||
|
||||
ap_rputs("<p>\n"
|
||||
"<table border='0'>\n"
|
||||
"<tr bgcolor='#000000'>\n"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>LDAP URL</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Size</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Max Entries</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b># Entries</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Full Mark</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Full Mark Time</b></font></td>"
|
||||
"</tr>\n", r
|
||||
);
|
||||
for (i=0; i < util_ldap_cache->size; ++i) {
|
||||
for (p = util_ldap_cache->nodes[i]; p != NULL; p = p->next) {
|
||||
|
||||
(*util_ldap_cache->display)(r, util_ldap_cache, p->payload);
|
||||
}
|
||||
}
|
||||
ap_rputs("</table>\n</p>\n", r);
|
||||
|
||||
|
||||
break;
|
||||
case 's':
|
||||
ap_rputs("<p>\n"
|
||||
"<table border='0'>\n"
|
||||
"<tr bgcolor='#000000'>\n"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>LDAP Filter</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>User Name</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Last Bind</b></font></td>"
|
||||
"</tr>\n", r
|
||||
);
|
||||
for (i=0; i < n->search_cache->size; ++i) {
|
||||
for (p = n->search_cache->nodes[i]; p != NULL; p = p->next) {
|
||||
|
||||
(*n->search_cache->display)(r, n->search_cache, p->payload);
|
||||
}
|
||||
}
|
||||
ap_rputs("</table>\n</p>\n", r);
|
||||
break;
|
||||
case 'c':
|
||||
ap_rputs("<p>\n"
|
||||
"<table border='0'>\n"
|
||||
"<tr bgcolor='#000000'>\n"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>DN</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Attribute</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Value</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Last Compare</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Result</b></font></td>"
|
||||
"</tr>\n", r
|
||||
);
|
||||
for (i=0; i < n->compare_cache->size; ++i) {
|
||||
for (p = n->compare_cache->nodes[i]; p != NULL; p = p->next) {
|
||||
|
||||
(*n->compare_cache->display)(r, n->compare_cache, p->payload);
|
||||
}
|
||||
}
|
||||
ap_rputs("</table>\n</p>\n", r);
|
||||
break;
|
||||
case 'd':
|
||||
ap_rputs("<p>\n"
|
||||
"<table border='0'>\n"
|
||||
"<tr bgcolor='#000000'>\n"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Require DN</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Actual DN</b></font></td>"
|
||||
"</tr>\n", r
|
||||
);
|
||||
for (i=0; i < n->dn_compare_cache->size; ++i) {
|
||||
for (p = n->dn_compare_cache->nodes[i]; p != NULL; p = p->next) {
|
||||
|
||||
(*n->dn_compare_cache->display)(r, n->dn_compare_cache, p->payload);
|
||||
}
|
||||
}
|
||||
ap_rputs("</table>\n</p>\n", r);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
ap_rputs("<p>\n"
|
||||
"<table border='0'>\n"
|
||||
"<tr bgcolor='#000000'>\n"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Cache Name</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Entries</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Avg. Chain Len.</b></font></td>"
|
||||
"<td colspan='2'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Hits</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Ins/Rem</b></font></td>"
|
||||
"<td colspan='2'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Purges</b></font></td>"
|
||||
"<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Avg Purge Time</b></font></td>"
|
||||
"</tr>\n", r
|
||||
);
|
||||
|
||||
|
||||
id1 = apr_psprintf(pool, argfmt, "main", 0, 0);
|
||||
buf = util_ald_cache_display_stats(r, st->util_ldap_cache, "LDAP URL Cache", id1);
|
||||
|
||||
for (i=0; i < util_ldap_cache->size; ++i) {
|
||||
for (p = util_ldap_cache->nodes[i],j=0; p != NULL; p = p->next,j++) {
|
||||
|
||||
n = (util_url_node_t *)p->payload;
|
||||
|
||||
t1 = apr_psprintf(pool, "%s (Searches)", n->url);
|
||||
t2 = apr_psprintf(pool, "%s (Compares)", n->url);
|
||||
t3 = apr_psprintf(pool, "%s (DNCompares)", n->url);
|
||||
id1 = apr_psprintf(pool, argfmt, "srch", i, j);
|
||||
id2 = apr_psprintf(pool, argfmt, "cmpr", i, j);
|
||||
id3 = apr_psprintf(pool, argfmt, "dncp", i, j);
|
||||
|
||||
buf = apr_psprintf(pool, "%s\n\n"
|
||||
"%s\n\n"
|
||||
"%s\n\n"
|
||||
"%s\n\n",
|
||||
buf,
|
||||
util_ald_cache_display_stats(r, n->search_cache, t1, id1),
|
||||
util_ald_cache_display_stats(r, n->compare_cache, t2, id2),
|
||||
util_ald_cache_display_stats(r, n->dn_compare_cache, t3, id3)
|
||||
);
|
||||
}
|
||||
}
|
||||
ap_rputs(buf, r);
|
||||
ap_rputs("</table>\n</p>\n", r);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif /* APR_HAS_LDAP */
|
Reference in New Issue
Block a user