/*
 * This module implements for the COVALENT-APACHE-MODULES-MIB module.
 * $Id: apache-modules-mib.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 "apache-modules-mib.h"

#define CAMODULESNAME                    2
#define CAMODULESVERSION                 3
#define CAMODULESMINORVERSION            4
#define CAMODULESMAGICNUMBER             5
#define CAMODULESHOOKS                   6

#define SET_BIT(bit)    (0x80 >> (bit % 8))

#ifdef COVALENT_APACHE_MODULES_MIB

int
get_module_count()
{
int count = 0;
module *mod = top_module;

    while (mod) {
	count++;
	mod = mod->next;
    }
    return(count);
}

module *
get_caModuleIndex(struct variable *vp,
	oid *name, size_t *namelength,
	oid *newname, size_t *newname_length,
	int exact)
{
oid *ptr;
module *module_ptr;
int result;

    /* setup fist module record, newname and index (1) */
    module_ptr = top_module;
    *newname_length = vp->namelen;
    memcpy((char *)newname, (char *)vp->name, *newname_length * sizeof(oid));
    ptr = &(newname[ (*newname_length)++ ]);
    *ptr = 1;
    /* Walk through the list to get the correct entry */
    while (module_ptr) {
        result = snmp_oid_compare(name, *namelength, newname, *newname_length);
        if ((exact && (result == 0)) || (!exact && (result < 0))) {
             return(module_ptr);
        }
	(*ptr)++;
        module_ptr = module_ptr->next;
    }
    return(NULL);
}

/*
 * Read methods for groups of scalars and tables:
 */

static unsigned char *
read_caModulesEntry(struct variable *vp,
    oid     *name,
    size_t  *length,
    int     exact,
    size_t  *var_len,
    WriteMethod **write_method)
{
oid newname[ MAX_OID_LEN ];
size_t newname_length;
module *mod_ptr;

    mod_ptr = get_caModuleIndex(vp, name, length, newname, &newname_length, exact);
    if (!mod_ptr) {
	return(NULL);
    }

    *length = newname_length;
    memcpy( (char *)name,(char *)newname, *length * sizeof(oid));
    *write_method = 0;
    *var_len = sizeof(long);

    switch (vp->magic) {

    case CAMODULESNAME:
        *var_len = strlen(mod_ptr->name);
        return (unsigned char *) mod_ptr->name;

    case CAMODULESVERSION:
	long_return = mod_ptr->version;
        return (unsigned char *) &long_return;
    case CAMODULESMINORVERSION:
        long_return = mod_ptr->minor_version;
        return (unsigned char *) &long_return;
    case CAMODULESMAGICNUMBER:
        long_return = mod_ptr->magic;
        return (unsigned char *) &long_return;
    case CAMODULESHOOKS:
	return_buf[0] = 0;
	return_buf[1] = 0;
	return_buf[2] = 0;
	if (mod_ptr->init) {
	     return_buf[0] = SET_BIT(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->handlers) {
	     return_buf[0] |= SET_BIT(6);
        }
	if (mod_ptr->translate_handler) {
	     return_buf[0] |= SET_BIT(7);
        }
	if (mod_ptr->ap_check_user_id) {
	     return_buf[1] |= SET_BIT(8);
        }
	if (mod_ptr->auth_checker) {
	     return_buf[1] |= SET_BIT(9);
        }
	if (mod_ptr->access_checker) {
	     return_buf[1] |= SET_BIT(10);
        }
	if (mod_ptr->type_checker) {
	     return_buf[1] |= SET_BIT(11);
        }
	if (mod_ptr->fixer_upper) {
	     return_buf[1] |= SET_BIT(12);
        }
	if (mod_ptr->logger) {
	     return_buf[1] |= SET_BIT(13);
        }
	if (mod_ptr->header_parser) {
	     return_buf[1] |= SET_BIT(14);
        }
	if (mod_ptr->child_init) {
	     return_buf[1] |= SET_BIT(15);
        }
	if (mod_ptr->child_exit) {
	     return_buf[2] |= SET_BIT(16);
        }
	if (mod_ptr->post_read_request) {
	     return_buf[2] |= SET_BIT(17);
        }
        *var_len = 3;
        return (unsigned char *) return_buf;
    default:
         ERROR_MSG("");
    }

    return NULL;
}


static oid caModulesEntry_oid[] = {1, 3, 6, 1, 4, 1, 6100, 6, 1, 1, 1};
struct variable2 caModulesEntry_variables[] = {
    { CAMODULESNAME, ASN_OCTET_STR, RONLY, read_caModulesEntry, 1, {2} },
    { CAMODULESVERSION, ASN_UNSIGNED, RONLY, read_caModulesEntry, 1, {3} },
    { CAMODULESMINORVERSION, ASN_UNSIGNED, RONLY, read_caModulesEntry, 1, {4} },
    { CAMODULESMAGICNUMBER, ASN_UNSIGNED, RONLY, read_caModulesEntry, 1, {5} },
    { CAMODULESHOOKS, ASN_OCTET_STR, RONLY, read_caModulesEntry, 1, {6} },
};


void init_covalent_apache_modules_mib()
{
    REGISTER_MIB("modules-mib/caModulesTable", caModulesEntry_variables, variable2, caModulesEntry_oid);
#ifdef USING_MIBII_SYSORTABLE_MODULE
  register_sysORTable(caModulesEntry_oid, 8, "The apache modules MIB module");
#endif
};


#endif /* COVALENT_APACHE_MODULES_MIB */

