/*
 * DisMan Event MIB:
 *     Core implementation of the trigger handling behaviour
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "disman/event/mteTrigger.h"
#include "disman/event/mteEvent.h"

netsnmp_feature_child_of(disman_debugging, libnetsnmpmibs)
netsnmp_feature_child_of(mtetrigger, libnetsnmpmibs)
netsnmp_feature_child_of(mtetrigger_removeentry, mtetrigger)

netsnmp_tdata *trigger_table_data;

oid    _sysUpTime_instance[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
size_t _sysUpTime_inst_len   = OID_LENGTH(_sysUpTime_instance);

long mteTriggerFailures;

    /*
     * Initialize the container for the (combined) mteTrigger*Table,
     * regardless of which table initialisation routine is called first.
     */

void
init_trigger_table_data(void)
{
    DEBUGMSGTL(("disman:event:init", "init trigger container\n"));
    if (!trigger_table_data) {
        trigger_table_data = netsnmp_tdata_create_table("mteTriggerTable", 0);
        if (!trigger_table_data) {
            snmp_log(LOG_ERR, "failed to create mteTriggerTable");
            return;
        }
        DEBUGMSGTL(("disman:event:init", "create trigger container (%p)\n",
                                          trigger_table_data));
    }
    mteTriggerFailures = 0;
}


/** Initializes the mteTrigger module */
void
init_mteTrigger(void)
{
    init_trigger_table_data();

}

    /* ===================================================
     *
     * APIs for maintaining the contents of the (combined)
     *    mteTrigger*Table container.
     *
     * =================================================== */

#ifndef NETSNMP_FEATURE_REMOVE_DISMAN_DEBUGGING
void
_mteTrigger_dump(void)
{
    struct mteTrigger *entry;
    netsnmp_tdata_row *row;
    int i = 0;

    for (row = netsnmp_tdata_row_first(trigger_table_data);
         row;
         row = netsnmp_tdata_row_next(trigger_table_data, row)) {
        entry = (struct mteTrigger *)row->data;
        DEBUGMSGTL(("disman:event:dump", "TriggerTable entry %d: ", i));
        DEBUGMSGOID(("disman:event:dump", row->oid_index.oids, row->oid_index.len));
        DEBUGMSG(("disman:event:dump", "(%s, %s)",
                                         row->indexes->val.string,
                                         row->indexes->next_variable->val.string));
        DEBUGMSG(("disman:event:dump", ": %p, %p\n", row, entry));
        i++;
    }
    DEBUGMSGTL(("disman:event:dump", "TriggerTable %d entries\n", i));
}
#endif /* NETSNMP_FEATURE_REMOVE_DISMAN_DEBUGGING */

/*
 * Create a new row in the trigger table 
 */
netsnmp_tdata_row *
mteTrigger_createEntry(const char *mteOwner, char *mteTName, int fixed)
{
    struct mteTrigger *entry;
    netsnmp_tdata_row *row;
    size_t mteOwner_len = (mteOwner) ? strlen(mteOwner) : 0;
    size_t mteTName_len = (mteTName) ? strlen(mteTName) : 0;

    DEBUGMSGTL(("disman:event:table", "Create trigger entry (%s, %s)\n",
                                       mteOwner, mteTName));
    /*
     * Create the mteTrigger entry, and the
     * (table-independent) row wrapper structure...
     */
    entry = SNMP_MALLOC_TYPEDEF(struct mteTrigger);
    if (!entry)
        return NULL;

    row = netsnmp_tdata_create_row();
    if (!row) {
        SNMP_FREE(entry);
        return NULL;
    }
    row->data = entry;

    /*
     * ... initialize this row with the indexes supplied
     *     and the default values for the row...
     */
    if (mteOwner)
        memcpy(entry->mteOwner, mteOwner, mteOwner_len);
    netsnmp_table_row_add_index(row, ASN_OCTET_STR,
                                entry->mteOwner, mteOwner_len);
    if (mteTName)
        memcpy(entry->mteTName, mteTName, mteTName_len);
    netsnmp_table_row_add_index(row, ASN_PRIV_IMPLIED_OCTET_STR,
                                entry->mteTName, mteTName_len);

  /* entry->mteTriggerTest         = MTE_TRIGGER_BOOLEAN; */
    entry->mteTriggerValueID_len  = 2;  /* .0.0 */
    entry->mteTriggerFrequency    = 600;
    memcpy(entry->mteDeltaDiscontID, _sysUpTime_instance,
                              sizeof(_sysUpTime_instance));
    entry->mteDeltaDiscontID_len  =  _sysUpTime_inst_len;
    entry->mteDeltaDiscontIDType  = MTE_DELTAD_TTICKS;
    entry->flags                 |= MTE_TRIGGER_FLAG_SYSUPT;
    entry->mteTExTest             = (MTE_EXIST_PRESENT | MTE_EXIST_ABSENT);
    entry->mteTExStartup          = (MTE_EXIST_PRESENT | MTE_EXIST_ABSENT);
    entry->mteTBoolComparison     = MTE_BOOL_UNEQUAL;
    entry->flags                 |= MTE_TRIGGER_FLAG_BSTART;
    entry->mteTThStartup          = MTE_THRESH_START_RISEFALL;

    if (fixed)
        entry->flags |= MTE_TRIGGER_FLAG_FIXED;

    /*
     * ... and insert the row into the (common) table container
     */
    netsnmp_tdata_add_row(trigger_table_data, row);
    DEBUGMSGTL(("disman:event:table", "Trigger entry created\n"));
    return row;
}

#ifndef NETSNMP_FEATURE_REMOVE_MTETRIGGER_REMOVEENTRY
/*
 * Remove a row from the trigger table 
 */
void
mteTrigger_removeEntry(netsnmp_tdata_row *row)
{
    struct mteTrigger *entry;

    if (!row)
        return;                 /* Nothing to remove */
    entry = (struct mteTrigger *)
        netsnmp_tdata_remove_and_delete_row(trigger_table_data, row);
    if (entry) {
        mteTrigger_disable( entry );
        SNMP_FREE(entry);
    }
}
#endif /* NETSNMP_FEATURE_REMOVE_MTETRIGGER_REMOVEENTRY */

    /* ===================================================
     *
     * APIs for evaluating a trigger,
     *   and firing the appropriate event
     *
     * =================================================== */
const char *_ops[] = { "",
                "!=", /* MTE_BOOL_UNEQUAL      */
                "==", /* MTE_BOOL_EQUAL        */
                "<",  /* MTE_BOOL_LESS         */
                "<=", /* MTE_BOOL_LESSEQUAL    */
                ">",  /* MTE_BOOL_GREATER      */
                ">="  /* MTE_BOOL_GREATEREQUAL */  };

void
_mteTrigger_failure( /* int error, */ const char *msg )
{
    /*
     * XXX - Send an mteTriggerFailure trap
     *           (if configured to do so)
     */
    mteTriggerFailures++;
    snmp_log(LOG_ERR, "%s\n", msg );
    return;
}

void
mteTrigger_run( unsigned int reg, void *clientarg)
{
    struct mteTrigger *entry = (struct mteTrigger *)clientarg;
    netsnmp_variable_list *var, *vtmp;
    netsnmp_variable_list *vp1, *vp1_prev;
    netsnmp_variable_list *vp2, *vp2_prev;
    netsnmp_variable_list *dvar = NULL;
    netsnmp_variable_list *dv1  = NULL, *dv2 = NULL;
    netsnmp_variable_list sysUT_var;
    int  cmp = 0, n, n2;
    long value;
    const char *reason;

    if (!entry) {
        snmp_alarm_unregister( reg );
        return;
    }
    if (!(entry->flags & MTE_TRIGGER_FLAG_ENABLED ) ||
        !(entry->flags & MTE_TRIGGER_FLAG_ACTIVE  ) ||
        !(entry->flags & MTE_TRIGGER_FLAG_VALID  )) {
        return;
    }

    {
	extern netsnmp_agent_session *netsnmp_processing_set;
	if (netsnmp_processing_set) {
	    /*
	     * netsnmp_handle_request will not be responsive to our efforts to
	     *	Retrieve the requested MIB value(s)...
	     * so we will skip it.
	     * https://sourceforge.net/tracker/
	     *	index.php?func=detail&aid=1557406&group_id=12694&atid=112694
	     */
	    DEBUGMSGTL(("disman:event:trigger:monitor",
		"Skipping trigger (%s) while netsnmp_processing_set\n",
		entry->mteTName));
	    return;
	}
    }

    /*
     * Retrieve the requested MIB value(s)...
     */
    DEBUGMSGTL(( "disman:event:trigger:monitor", "Running trigger (%s)\n", entry->mteTName));
    var = (netsnmp_variable_list *)SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
    if (!var) {
        _mteTrigger_failure("failed to create mteTrigger query varbind");
        return;
    }
    snmp_set_var_objid( var, entry->mteTriggerValueID,
                             entry->mteTriggerValueID_len );
    if ( entry->flags & MTE_TRIGGER_FLAG_VWILD ) {
        n = netsnmp_query_walk( var, entry->session );
    } else {
        n = netsnmp_query_get(  var, entry->session );
    }
    if ( n != SNMP_ERR_NOERROR ) {
        DEBUGMSGTL(( "disman:event:trigger:monitor", "Trigger query (%s) failed: %d\n",
                           (( entry->flags & MTE_TRIGGER_FLAG_VWILD ) ? "walk" : "get"), n));
        _mteTrigger_failure( "failed to run mteTrigger query" );
        snmp_free_varbind(var);
        return;
    }

    /*
     * ... canonicalise the results (to simplify later comparisons)...
     */

    vp1 = var;                vp1_prev = NULL;
    vp2 = entry->old_results; vp2_prev = NULL;
    entry->count=0;
    while (vp1) {
           /*
            * Flatten various missing values/exceptions into a single form
            */ 
	switch (vp1->type) {
        case SNMP_NOSUCHINSTANCE:
        case SNMP_NOSUCHOBJECT:
        case ASN_PRIV_RETRY:   /* Internal only ? */
            vp1->type = ASN_NULL;
        }
           /*
            * Keep track of how many entries have been retrieved.
            */ 
           entry->count++;
        
           /*
            * Ensure previous and current result match
            *  (with corresponding entries in both lists)
            * and set the flags indicating which triggers are armed
            */ 
        if (vp2) {
            cmp = snmp_oid_compare(vp1->name, vp1->name_length,
                                   vp2->name, vp2->name_length);
            if ( cmp < 0 ) {
                /*
                 * If a new value has appeared, insert a matching
                 * dummy entry into the previous result list.
                 *
                 * XXX - check how this is best done.
                 */
                vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                if (!vtmp) {
                    _mteTrigger_failure(
                          "failed to create mteTrigger temp varbind");
                    snmp_free_varbind(var);
                    return;
                }
                vtmp->type = ASN_NULL;
                snmp_set_var_objid( vtmp, vp1->name, vp1->name_length );
                vtmp->next_variable = vp2;
                if (vp2_prev) {
                    vp2_prev->next_variable = vtmp;
                } else {
                    entry->old_results      = vtmp;
                }
                vp2_prev   = vtmp;
                vp1->index = MTE_ARMED_ALL;	/* XXX - plus a new flag */
                vp1_prev   = vp1;
                vp1        = vp1->next_variable;
            }
            else if ( cmp == 0 ) {
                /*
                 * If it's a continuing entry, just copy across the armed flags
                 */
                vp1->index = vp2->index;
                vp1_prev   = vp1;
                vp1        = vp1->next_variable;
                vp2_prev   = vp2;
                vp2        = vp2->next_variable;
            } else {
                /*
                 * If a value has just disappeared, insert a
                 * matching dummy entry into the current result list.
                 *
                 * XXX - check how this is best done.
                 *
                 */
                if ( vp2->type != ASN_NULL ) {
                    vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                    if (!vtmp) {
                        _mteTrigger_failure(
                                 "failed to create mteTrigger temp varbind");
                        snmp_free_varbind(var);
                        return;
                    }
                    vtmp->type = ASN_NULL;
                    snmp_set_var_objid( vtmp, vp2->name, vp2->name_length );
                    vtmp->next_variable = vp1;
                    if (vp1_prev) {
                        vp1_prev->next_variable = vtmp;
                    } else {
                        var                     = vtmp;
                    }
                    vp1_prev = vtmp;
                    vp2_prev = vp2;
                    vp2      = vp2->next_variable;
                } else {
                    /*
                     * But only if this entry has *just* disappeared.  If the
                     * entry from the last run was a dummy too, then remove it.
                     *   (leaving vp2_prev unchanged)
                     */
                    vtmp = vp2;
                    if (vp2_prev) {
                        vp2_prev->next_variable = vp2->next_variable;
                    } else {
                        entry->old_results      = vp2->next_variable;
                    }
                    vp2  = vp2->next_variable;
                    vtmp->next_variable = NULL;
                    snmp_free_varbind( vtmp );
                }
            }
        } else {
            /*
             * No more old results to compare.
             * Either all remaining values have only just been created ...
             *   (and we need to create dummy 'old' entries for them)
             */
            if ( vp2_prev ) {
                vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                if (!vtmp) {
                    _mteTrigger_failure(
                             "failed to create mteTrigger temp varbind");
                    snmp_free_varbind(var);
                    return;
                }
                vtmp->type = ASN_NULL;
                snmp_set_var_objid( vtmp, vp1->name, vp1->name_length );
                vtmp->next_variable     = vp2_prev->next_variable;
                vp2_prev->next_variable = vtmp;
                vp2_prev                = vtmp;
            }
            /*
             * ... or this is the first run through
             *   (and there were no old results at all)
             *
             * In either case, mark the current entry as armed and new.
             * Note that we no longer need to maintain 'vp1_prev'
             */
            vp1->index = MTE_ARMED_ALL;	/* XXX - plus a new flag */
            vp1        = vp1->next_variable;
        }
    }

    /*
     * ... and then work through these result(s), deciding
     *     whether or not to trigger the corresponding event.
     *
     *  Note that there's no point in evaluating Existence or
     *    Boolean tests if there's no corresponding event.
     *   (Even if the trigger matched, nothing would be done anyway).
     */
    if ((entry->mteTriggerTest & MTE_TRIGGER_EXISTENCE) &&
        (entry->mteTExEvent[0] != '\0' )) {
        /*
         * If we don't have a record of previous results,
         * this must be the first time through, so consider
         * the mteTriggerExistenceStartup tests.
         */
        if ( !entry->old_results ) {
            /*
             * With the 'present(0)' test, the trigger should fire
             *   for each value in the varbind list returned
             *   (whether the monitored value is wildcarded or not).
             */
            if (entry->mteTExTest & entry->mteTExStartup & MTE_EXIST_PRESENT) {
                for (vp1 = var; vp1; vp1=vp1->next_variable) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing initial existence test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire",
                                 " (present)\n"));;
                    entry->mteTriggerXOwner   = entry->mteTExObjOwner;
                    entry->mteTriggerXObjects = entry->mteTExObjects;
                    entry->mteTriggerFired    = vp1;
                    n = entry->mteTriggerValueID_len;
                    mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent, 
                                  entry, vp1->name+n, vp1->name_length-n);
                }
            }
            /*
             * An initial 'absent(1)' test only makes sense when
             *   monitoring a non-wildcarded OID (how would we know
             *   which rows of the table "ought" to exist, but don't?)
             */
            if (entry->mteTExTest & entry->mteTExStartup & MTE_EXIST_ABSENT) {
                if (!(entry->flags & MTE_TRIGGER_FLAG_VWILD) &&
                    var->type == ASN_NULL ) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing initial existence test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 var->name, var->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire",
                                 " (absent)\n"));;
                    entry->mteTriggerXOwner   = entry->mteTExObjOwner;
                    entry->mteTriggerXObjects = entry->mteTExObjects;
                    /*
                     * It's unclear what value the 'mteHotValue' payload
                     *  should take when a monitored instance does not
                     *  exist on startup. The only sensible option is
                     *  to report a NULL value, but this clashes with
                     * the syntax of the mteHotValue MIB object.
                     */
                    entry->mteTriggerFired    = var;
                    n = entry->mteTriggerValueID_len;
                    mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent, 
                                  entry, var->name+n, var->name_length-n);
                }
            }
        } /* !old_results */
            /*
             * Otherwise, compare the current set of results with
             * the previous ones, looking for changes.  We can
             * assume that the two lists match (see above).
             */
        else {
            for (vp1 = var, vp2 = entry->old_results;
                 vp1;
                 vp1=vp1->next_variable, vp2=vp2->next_variable) {

                /* Use this field to indicate that the trigger should fire */
                entry->mteTriggerFired = NULL;
                reason                 = NULL;

                if ((entry->mteTExTest & MTE_EXIST_PRESENT) &&
                    (vp1->type != ASN_NULL) &&
                    (vp2->type == ASN_NULL)) {
                    /* A new instance has appeared */
                    entry->mteTriggerFired = vp1;
                    reason = "(present)";

                } else if ((entry->mteTExTest & MTE_EXIST_ABSENT) &&
                    (vp1->type == ASN_NULL) &&
                    (vp2->type != ASN_NULL)) {

                    /*
                     * A previous instance has disappeared.
                     *
                     * It's unclear what value the 'mteHotValue' payload
                     *  should take when this happens - the previous
                     *  value (vp2), or a NULL value (vp1) ?
                     * NULL makes more sense logically, but clashes
                     *  with the syntax of the mteHotValue MIB object.
                     */
                    entry->mteTriggerFired = vp2;
                    reason = "(absent)";

                } else if ((entry->mteTExTest & MTE_EXIST_CHANGED) &&
                    ((vp1->val_len != vp2->val_len) || 
                     (memcmp( vp1->val.string, vp2->val.string,
                              vp1->val_len) != 0 ))) {
                    /*
                     * This comparison detects changes in *any* type
                     *  of value, numeric or string (or even OID).
                     *
                     * Unfortunately, the default 'mteTriggerFired'
                     *  notification payload can't report non-numeric
                     *  changes properly (see syntax of 'mteHotValue')
                     */
                    entry->mteTriggerFired = vp1;
                    reason = "(changed)";
                }
                if ( entry->mteTriggerFired ) {
                    /*
                     * One of the above tests has matched,
                     *   so fire the trigger.
                     */
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing existence test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire",
                                 " %s\n", reason));;
                    entry->mteTriggerXOwner   = entry->mteTExObjOwner;
                    entry->mteTriggerXObjects = entry->mteTExObjects;
                    n = entry->mteTriggerValueID_len;
                    mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent, 
                                  entry, vp1->name+n, vp1->name_length-n);
                }
            }
        } /* !old_results - end of else block */
    } /* MTE_TRIGGER_EXISTENCE */

    /*
     * We'll need sysUpTime.0 regardless...
     */
    DEBUGMSGTL(("disman:event:delta", "retrieve sysUpTime.0\n"));
    memset( &sysUT_var, 0, sizeof( netsnmp_variable_list ));
    snmp_set_var_objid( &sysUT_var, _sysUpTime_instance, _sysUpTime_inst_len );
    netsnmp_query_get(  &sysUT_var, entry->session );

    if (( entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN   ) ||
        ( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD )) {
        /*
         * Although Existence tests can work with any syntax values,
         * Boolean and Threshold tests are integer-only.  Ensure that
         * the returned value(s) are appropriate.
         *
         * Note that we only need to check the first value, since all
         *  instances of a given object should have the same syntax.
         */
        switch (var->type) {
        case ASN_INTEGER:
        case ASN_COUNTER:
        case ASN_GAUGE:
        case ASN_TIMETICKS:
        case ASN_UINTEGER:
        case ASN_COUNTER64:
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
        case ASN_OPAQUE_COUNTER64:
        case ASN_OPAQUE_U64:
        case ASN_OPAQUE_I64:
#endif
            /* OK */
            break;
        default:
            /*
             * Other syntax values can't be used for Boolean/Theshold
             * tests. Report this as an error, and then rotate the
             * results ready for the next run, (which will presumably
             * also detect this as an error once again!)
             */
            DEBUGMSGTL(( "disman:event:trigger:fire",
                         "Returned non-integer result(s): "));
            DEBUGMSGOID(("disman:event:trigger:fire",
                         var->name, var->name_length));
            DEBUGMSG((   "disman:event:trigger:fire",
                         " (boolean/threshold) %d\n", var->type));;
            snmp_free_varbind( entry->old_results );
            entry->old_results = var;
            return;
        }


        /*
         * Retrieve the discontinuity markers for delta-valued samples.
         * (including sysUpTime.0 if not specified explicitly).
         */
        if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) {

            if (!(entry->flags & MTE_TRIGGER_FLAG_SYSUPT)) {
                /*
                 * ... but only retrieve the configured discontinuity
                 *      marker(s) if they refer to something different.
                 */
                DEBUGMSGTL(( "disman:event:delta",
                             "retrieve discontinuity marker(s): "));
                DEBUGMSGOID(("disman:event:delta", entry->mteDeltaDiscontID,
                                               entry->mteDeltaDiscontID_len ));
                DEBUGMSG((   "disman:event:delta", " %s\n", 
                     (entry->flags & MTE_TRIGGER_FLAG_DWILD ? " (wild)" : "")));

                dvar = (netsnmp_variable_list *)
                                SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                if (!dvar) {
                    _mteTrigger_failure(
                            "failed to create mteTrigger delta query varbind");
                    return;
                }
                snmp_set_var_objid( dvar, entry->mteDeltaDiscontID,
                                          entry->mteDeltaDiscontID_len );
                if ( entry->flags & MTE_TRIGGER_FLAG_DWILD ) {
                    n = netsnmp_query_walk( dvar, entry->session );
                } else {
                    n = netsnmp_query_get(  dvar, entry->session );
                }
                if ( n != SNMP_ERR_NOERROR ) {
                    _mteTrigger_failure( "failed to run mteTrigger delta query" );
                    snmp_free_varbind( dvar );
                    return;
                }
            }

            /*
             * We can't calculate delta values the first time through,
             *  so there's no point in evaluating the remaining tests.
             *
             * Save the results (and discontinuity markers),
             *   ready for the next run.
             */
            if ( !entry->old_results ) {
                entry->old_results =  var;
                entry->old_deltaDs = dvar;
                entry->sysUpTime   = *sysUT_var.val.integer;
                return;
            }
            /*
             * If the sysUpTime marker has been reset (or strictly,
             *   has advanced by less than the monitor frequency),
             *  there's no point in trying the remaining tests.
             */

            if (*sysUT_var.val.integer < entry->sysUpTime) {
                DEBUGMSGTL(( "disman:event:delta",
                             "single discontinuity: (sysUT)\n"));
                snmp_free_varbind( entry->old_results );
                snmp_free_varbind( entry->old_deltaDs );
                entry->old_results =  var;
                entry->old_deltaDs = dvar;
                entry->sysUpTime   = *sysUT_var.val.integer;
                return;
            }
            /*
             * Similarly if a separate (non-wildcarded) discontinuity
             *  marker has changed, then there's no
             *  point in trying to evaluate these tests either.
             */
            if (!(entry->flags & MTE_TRIGGER_FLAG_DWILD)  &&
                !(entry->flags & MTE_TRIGGER_FLAG_SYSUPT) &&
                  (!entry->old_deltaDs ||
                   (entry->old_deltaDs->val.integer != dvar->val.integer))) {
                DEBUGMSGTL((  "disman:event:delta", "single discontinuity: ("));
                DEBUGMSGOID(( "disman:event:delta", entry->mteDeltaDiscontID,
                                           entry->mteDeltaDiscontID_len));
                DEBUGMSG((    "disman:event:delta", ")\n"));
                snmp_free_varbind( entry->old_results );
                snmp_free_varbind( entry->old_deltaDs );
                entry->old_results =  var;
                entry->old_deltaDs = dvar;
                entry->sysUpTime   = *sysUT_var.val.integer;
                return;
            }

            /*
             * Ensure that the list of (wildcarded) discontinuity 
             *  markers matches the list of monitored values
             *  (inserting/removing discontinuity varbinds as needed)
             *
             * XXX - An alternative approach would be to use the list
             *    of monitored values (instance subidentifiers) to build
             *    the exact list of delta markers to retrieve earlier.
             */
            if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                vp1      =  var;
                vp2      = dvar;
                vp2_prev = NULL;
                n  = entry->mteTriggerValueID_len;
                n2 = entry->mteDeltaDiscontID_len;
                while (vp1) {
                    /*
                     * For each monitored instance, check whether
                     *   there's a matching discontinuity entry.
                     */
                    cmp = snmp_oid_compare(vp1->name+n,  vp1->name_length-n,
                                           vp2->name+n2, vp2->name_length-n2 );
                    if ( cmp < 0 ) {
                        /*
                         * If a discontinuity entry is missing,
                         *   insert a (dummy) varbind.
                         * The corresponding delta calculation will
                         *   fail, but this simplifies the later code.
                         */
                        vtmp = (netsnmp_variable_list *)
                                SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
                        if (!vtmp) {
                            _mteTrigger_failure(
                                  "failed to create mteTrigger discontinuity varbind");
                            snmp_free_varbind(dvar);
                            return;
                        }
                        snmp_set_var_objid(vtmp, entry->mteDeltaDiscontID,
                                                 entry->mteDeltaDiscontID_len);
                            /* XXX - append instance subids */
                        vtmp->next_variable     = vp2;
                        vp2_prev->next_variable = vtmp;
                        vp2_prev                = vtmp;
                        vp1 = vp1->next_variable;
                    } else if ( cmp == 0 ) {
                        /*
                         * Matching discontinuity entry -  all OK.
                         */
                        vp2_prev = vp2;
                        vp2      = vp2->next_variable;
                        vp1      = vp1->next_variable;
                    } else {
                        /*
                         * Remove unneeded discontinuity entry
                         */
                        vtmp = vp2;
                        vp2_prev->next_variable = vp2->next_variable;
                        vp2                     = vp2->next_variable;
                        vtmp->next_variable = NULL;
                        snmp_free_varbind( vtmp );
                    }
                }
                /*
                 * XXX - Now need to ensure that the old list of
                 *   delta discontinuity markers matches as well.
                 */
            }
        } /* delta samples */
    } /* Boolean/Threshold test checks */



    /*
     * Only run the Boolean tests if there's an event to be triggered
     */
    if ((entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN) &&
        (entry->mteTBoolEvent[0] != '\0' )) {

        if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
            vp2 = entry->old_results;
            if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                dv1 = dvar;
                dv2 = entry->old_deltaDs;
            }
        }
        for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
            /*
             * Determine the value to be monitored...
             */
            if ( !vp1->val.integer ) {  /* No value */
                if ( vp2 )
                    vp2 = vp2->next_variable;
                continue;
            }
            if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
                if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                    /*
                     * We've already checked any non-wildcarded
                     *   discontinuity markers (inc. sysUpTime.0).
                     * Validate this particular sample against
                     *   the relevant wildcarded marker...
                     */
                    if ((dv1->type == ASN_NULL)  ||
                        (dv1->type != dv2->type) ||
                        (*dv1->val.integer != *dv2->val.integer)) {
                        /*
                         * Bogus or changed discontinuity marker.
                         * Need to skip this sample.
                         */
    DEBUGMSGTL(( "disman:event:delta", "discontinuity occurred: "));
    DEBUGMSGOID(("disman:event:delta", vp1->name,
                                       vp1->name_length ));
    DEBUGMSG((   "disman:event:delta", " \n" ));
                        vp2 = vp2->next_variable;
                        continue;
                    }
                }
                /*
                 * ... and check there is a previous sample to calculate
                 *   the delta value against (regardless of whether the
                 *   discontinuity marker was wildcarded or not).
                 */
                if (vp2->type == ASN_NULL) {
    DEBUGMSGTL(( "disman:event:delta", "missing sample: "));
    DEBUGMSGOID(("disman:event:delta", vp1->name,
                                       vp1->name_length ));
    DEBUGMSG((   "disman:event:delta", " \n" ));
                    vp2 = vp2->next_variable;
                    continue;
                }
                value = (*vp1->val.integer - *vp2->val.integer);
    DEBUGMSGTL(( "disman:event:delta", "delta sample: "));
    DEBUGMSGOID(("disman:event:delta", vp1->name,
                                       vp1->name_length ));
    DEBUGMSG((   "disman:event:delta", " (%ld - %ld) = %ld\n",
                *vp1->val.integer,  *vp2->val.integer, value));
                vp2 = vp2->next_variable;
            } else {
                value = *vp1->val.integer;
            }

            /*
             * ... evaluate the comparison ...
             */
            switch (entry->mteTBoolComparison) {
            case MTE_BOOL_UNEQUAL:
                cmp = ( value != entry->mteTBoolValue );
                break;
            case MTE_BOOL_EQUAL:
                cmp = ( value == entry->mteTBoolValue );
                break;
            case MTE_BOOL_LESS:
                cmp = ( value <  entry->mteTBoolValue );
                break;
            case MTE_BOOL_LESSEQUAL:
                cmp = ( value <= entry->mteTBoolValue );
                break;
            case MTE_BOOL_GREATER:
                cmp = ( value >  entry->mteTBoolValue );
                break;
            case MTE_BOOL_GREATEREQUAL:
                cmp = ( value >= entry->mteTBoolValue );
                break;
            }
    DEBUGMSGTL(( "disman:event:delta", "Bool comparison: (%ld %s %ld) %d\n",
                          value, _ops[entry->mteTBoolComparison],
                          entry->mteTBoolValue, cmp));

            /*
             * ... and decide whether to trigger the event.
             *    (using the 'index' field of the varbind structure
             *     to remember whether the trigger has already fired)
             */
            if ( cmp ) {
              if (vp1->index & MTE_ARMED_BOOLEAN ) {
                vp1->index &= ~MTE_ARMED_BOOLEAN;
                /*
                 * NB: Clear the trigger armed flag even if the
                 *   (starting) event dosn't actually fire.
                 *   Otherwise initially true (but suppressed)
                 *   triggers will fire on the *second* probe.
                 */
                if ( entry->old_results ||
                    (entry->flags & MTE_TRIGGER_FLAG_BSTART)) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing boolean test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire", "%s\n",
                                  (entry->old_results ? "" : " (startup)")));
                    entry->mteTriggerXOwner   = entry->mteTBoolObjOwner;
                    entry->mteTriggerXObjects = entry->mteTBoolObjects;
                    /*
                     * XXX - when firing a delta-based trigger, should
                     *   'mteHotValue' report the actual value sampled
                     *   (as here), or the delta that triggered the event ?
                     */
                    entry->mteTriggerFired    = vp1;
                    n = entry->mteTriggerValueID_len;
                    mteEvent_fire(entry->mteTBoolEvOwner, entry->mteTBoolEvent, 
                                  entry, vp1->name+n, vp1->name_length-n);
                }
              }
            } else {
                vp1->index |= MTE_ARMED_BOOLEAN;
            }
        }
    }


    /*
     * Only run the basic threshold tests if there's an event to
     *    be triggered.  (Either rising or falling will do)
     */
    if (( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) &&
        ((entry->mteTThRiseEvent[0] != '\0' ) ||
         (entry->mteTThFallEvent[0] != '\0' ))) {

        /*
         * The same delta-sample validation from Boolean
         *   tests also applies here too.
         */
        if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
            vp2 = entry->old_results;
            if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                dv1 = dvar;
                dv2 = entry->old_deltaDs;
            }
        }
        for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
            /*
             * Determine the value to be monitored...
             */
            if ( !vp1->val.integer ) {  /* No value */
                if ( vp2 )
                    vp2 = vp2->next_variable;
                continue;
            }
            if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
                if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
                    /*
                     * We've already checked any non-wildcarded
                     *   discontinuity markers (inc. sysUpTime.0).
                     * Validate this particular sample against
                     *   the relevant wildcarded marker...
                     */
                    if ((dv1->type == ASN_NULL)  ||
                        (dv1->type != dv2->type) ||
                        (*dv1->val.integer != *dv2->val.integer)) {
                        /*
                         * Bogus or changed discontinuity marker.
                         * Need to skip this sample.
                         */
                        vp2 = vp2->next_variable;
                        continue;
                    }
                }
                /*
                 * ... and check there is a previous sample to calculate
                 *   the delta value against (regardless of whether the
                 *   discontinuity marker was wildcarded or not).
                 */
                if (vp2->type == ASN_NULL) {
                    vp2 = vp2->next_variable;
                    continue;
                }
                value = (*vp1->val.integer - *vp2->val.integer);
                vp2 = vp2->next_variable;
            } else {
                value = *vp1->val.integer;
            }

            /*
             * ... evaluate the single-value comparisons,
             *     and decide whether to trigger the event.
             */
            cmp = vp1->index;   /* working copy of 'armed' flags */
            if ( value >= entry->mteTThRiseValue ) {
              if (cmp & MTE_ARMED_TH_RISE ) {
                cmp &= ~MTE_ARMED_TH_RISE;
                cmp |=  MTE_ARMED_TH_FALL;
                /*
                 * NB: Clear the trigger armed flag even if the
                 *   (starting) event dosn't actually fire.
                 *   Otherwise initially true (but suppressed)
                 *   triggers will fire on the *second* probe.
                 * Similarly for falling thresholds (see below).
                 */
                if ( entry->old_results ||
                    (entry->mteTThStartup & MTE_THRESH_START_RISE)) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing rising threshold test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire", "%s\n",
                                 (entry->old_results ? "" : " (startup)")));
                    /*
                     * If no riseEvent is configured, we need still to
                     *  set the armed flags appropriately, but there's
                     *  no point in trying to fire the (missing) event.
                     */
                    if (entry->mteTThRiseEvent[0] != '\0' ) {
                        entry->mteTriggerXOwner   = entry->mteTThObjOwner;
                        entry->mteTriggerXObjects = entry->mteTThObjects;
                        entry->mteTriggerFired    = vp1;
                        n = entry->mteTriggerValueID_len;
                        mteEvent_fire(entry->mteTThRiseOwner,
                                      entry->mteTThRiseEvent, 
                                      entry, vp1->name+n, vp1->name_length-n);
                    }
                }
              }
            }

            if ( value <= entry->mteTThFallValue ) {
              if (cmp & MTE_ARMED_TH_FALL ) {
                cmp &= ~MTE_ARMED_TH_FALL;
                cmp |=  MTE_ARMED_TH_RISE;
                /* Clear the trigger armed flag (see above) */
                if ( entry->old_results ||
                    (entry->mteTThStartup & MTE_THRESH_START_FALL)) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing falling threshold test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire", "%s\n",
                                 (entry->old_results ? "" : " (startup)")));
                    /*
                     * Similarly, if no fallEvent is configured,
                     *  there's no point in trying to fire it either.
                     */
                    if (entry->mteTThRiseEvent[0] != '\0' ) {
                        entry->mteTriggerXOwner   = entry->mteTThObjOwner;
                        entry->mteTriggerXObjects = entry->mteTThObjects;
                        entry->mteTriggerFired    = vp1;
                        n = entry->mteTriggerValueID_len;
                        mteEvent_fire(entry->mteTThFallOwner,
                                      entry->mteTThFallEvent, 
                                      entry, vp1->name+n, vp1->name_length-n);
                    }
                }
              }
            }
            vp1->index = cmp;
        }
    }

    /*
     * The same processing also works for delta-threshold tests (if configured)
     */
    if (( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) &&
        ((entry->mteTThDRiseEvent[0] != '\0' ) ||
         (entry->mteTThDFallEvent[0] != '\0' ))) {

        /*
         * Delta-threshold tests can only be used with
         *   absolute valued samples.
         */
        vp2 = entry->old_results;
        if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
            DEBUGMSGTL(( "disman:event:trigger",
                         "Delta-threshold on delta-sample\n"));
        } else if ( vp2 != NULL ) {
          for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
            /*
             * Determine the value to be monitored...
             *  (similar to previous delta-sample processing,
             *   but without the discontinuity marker checks)
             */
            if (!vp2) {
                break;   /* Run out of 'old' values */
            }
            if (( !vp1->val.integer ) ||
                (vp2->type == ASN_NULL)) {
                vp2 = vp2->next_variable;
                continue;
            }
            value = (*vp1->val.integer - *vp2->val.integer);
            vp2 = vp2->next_variable;

            /*
             * ... evaluate the single-value comparisons,
             *     and decide whether to trigger the event.
             */
            cmp = vp1->index;   /* working copy of 'armed' flags */
            if ( value >= entry->mteTThDRiseValue ) {
                if (vp1->index & MTE_ARMED_TH_DRISE ) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing rising delta threshold test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire", "\n"));
                    cmp &= ~MTE_ARMED_TH_DRISE;
                    cmp |=  MTE_ARMED_TH_DFALL;
                    /*
                     * If no riseEvent is configured, we need still to
                     *  set the armed flags appropriately, but there's
                     *  no point in trying to fire the (missing) event.
                     */
                    if (entry->mteTThDRiseEvent[0] != '\0' ) {
                        entry->mteTriggerXOwner   = entry->mteTThObjOwner;
                        entry->mteTriggerXObjects = entry->mteTThObjects;
                        entry->mteTriggerFired    = vp1;
                        n = entry->mteTriggerValueID_len;
                        mteEvent_fire(entry->mteTThDRiseOwner,
                                      entry->mteTThDRiseEvent, 
                                      entry, vp1->name+n, vp1->name_length-n);
                    }
                }
            }

            if ( value <= entry->mteTThDFallValue ) {
                if (vp1->index & MTE_ARMED_TH_DFALL ) {
                    DEBUGMSGTL(( "disman:event:trigger:fire",
                                 "Firing falling delta threshold test: "));
                    DEBUGMSGOID(("disman:event:trigger:fire",
                                 vp1->name, vp1->name_length));
                    DEBUGMSG((   "disman:event:trigger:fire", "\n"));
                    cmp &= ~MTE_ARMED_TH_DFALL;
                    cmp |=  MTE_ARMED_TH_DRISE;
                    /*
                     * Similarly, if no fallEvent is configured,
                     *  there's no point in trying to fire it either.
                     */
                    if (entry->mteTThDRiseEvent[0] != '\0' ) {
                        entry->mteTriggerXOwner   = entry->mteTThObjOwner;
                        entry->mteTriggerXObjects = entry->mteTThObjects;
                        entry->mteTriggerFired    = vp1;
                        n = entry->mteTriggerValueID_len;
                        mteEvent_fire(entry->mteTThDFallOwner,
                                      entry->mteTThDFallEvent, 
                                      entry, vp1->name+n, vp1->name_length-n);
                    }
                }
            }
            vp1->index = cmp;
          }
        }
    }

    /*
     * Finally, rotate the results - ready for the next run.
     */
    snmp_free_varbind( entry->old_results );
    entry->old_results = var;
    if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) {
        snmp_free_varbind( entry->old_deltaDs );
        entry->old_deltaDs = dvar;
        entry->sysUpTime   = *sysUT_var.val.integer;
    }
}

void
mteTrigger_enable( struct mteTrigger *entry )
{
    if (!entry)
        return;

    if (entry->alarm) {
        /* XXX - or explicitly call mteTrigger_disable ?? */
        snmp_alarm_unregister( entry->alarm );
        entry->alarm = 0;
    }

    if (entry->mteTriggerFrequency) {
        /*
         * register once to run ASAP, and another to run
         * at the trigger frequency
         */
        snmp_alarm_register(0, 0, mteTrigger_run, entry );
        entry->alarm = snmp_alarm_register(
                           entry->mteTriggerFrequency, SA_REPEAT,
                           mteTrigger_run, entry );
    }
}

void
mteTrigger_disable( struct mteTrigger *entry )
{
    if (!entry)
        return;

    if (entry->alarm) {
        snmp_alarm_unregister( entry->alarm );
        entry->alarm = 0;
        /* XXX - perhaps release any previous results */
    }
}

long _mteTrigger_MaxCount = 0;
long _mteTrigger_countEntries(void)
{
    struct mteTrigger *entry;
    netsnmp_tdata_row *row;
    long count = 0;

    for (row = netsnmp_tdata_row_first(trigger_table_data);
         row;
         row = netsnmp_tdata_row_next(trigger_table_data, row)) {
        entry  = (struct mteTrigger *)row->data;
        count += entry->count;
    }

    return count;
}

long mteTrigger_getNumEntries(int max)
{
    long count;
    /* XXX - implement some form of caching ??? */
    count = _mteTrigger_countEntries();
    if ( count > _mteTrigger_MaxCount )
        _mteTrigger_MaxCount = count;
    
    return ( max ?  _mteTrigger_MaxCount : count);
}
