/*
 * Note: this file originally auto-generated by mib2c using
 *        : mib2c.create-dataset.conf,v 5.2 2002/07/17 14:41:53 dts12 Exp $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "mteTriggerTable.h"
#include "mteEventTable.h"
#include "mteEventNotificationTable.h"
#include "mteObjectsTable.h"

static netsnmp_table_data_set *table_set = NULL;

/** Initialize the mteEventTable table by defining its contents and how it's structured */
void
initialize_table_mteEventTable(void)
{
    static oid      mteEventTable_oid[] =
        { 1, 3, 6, 1, 2, 1, 88, 1, 4, 2 };
    size_t          mteEventTable_oid_len = OID_LENGTH(mteEventTable_oid);

    /*
     * create the table structure itself 
     */
    table_set = netsnmp_create_table_data_set("mteEventTable");

    /*
     * comment this out or delete if you don't support creation of new rows 
     */
    table_set->allow_creation = 1;
    /* mark the row status column */
    table_set->rowstatus_column = COLUMN_MTEEVENTENTRYSTATUS;

    /***************************************************
     * Adding indexes
     */
    DEBUGMSGTL(("initialize_table_mteEventTable",
                "adding indexes to table mteEventTable\n"));
    netsnmp_table_set_add_indexes(table_set,
                                  ASN_OCTET_STR,   /* index: mteOwner */
                                  ASN_PRIV_IMPLIED_OCTET_STR, /* index: mteEventName */
                                  0);

    DEBUGMSGTL(("initialize_table_mteEventTable",
                "adding column types to table mteEventTable\n"));
    netsnmp_table_set_multi_add_default_row(table_set,
                                            COLUMN_MTEEVENTNAME,
                                            ASN_OCTET_STR, 0, NULL, 0,
                                            COLUMN_MTEEVENTCOMMENT,
                                            ASN_OCTET_STR, 1, NULL, 0,
                                            COLUMN_MTEEVENTACTIONS,
                                            ASN_OCTET_STR, 1, NULL, 0,
                                            COLUMN_MTEEVENTENABLED,
                                            ASN_INTEGER, 1, NULL, 0,
                                            COLUMN_MTEEVENTENTRYSTATUS,
                                            ASN_INTEGER, 1, NULL, 0, 0);

    /* keep index values around for comparisons later */
    table_set->table->store_indexes = 1;
    /*
     * registering the table with the master agent 
     */
    /*
     * note: if you don't need a subhandler to deal with any aspects
     * of the request, change mteEventTable_handler to "NULL" 
     */
    netsnmp_register_table_data_set(netsnmp_create_handler_registration
                                    ("mteEventTable",
                                     mteEventTable_handler,
                                     mteEventTable_oid,
                                     mteEventTable_oid_len,
                                     HANDLER_CAN_RWRITE), table_set, NULL);
}

/** Initializes the mteEventTable module */
void
init_mteEventTable(void)
{

    /*
     * here we initialize all the tables we're planning on supporting 
     */
    initialize_table_mteEventTable();

    snmpd_register_config_handler("notificationEvent", parse_notificationEvent,
                                  NULL,
                                  "notificationEvent NAME TRAP_OID [[-w] EXTRA_OID ...]");

    snmpd_register_config_handler("linkUpDownNotifications",
                                  parse_linkUpDownNotifications,
                                  NULL,
                                  "linkUpDownNotifications (yes|no)");
}

/** handles requests for the mteEventTable table, if anything else needs to be done */
int
mteEventTable_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests)
{
    /*
     * perform anything here that you need to do.  The requests have
     * already been processed by the master table_dataset handler, but
     * this gives you chance to act on the request in some other way
     * if need be. 
     */

    /* XXX: on rowstatus = destroy, remove the corresponding rows from the
       other tables: snmpEventNotificationTable and the set table */
    return SNMP_ERR_NOERROR;
}

void
parse_linkUpDownNotifications(const char *token, char *line) {
    if (strncmp(line, "y", 1) == 0) {
        parse_notificationEvent("notificationEvent", "linkUpTrap   	 linkUp     ifIndex ifAdminStatus ifOperStatus");
        parse_notificationEvent("notificationEvent", "linkDownTrap 	 linkDown   ifIndex ifAdminStatus ifOperStatus");

        parse_simple_monitor("monitor", "-r 60 -e linkUpTrap \"Generate linkUp\" ifOperStatus != 2");
        parse_simple_monitor("monitor", "-r 60 -e linkDownTrap \"Generate linkDown\" ifOperStatus == 2");
    }
}

void
parse_notificationEvent(const char *token, char *line) {
    char            name_buf[64];
    char            oid_name_buf[SPRINT_MAX_LEN];
    oid             oid_buf[MAX_OID_LEN];
    size_t          oid_buf_len = MAX_OID_LEN;
    int             wild = 1;
    netsnmp_table_row *row;
    long tlong;
    char tc;

    /* get the owner */
    const char *owner = "snmpd.conf";

    /* get the name */
    char *cp = copy_nword(line, name_buf, SPRINT_MAX_LEN);

    if (!cp || name_buf[0] == '\0') {
        config_perror("syntax error.");
        return;
    }

    for(row = table_set->table->first_row; row; row = row->next) {
        if (strcmp(row->indexes->val.string, owner) == 0 &&
            strcmp(row->indexes->next_variable->val.string,
                   name_buf) == 0) {
            config_perror("An eventd by that name has already been defined.");
            return;
        }
    }

    /* now, get all the trap oid */
    cp = copy_nword(cp, oid_name_buf, SPRINT_MAX_LEN);

    if (oid_name_buf[0] == '\0') {
        config_perror("syntax error.");
        return;
    }
    if (!snmp_parse_oid(oid_name_buf, oid_buf, &oid_buf_len)) {
        snmp_log(LOG_ERR,"namebuf: %s\n",oid_name_buf);
        config_perror("unable to parse trap oid");
        return;
    }

    /*
     * add to the mteEventNotificationtable to point to the
     * notification and the objects.
     */
    row = netsnmp_create_table_data_row();

    /* indexes */
    netsnmp_table_row_add_index(row, ASN_OCTET_STR, owner, strlen(owner));
    netsnmp_table_row_add_index(row, ASN_PRIV_IMPLIED_OCTET_STR,
                                name_buf, strlen(name_buf));


    /* columns */
    netsnmp_set_row_column(row, COLUMN_MTEEVENTNOTIFICATION, ASN_OBJECT_ID,
                           (char *) oid_buf, oid_buf_len * sizeof(oid));
    netsnmp_set_row_column(row, COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER,
                           ASN_OCTET_STR, owner, strlen(owner));
    netsnmp_set_row_column(row, COLUMN_MTEEVENTNOTIFICATIONOBJECTS,
                           ASN_OCTET_STR, name_buf, strlen(name_buf));

    netsnmp_table_data_add_row(mteEventNotif_table_set->table, row);

    /*
     * add to the mteEventTable to make it a notification to trigger
     * notification and the objects.
     */
    row = netsnmp_create_table_data_row();

    /* indexes */
    netsnmp_table_row_add_index(row, ASN_OCTET_STR, owner, strlen(owner));
    netsnmp_table_row_add_index(row, ASN_PRIV_IMPLIED_OCTET_STR,
                                name_buf, strlen(name_buf));


    /* columns */
    tc = (u_char)0x80;
    netsnmp_set_row_column(row, COLUMN_MTEEVENTACTIONS, ASN_OCTET_STR,
                           &tc, 1);
    tlong = MTETRIGGERENABLED_TRUE;
    netsnmp_set_row_column(row, COLUMN_MTEEVENTENABLED,
                           ASN_INTEGER, (char *) &tlong, sizeof(tlong));
    tlong = RS_ACTIVE;
    netsnmp_set_row_column(row, COLUMN_MTEEVENTENTRYSTATUS,
                           ASN_INTEGER, (char *) &tlong, sizeof(tlong));

    netsnmp_table_data_add_row(table_set->table, row);
    
    /*
     * now all the objects to put into the trap's object row
     */
    while(cp) {
        cp = copy_nword(cp, oid_name_buf, SPRINT_MAX_LEN);
        if (strcmp(oid_name_buf, "-w") == 0) {
            wild = 0;
            continue;
        }
        oid_buf_len = MAX_OID_LEN;
        if (!snmp_parse_oid(oid_name_buf, oid_buf, &oid_buf_len)) {
            config_perror("unable to parse an object oid");
            return;
        }
        mte_add_object_to_table("snmpd.conf", name_buf,
                                oid_buf, oid_buf_len, wild);
        wild = 1;
    }
}

/*
 * send trap 
 */
void
run_mte_events(struct mteTriggerTable_data *item,
               oid * name_oid, size_t name_oid_len,
               const char *eventobjowner, const char *eventobjname)
{
    static oid      objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };     /* snmpTrapIOD.0 */

    netsnmp_variable_list *var_list = NULL;

    netsnmp_table_row *row, *notif_row;
    netsnmp_table_data_set_storage *col1, *tc, *no, *noo;

    for(row = table_set->table->first_row; row; row = row->next) {
        if (strcmp(row->indexes->val.string, eventobjowner) == 0 &&
            strcmp(row->indexes->next_variable->val.string,
                   eventobjname) == 0) {
            /* run this event */
            col1 = (netsnmp_table_data_set_storage *) row->data;
            
            tc = netsnmp_table_data_set_find_column(col1,
                                                    COLUMN_MTEEVENTACTIONS);
            if (!tc->data.bitstring[0] & 0x80) {
                /* not a notification.  next! (XXX: do sets) */
                continue;
            }

            tc = netsnmp_table_data_set_find_column(col1,
                                                    COLUMN_MTEEVENTENABLED);
            if (*(tc->data.integer) != 1) {
                /* not enabled.  next! */
                continue;
            }

            if (!mteEventNotif_table_set) {
                /* no notification info */
                continue;
            }

            /* send the notification */
            var_list = NULL;

            /* XXX: get notif information */
            for(notif_row = mteEventNotif_table_set->table->first_row;
                notif_row; notif_row = notif_row->next) {
                if (strcmp(notif_row->indexes->val.string,
                           eventobjowner) == 0 &&
                    strcmp(notif_row->indexes->next_variable->val.string,
                           eventobjname) == 0) {

                    /* run this event */
                    col1 = (netsnmp_table_data_set_storage *) notif_row->data;
            
                    tc = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATION);
                    no = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATIONOBJECTS);
                    noo = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER);
                    if (!tc)
                        continue; /* no notification to be had. XXX: return? */
                    
                    /*
                     * snmpTrap oid 
                     */
                    snmp_varlist_add_variable(&var_list, objid_snmptrap,
                                              sizeof(objid_snmptrap) /
                                              sizeof(oid),
                                              ASN_OBJECT_ID,
                                              (u_char *) tc->data.objid,
                                              tc->data_len);

                    /* XXX: add objects from the mteObjectsTable */
                    DEBUGMSGTL(("mteEventTable:send_events", "no: %x, no->data: %s", no, no->data.string));
                    DEBUGMSGTL(("mteEventTable:send_events", "noo: %x, noo->data: %s", noo, noo->data.string));
                    DEBUGMSGTL(("mteEventTable:send_events", "name_oid: %x",name_oid));
                    if (no && no->data.string &&
                        noo && noo->data.string && name_oid) {
                        char *tmpowner =
                            netsnmp_strdup_and_null(noo->data.string,
                                                    noo->data_len);
                        char *tmpname =
                            netsnmp_strdup_and_null(no->data.string,
                                                    no->data_len);

                        DEBUGMSGTL(("mteEventTable:send_events", "Adding objects for owner=%s name=%s", tmpowner, tmpname));
                        mte_add_objects(var_list, item,
                                        tmpowner, tmpname, 
                                       name_oid + item->mteTriggerValueIDLen,
                                        name_oid_len - item->mteTriggerValueIDLen);
                        free(tmpowner);
                        free(tmpname);
                    }

                    DEBUGMSGTL(("mteEventTable:send_events", "sending an event "));
                    DEBUGMSGOID(("mteEventTable:send_events", tc->data.objid, tc->data_len / sizeof(oid)));
                    DEBUGMSG(("mteEventTable:send_events", "\n"));
                    
                    send_v2trap(var_list);
                    snmp_free_varbind(var_list);
                }
            }
        }
    }
}
