/*
 * This module implements for the COVALENT-APACHE-MODULES-MIB module.
 * $Id: module-table.c 8676 2008-01-17 23:11:17Z ispringer $
 */
#include <stdio.h>
#include <sys/types.h>

/* Apache includes */
#define CORE_PRIVATE
#include <httpd.h>
#include <http_config.h>

/* UCD-SNMP includes */
#include <ucd-snmp-config.h>
#include <asn1.h>
#include <snmp.h>
#include <snmp_api.h>
#include <snmp_impl.h>
#include <snmp_debug.h>
#include <snmp_vars.h>
#include <var_struct.h>

#include "covalent-snmp-config.h"
#include "snmpcommon/snmpcommon.h"
#include "apache-modules-mib.h"

#define CTMODULESNAME                    2
#define CTMODULESVERSION                 3
#define CTMODULESMINORVERSION            4
#define CTMODULESMAGICNUMBER             5
#define CTMODULESHOOKS                   6


#ifdef COVALENT_APACHE_MODULES_MIB

#define SET_BIT(bit)    (0x80 >> (bit % 8))
#ifndef SNMP_MIN
#define SNMP_MIN(a,b)   (((a)<(b)) ? (a) : (b))
#endif

#define NEXT    FALSE
#define EXACT   TRUE
#define INDEX   2

module *
get_ctModuleIndex(struct variable *vp,
        oid *name, size_t *namelength,
        int exact, module *module_ptr)
{
oid *index;

    index = &(vp->name[ vp->namelen++ ]);
    *index = 1;
    /* Walk through the list to get the correct entry */
    while (module_ptr) {
        if (exact == NEXT) {
            if (0 > snmp_oid_compare(name, *namelength, vp->name, vp->namelen)) {
                return(module_ptr);
            }
        } else if (exact == EXACT) {
            if (0 == snmp_oid_compare(name, *namelength, vp->name, vp->namelen)) {
                return(module_ptr);
            }
        } else if (exact == INDEX) {
            if (0 >= snmp_oid_compare(name, SNMP_MIN(*namelength,vp->namelen),
                            vp->name, SNMP_MIN(*namelength, vp->namelen))) {
                return(module_ptr);
            }
        }
        (*index)++;
        module_ptr = module_ptr->next;
    }
    return(NULL);
}

static unsigned char *
read_ctModulesEntry(struct variable *vp,
    oid     *name,
    size_t  *length,
    int     exact,
    size_t  *var_len,
    WriteMethod **write_method)
{
module *mod_ptr;

    vp->name[ vp->namelen++ ] = get_appl_index();
    mod_ptr = get_ctModuleIndex(vp, name, length, exact, ap_top_module);
    if (!mod_ptr) {
	return(NULL);
    }

    *length = vp->namelen;
    memcpy( (char *)name,(char *)vp->name, *length * sizeof(oid));
    *write_method = 0;
    *var_len = sizeof(long);

    switch (vp->magic) {
    case CTMODULESNAME:
        *var_len = strlen(mod_ptr->name);
        return (unsigned char *) mod_ptr->name;
    case CTMODULESVERSION:
	long_return = mod_ptr->version;
        return (unsigned char *) &long_return;
    case CTMODULESMINORVERSION:
        long_return = mod_ptr->minor_version;
        return (unsigned char *) &long_return;
    case CTMODULESMAGICNUMBER:
        long_return = mod_ptr->magic;
        return (unsigned char *) &long_return;
    case CTMODULESHOOKS:
	return_buf[0] = 0;
	return_buf[1] = 0;
	return_buf[2] = 0;
	if (mod_ptr->create_dir_config) {
	     return_buf[0] |= SET_BIT(1);
        }
	if (mod_ptr->merge_dir_config) {
	     return_buf[0] |= SET_BIT(2);
        }
	if (mod_ptr->create_server_config) {
	     return_buf[0] |= SET_BIT(3);
        }
	if (mod_ptr->merge_server_config) {
	     return_buf[0] |= SET_BIT(4);
        }
	if (mod_ptr->cmds) {
	     return_buf[0] |= SET_BIT(5);
        }
        if (mod_ptr->rewrite_args) {
            return_buf[2] |= SET_BIT(18);
        }
        if (mod_ptr->register_hooks) {
            return_buf[2] |= SET_BIT(19);
        }
        *var_len = 3;
        return (unsigned char *) return_buf;
    default:
         ERROR_MSG("");
    }

    return NULL;
}


static oid ctModulesEntry_oid[] = {1, 3, 6, 1, 4, 1, 6100, 6, 1, 1, 1};
struct variable2 ctModulesEntry_variables[] = {
    { CTMODULESNAME, ASN_OCTET_STR, RONLY, read_ctModulesEntry, 1, {2} },
    { CTMODULESVERSION, ASN_UNSIGNED, RONLY, read_ctModulesEntry, 1, {3} },
    { CTMODULESMINORVERSION, ASN_UNSIGNED, RONLY, read_ctModulesEntry, 1, {4} },
    { CTMODULESMAGICNUMBER, ASN_UNSIGNED, RONLY, read_ctModulesEntry, 1, {5} },
    { CTMODULESHOOKS, ASN_OCTET_STR, RONLY, read_ctModulesEntry, 1, {6} },
};


void init_covalent_apache_modules_group()
{
    REGISTER_MIB("modules-mib/ctModulesTable", ctModulesEntry_variables, variable2, ctModulesEntry_oid);
};


#endif /* COVALENT_APACHE_MODULES_MIB */

