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

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

/* Conductor module includes */
#include "covalent-snmp-config.h"
#include "ietf-mibs/snmp-generic.h"
#include "covalent-snmp-logging.h"
#include "covalent-snmp.h"
#include "covalent-snmp-sconfig.h"
#include "ietf-mibs/www-mib-utils.h"
#include "covalent-mibs/resp-notify-mib.h"

#include "logging.h"

extern module snmp_agt_module;
extern server_rec *www_services; /* www service records */

covalent_snmp_logpath_t logpath;

int
snmp_generic_logger(snmp_generic_log_record *data) 
{
    return(sendto(logpath.socket, (char *)data, sizeof(snmp_generic_log_record), 0,
                (struct sockaddr *)&logpath.address, logpath.address_size));
}

void open_logpath(int apache_state, server_rec *s)
{
/*    if (apache_state == 1) { */
        logpath.socket = socket(AF_INET, SOCK_DGRAM, 0);
        if (logpath.socket < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, s,
                    "SNMP: Cannot open 'log-path' socket (exiting)\n");
	    exit(1);
        }
        memset(&logpath.address, 0, sizeof(logpath.address));
        logpath.address.sin_family = AF_INET;
        logpath.address.sin_addr.s_addr = inet_addr("127.0.0.1");
        logpath.address.sin_port = htons(0);
        logpath.address_size = sizeof(logpath.address);
        if (bind(logpath.socket, (struct sockaddr *)&logpath.address,
                                    logpath.address_size) < 0){
            ap_log_error(APLOG_MARK, APLOG_ERR, s,
                    "SNMP: Cannot bind 'log-path' socket (exiting)\n");
	    exit(1);
        }
        if (getsockname(logpath.socket, (struct sockaddr *)&logpath.address,
                                  &logpath.address_size)) {
	    ap_log_error(APLOG_MARK, APLOG_ERR, s,
		    "SNMP: Cannot retrieve 'log-path' address (exiting)\n");
	    exit(1);
        }
        shared_store("logpath", &logpath, sizeof(logpath));
/*    } else if (apache_state > 1) {
        shared_fetch("logpath", &logpath, sizeof(logpath));
    } */
}

static int
external_log_sinks(snmp_generic_log_record *log_record)
{
covalent_snmp_sconfig *sconf_ptr;
array_header *external_subtrees;
external_mib_subtree *subtree;
int i;

    sconf_ptr = (covalent_snmp_sconfig *)
                ap_get_module_config(www_services->module_config,
                        &snmp_agt_module);
    external_subtrees = sconf_ptr->external_mib_subtrees;
    subtree = (external_mib_subtree *) external_subtrees->elts;
    for (i = 0 ; i < external_subtrees->nelts ; i++, subtree++) {
       if (subtree->logging_sink) {
            if (subtree->logging_sink(log_record)) {
                return(0);
            }
	}
    }
    return(0);
}

int
snmp_generic_log_sink(int socket)
{
snmp_generic_log_record log_record;

    if (read(socket, &log_record, sizeof(log_record)) != sizeof(log_record)) {
        return(!OK);
    }
    switch (log_record.type) {
        case STARTUP:
            /* At this phase we can ignore these. */
            break;
        case WWW:
            /* For the WWW type we need to update the www-mib statistics   */
            /* and check wheter to send a notification for a www response. */
#ifdef WWW_MIB
            update_www_access_statistics(&(log_record.data.www));
#endif /* WWW_MIB */
#ifdef COVALENT_RESP_NOTIFY_MIB
            generate_ctNotifyResponse_notification(&(log_record.data.www));
#endif /* COVALENT_RESP_NOTIFY_MIB */
            break;
        default:
            /* Do all external defined log sinks. */
            external_log_sinks(&log_record);
            break;
    }
    return(OK);
}

