/*
 * This file implements the SNMP-SET requirements of the 
 * COVALENT-APACHE-MPM-MIB module.
 * $Id: mpm-write.c 8676 2008-01-17 23:11:17Z ispringer $
 */

/* General includes */
#include <stdio.h>
#include <sys/types.h>

/* Apache includes */
#include <httpd.h>
#include <http_log.h>
#include <http_config.h>
#include <scoreboard.h>
#include <ap_mpm.h>

/* 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 "covalent-snmp-config.h"
#define APACHE_MPM_MIB_PRIVATE
#include "apache-mpm-mib.h"


#ifdef COVALENT_APACHE_MPM_MIB_WRITE

int shadow_daemons_limit;
int shadow_daemons_min_free;
int shadow_daemons_max_free;
int shadow_max_requests_per_child;

int
write_ctApacheMPMEntry(int action,
    unsigned char *var_val, unsigned char var_val_type, size_t var_val_len,
    unsigned char *statP, oid *name, size_t name_len)
{
int column = name[ 11 ];
int hard_server_limit;
int hard_thread_limit;

ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "ACTION %d COLUMN %d ->%d ", action, column, *((unsigned long *) var_val));
    if (var_val_type != ASN_UNSIGNED) {
        return SNMP_ERR_WRONGTYPE;
    }

    if (var_val_len > sizeof(int)) {
        return(SNMP_ERR_WRONGLENGTH);
    }

    ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &hard_server_limit);
    ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &hard_thread_limit);

    switch (action) {
    case RESERVE1:
        switch(column) {
        case CTAPACHEMPMMAXDAEMONS:
            shadow_daemons_limit = *((unsigned long *) var_val);
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMAXTHREADS:
            return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMINSPAREDAEMONS:
            shadow_daemons_min_free = *((unsigned long *) var_val);
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMINSPARETHREADS:
            return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMAXSPAREDAEMONS:
            shadow_daemons_max_free = *((unsigned long *) var_val);
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMAXSPARETHREADS:
            return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMAXREQUESTPERDAEMON:
            shadow_max_requests_per_child = *((unsigned long *) var_val);
            return(SNMP_ERR_NOERROR);
        default:
            return(SNMP_ERR_NOTWRITABLE);
        }
    case RESERVE2:
        switch(column) {
        case CTAPACHEMPMMAXDAEMONS:
            if ((shadow_daemons_limit < 1) ||
                (hard_server_limit < shadow_daemons_limit)) {
                return(SNMP_ERR_WRONGVALUE);
            }
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMAXTHREADS:
            return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMINSPAREDAEMONS:
            if ((shadow_daemons_min_free < 1) ||
                (hard_server_limit < shadow_daemons_min_free)) {
                return SNMP_ERR_WRONGVALUE;
            }
            if (shadow_daemons_min_free > shadow_daemons_max_free) {
                return(SNMP_ERR_INCONSISTENTVALUE);
            }
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMINSPARETHREADS:
            return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMAXSPAREDAEMONS:
            if ((shadow_daemons_max_free < 1) ||
                (hard_server_limit < shadow_daemons_max_free)) {
                return SNMP_ERR_WRONGVALUE;
            }
            if (shadow_daemons_min_free > shadow_daemons_max_free) {
                return(SNMP_ERR_INCONSISTENTVALUE);
            }
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMAXSPARETHREADS:
            return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMAXREQUESTPERDAEMON:
            if (shadow_max_requests_per_child < 0) {
                return SNMP_ERR_WRONGVALUE;
            }
            return(SNMP_ERR_NOERROR);
        default:
            return(SNMP_ERR_NOTWRITABLE);
        }
    case COMMIT:
        switch(column) { 
        case CTAPACHEMPMMAXDAEMONS:
            ap_scoreboard_image->global.ap_daemons_limit =
                                        shadow_daemons_limit;
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMAXTHREADS:
            return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMINSPAREDAEMONS:
            ap_scoreboard_image->global.ap_daemons_min_free =
                                        shadow_daemons_min_free;
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMINSPARETHREADS:
	    return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMAXSPAREDAEMONS:
            ap_scoreboard_image->global.ap_daemons_max_free =
                                        shadow_daemons_max_free;
            return(SNMP_ERR_NOERROR);
        case CTAPACHEMPMMAXSPARETHREADS:
	    return(SNMP_ERR_NOTWRITABLE);
        case CTAPACHEMPMMAXREQUESTPERDAEMON:
            ap_scoreboard_image->global.ap_max_requests_per_child =
                                        shadow_max_requests_per_child;
            return(SNMP_ERR_NOERROR);
        default:
            return(SNMP_ERR_NOTWRITABLE);
        }
    case FREE:
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS,
                        &shadow_daemons_limit);
        ap_mpm_query(AP_MPMQ_MIN_SPARE_DEAMONS,
                        &shadow_daemons_min_free);
        ap_mpm_query(AP_MPMQ_MAX_SPARE_DAEMONS,
                        &shadow_daemons_max_free);
        ap_mpm_query(AP_MPMQ_MAX_REQUESTS_DEAMON,
                        &shadow_max_requests_per_child);
    }
    return SNMP_ERR_NOERROR;
}

#endif /* COVALENT_APACHE_MPM_MIB_WRITE */
