summaryrefslogtreecommitdiff
path: root/agent/mibgroup/disman/event/mteTriggerConf.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/disman/event/mteTriggerConf.c')
-rw-r--r--agent/mibgroup/disman/event/mteTriggerConf.c1489
1 files changed, 1489 insertions, 0 deletions
diff --git a/agent/mibgroup/disman/event/mteTriggerConf.c b/agent/mibgroup/disman/event/mteTriggerConf.c
new file mode 100644
index 0000000..e7bb69b
--- /dev/null
+++ b/agent/mibgroup/disman/event/mteTriggerConf.c
@@ -0,0 +1,1489 @@
+/*
+ * DisMan Event MIB:
+ * Implementation of the trigger table configure handling
+ */
+
+#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 <net-snmp/agent/agent_callbacks.h>
+#include "utilities/iquery.h"
+#include "disman/event/mteObjects.h"
+#include "disman/event/mteTrigger.h"
+#include "disman/event/mteTriggerConf.h"
+
+#include <ctype.h>
+
+netsnmp_feature_require(iquery)
+
+/** Initializes the mteTriggerConf module */
+void
+init_mteTriggerConf(void)
+{
+ init_trigger_table_data();
+
+ /*
+ * Register config handler for user-level (fixed) triggers ...
+ */
+ snmpd_register_const_config_handler("monitor",
+ parse_mteMonitor,
+ NULL,
+ "triggername [-I] [-i OID | -o OID]* [-e event] expression ");
+ snmpd_register_const_config_handler("defaultMonitors",
+ parse_default_mteMonitors,
+ NULL, "yes|no");
+ snmpd_register_const_config_handler("linkUpDownNotifications",
+ parse_linkUpDown_traps,
+ NULL, "yes|no");
+
+ /*
+ * ... for persistent storage of various event table entries ...
+ */
+ snmpd_register_config_handler("_mteTTable",
+ parse_mteTTable, NULL, NULL);
+ snmpd_register_config_handler("_mteTDTable",
+ parse_mteTDTable, NULL, NULL);
+ snmpd_register_config_handler("_mteTExTable",
+ parse_mteTExTable, NULL, NULL);
+ snmpd_register_config_handler("_mteTBlTable",
+ parse_mteTBlTable, NULL, NULL);
+ snmpd_register_config_handler("_mteTThTable",
+ parse_mteTThTable, NULL, NULL);
+
+ /*
+ * ... and backwards compatability with the previous implementation.
+ */
+ snmpd_register_config_handler("mteTriggerTable",
+ parse_mteTriggerTable, NULL, NULL);
+
+ /*
+ * Register to save (non-fixed) entries when the agent shuts down
+ */
+ snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
+ store_mteTTable, NULL);
+ snmp_register_callback(SNMP_CALLBACK_APPLICATION,
+ SNMPD_CALLBACK_PRE_UPDATE_CONFIG,
+ clear_mteTTable, NULL);
+}
+
+/* ==============================
+ *
+ * utility routines
+ *
+ * ============================== */
+
+ /*
+ * Find or create the specified trigger entry
+ */
+struct mteTrigger *
+_find_mteTrigger_entry( const char *owner, char *tname )
+{
+ netsnmp_variable_list owner_var, tname_var;
+ netsnmp_tdata_row *row;
+
+ /*
+ * If there's already an existing entry,
+ * then use that...
+ */
+ memset(&owner_var, 0, sizeof(netsnmp_variable_list));
+ memset(&tname_var, 0, sizeof(netsnmp_variable_list));
+ snmp_set_var_typed_value(&owner_var, ASN_OCTET_STR, owner, strlen(owner));
+ snmp_set_var_typed_value(&tname_var, ASN_PRIV_IMPLIED_OCTET_STR,
+ tname, strlen(tname));
+ owner_var.next_variable = &tname_var;
+ row = netsnmp_tdata_row_get_byidx( trigger_table_data, &owner_var );
+ /*
+ * ... otherwise, create a new one
+ */
+ if (!row)
+ row = mteTrigger_createEntry( owner, tname, 0 );
+ if (!row)
+ return NULL;
+
+ /* return (struct mteTrigger *)netsnmp_tdata_row_entry( row ); */
+ return (struct mteTrigger *)row->data;
+}
+
+struct mteTrigger *
+_find_typed_mteTrigger_entry( const char *owner, char *tname, int type )
+{
+ struct mteTrigger *entry = _find_mteTrigger_entry( owner, tname );
+ if (!entry)
+ return NULL;
+
+ /*
+ * If this is an existing (i.e. valid) entry of the
+ * same type, then throw an error and discard it.
+ * But allow combined Existence/Boolean/Threshold trigger.
+ */
+ if ( entry &&
+ (entry->flags & MTE_TRIGGER_FLAG_VALID) &&
+ (entry->mteTriggerTest & type )) {
+ config_perror("duplicate trigger name");
+ return NULL;
+ }
+ return entry;
+}
+
+
+/* ================================================
+ *
+ * Handlers for user-configured (static) triggers
+ *
+ * ================================================ */
+
+int
+_mteTrigger_callback_enable( int majorID, int minorID,
+ void *serverargs, void *clientarg)
+{
+ struct mteTrigger *entry = (struct mteTrigger *)clientarg;
+ mteTrigger_enable( entry );
+
+ return 0;
+}
+
+
+void
+parse_mteMonitor(const char *token, const char *line)
+{
+ char buf[ SPRINT_MAX_LEN];
+ char tname[MTE_STR1_LEN+1];
+ const char *cp;
+ long test = 0;
+
+ char ename[MTE_STR1_LEN+1];
+ long flags = MTE_TRIGGER_FLAG_ENABLED |
+ MTE_TRIGGER_FLAG_ACTIVE |
+ MTE_TRIGGER_FLAG_FIXED |
+ MTE_TRIGGER_FLAG_VWILD |
+ MTE_TRIGGER_FLAG_SYSUPT |
+ MTE_TRIGGER_FLAG_VALID;
+ long idx = 0;
+ long startup = 1; /* ??? or 0 */
+ long repeat = 600;
+ netsnmp_session *sess = NULL;
+
+ int seen_name = 0;
+ char oid_name_buf[SPRINT_MAX_LEN];
+ oid name_buf[MAX_OID_LEN];
+ size_t name_buf_len;
+ u_char op = 0;
+ long value = 0;
+
+ struct mteObject *object;
+ struct mteTrigger *entry;
+
+ DEBUGMSGTL(("disman:event:conf", "Parsing disman monitor config (%s)\n", line));
+
+ /*
+ * Before parsing the configuration fully, first
+ * skim through the config line in order to:
+ * a) locate the name for the trigger, and
+ * b) identify the type of trigger test
+ *
+ * This information will be used both for creating the trigger
+ * entry, and registering any additional payload objects.
+ */
+ memset( buf, 0, sizeof(buf));
+ memset( tname, 0, sizeof(tname));
+ memset( ename, 0, sizeof(ename));
+ for (cp = copy_nword_const(line, buf, SPRINT_MAX_LEN);
+ ;
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN)) {
+
+ if ( buf[0] == '-' ) {
+ switch (buf[1]) {
+ case 't':
+ /* No longer necessary */
+ break;
+ case 'd':
+ case 'e':
+ case 'o':
+ case 'r':
+ case 'u':
+ /* skip option parameter */
+ cp = skip_token_const( cp );
+ break;
+ case 'D':
+ case 'I':
+ case 's':
+ case 'S':
+ /* flag options */
+ break;
+ case 'i':
+ /*
+ * '-i' can act as a flag or take a parameter.
+ * Handle either case.
+ */
+ if (cp && *cp != '-')
+ cp = skip_token_const( cp );
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* accept negative values */
+ case '\0':
+ /* and '-' placeholder value */
+ break;
+ default:
+ config_perror("unrecognised option");
+ return;
+ }
+ } else {
+ /*
+ * Save the first non-option parameter as the trigger name.
+ *
+ * This name will also be used to register entries in the
+ * mteObjectsTable, so insert a distinguishing prefix.
+ * This will ensure combined trigger entries don't clash with
+ * each other, or with a similarly-named notification event.
+ */
+ if ( !tname[0] ) {
+ tname[0] = '_';
+ tname[1] = '_'; /* Placeholder */
+ memcpy( tname+2, buf, MTE_STR1_LEN-2 );
+ } else {
+ /*
+ * This marks the beginning of the monitor expression,
+ * so we don't need to scan any further
+ */
+ break;
+ }
+ }
+ if (!cp)
+ break;
+ }
+
+ /*
+ * Now let's examine the expression to determine the type of
+ * monitor being configured. There are four possible forms:
+ * != OID (or ! OID) (existence test)
+ * OID (existence test)
+ * OID op VALUE (boolean test)
+ * OID MIN MAX (threshold test)
+ */
+ if ( *buf == '!' ) {
+ /*
+ * If the expression starts with '!=' or '!', then
+ * it must be the first style of existence test.
+ */
+ test = MTE_TRIGGER_EXISTENCE;
+ } else {
+ /*
+ * Otherwise the first token is the OID to be monitored.
+ * Skip it and look at the next token (if any).
+ */
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ if (cp) {
+ /*
+ * If this is a numeric value, then it'll be the MIN
+ * field of a threshold test (the fourth form)
+ * Otherwise it'll be the operation field of a
+ * boolean test (the third form)
+ */
+ if ( isdigit((unsigned char)(buf[0])) || buf[0] == '-' )
+ test = MTE_TRIGGER_THRESHOLD;
+ else
+ test = MTE_TRIGGER_BOOLEAN;
+ } else {
+ /*
+ * If there isn't a "next token", then this
+ * must be the second style of existence test.
+ */
+ test = MTE_TRIGGER_EXISTENCE;
+ }
+ }
+
+ /*
+ * Use the type of trigger test to update the trigger name buffer
+ */
+ switch (test) {
+ case MTE_TRIGGER_BOOLEAN:
+ tname[1] = 'B'; break;
+ case MTE_TRIGGER_THRESHOLD:
+ tname[1] = 'T'; break;
+ case MTE_TRIGGER_EXISTENCE:
+ tname[1] = 'X'; break;
+ }
+
+
+
+ /*
+ * Now start parsing again at the beginning of the directive,
+ * extracting the various options...
+ */
+ for (cp = copy_nword_const(line, buf, SPRINT_MAX_LEN);
+ ;
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN)) {
+
+ if (buf[0] == '-' ) {
+ switch (buf[1]) {
+ case 'D': /* delta sample value */
+ flags |= MTE_TRIGGER_FLAG_DELTA;
+ break;
+
+ case 'd': /* discontinuity OID (implies delta sample) */
+ flags |= MTE_TRIGGER_FLAG_DELTA;
+ if (buf[2] != 'i')
+ flags |= MTE_TRIGGER_FLAG_DWILD;
+ memset( oid_name_buf, 0, sizeof(oid_name_buf));
+ memset( name_buf, 0, sizeof( name_buf));
+ name_buf_len = MAX_OID_LEN;
+ cp = copy_nword_const(cp, oid_name_buf, MTE_STR1_LEN);
+ if (!snmp_parse_oid(oid_name_buf, name_buf, &name_buf_len)) {
+ snmp_log(LOG_ERR, "discontinuity OID: %s\n", oid_name_buf);
+ config_perror("unknown discontinuity OID");
+ mteObjects_removeEntries( "snmpd.conf", tname );
+ return;
+ }
+ if ( snmp_oid_compare( name_buf, name_buf_len,
+ _sysUpTime_instance,
+ _sysUpTime_inst_len) != 0 )
+ flags &= ~MTE_TRIGGER_FLAG_SYSUPT;
+ break;
+
+ case 'e': /* event */
+ cp = copy_nword_const(cp, ename, MTE_STR1_LEN);
+ break;
+
+ case 'I': /* value instance */
+ flags &= ~MTE_TRIGGER_FLAG_VWILD;
+ break;
+
+ /*
+ * "instance" flag:
+ * either non-wildcarded mteTriggerValueID
+ * (backwards compatability - see '-I')
+ * or exact payload OID
+ * (c.f. notificationEvent config)
+ */
+ case 'i':
+ if ( *cp == '-' ) {
+ /* Backwards compatibility - now '-I' */
+ flags &= ~MTE_TRIGGER_FLAG_VWILD;
+ continue;
+ }
+ idx++;
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ object = mteObjects_addOID( "snmpd.conf", tname, idx, buf, 0 );
+ if (!object) {
+ snmp_log(LOG_ERR, "Unknown payload OID: %s\n", buf);
+ config_perror("Unknown payload OID");
+ mteObjects_removeEntries( "snmpd.conf", tname );
+ } else
+ idx = object->mteOIndex;
+ break;
+
+ case 'o': /* object */
+ idx++;
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ object = mteObjects_addOID( "snmpd.conf", tname, idx, buf, 1 );
+ if (!object) {
+ snmp_log(LOG_ERR, "Unknown payload OID: %s\n", buf);
+ config_perror("Unknown payload OID");
+ mteObjects_removeEntries( "snmpd.conf", tname );
+ } else
+ idx = object->mteOIndex;
+ break;
+
+ case 'r': /* repeat frequency */
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ repeat = strtoul(buf, NULL, 0);
+ break;
+
+ case 'S': /* disable startup tests */
+ startup = 0;
+ break;
+
+ case 's': /* enable startup tests (default?) */
+ startup = 1;
+ break;
+
+ case 't': /* threshold test - already handled */
+ break;
+
+ case 'u': /* user */
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ sess = netsnmp_iquery_user_session(buf);
+ if (NULL == sess) {
+ snmp_log(LOG_ERR, "user name %s not found\n", buf);
+ config_perror("Unknown user name\n");
+ mteObjects_removeEntries( "snmpd.conf", tname );
+ return;
+ }
+ break;
+ }
+ } else {
+ /*
+ * Skip the first non-option token - the trigger
+ * name (which has already been processed earlier).
+ */
+ if ( !seen_name ) {
+ seen_name = 1;
+ } else {
+ /*
+ * But the next non-option token encountered will
+ * mark the start of the expression to be monitored.
+ *
+ * There are three possible expression formats:
+ * [op] OID (existence tests)
+ * OID op value (boolean tests)
+ * OID val val [val val] (threshold tests)
+ *
+ * Extract the OID, operation and (first) value.
+ */
+ switch ( test ) {
+ case MTE_TRIGGER_EXISTENCE:
+ /*
+ * Identify the existence operator (if any)...
+ */
+ op = MTE_EXIST_PRESENT;
+ if (buf[0] == '!') {
+ if (buf[1] == '=') {
+ op = MTE_EXIST_CHANGED;
+ } else {
+ op = MTE_EXIST_ABSENT;
+ }
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ }
+ /*
+ * ... then extract the monitored OID.
+ * (ignoring anything that remains)
+ */
+ memcpy(oid_name_buf, buf, SPRINT_MAX_LEN);
+ cp = NULL; /* To terminate the processing loop */
+ DEBUGMSGTL(("disman:event:conf", "%s: Exist (%s, %d)\n",
+ tname, oid_name_buf, op));
+ break;
+
+ case MTE_TRIGGER_BOOLEAN:
+ /*
+ * Extract the monitored OID, and
+ * identify the boolean operator ...
+ */
+ memcpy(oid_name_buf, buf, SPRINT_MAX_LEN);
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ if (buf[0] == '!') {
+ op = MTE_BOOL_UNEQUAL;
+ } else if (buf[0] == '=') {
+ op = MTE_BOOL_EQUAL;
+ } else if (buf[0] == '<') {
+ if (buf[1] == '=') {
+ op = MTE_BOOL_LESSEQUAL;
+ } else {
+ op = MTE_BOOL_LESS;
+ }
+ } else if (buf[0] == '>') {
+ if (buf[1] == '=') {
+ op = MTE_BOOL_GREATEREQUAL;
+ } else {
+ op = MTE_BOOL_GREATER;
+ }
+ }
+ /*
+ * ... then extract the comparison value.
+ * (ignoring anything that remains)
+ */
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ value = strtol(buf, NULL, 0);
+ cp = NULL; /* To terminate the processing loop */
+ DEBUGMSGTL(("disman:event:conf", "%s: Bool (%s, %d, %ld)\n",
+ tname, oid_name_buf, op, value));
+ break;
+
+ case MTE_TRIGGER_THRESHOLD:
+ /*
+ * Extract the monitored OID, and
+ * the first comparison value...
+ */
+ memcpy(oid_name_buf, buf, SPRINT_MAX_LEN);
+ memset( buf, 0, SPRINT_MAX_LEN);
+ cp = copy_nword_const(cp, buf, SPRINT_MAX_LEN);
+ value = strtol(buf, NULL, 0);
+
+ /*
+ * ... then save the rest of the line for later.
+ */
+ memset( buf, 0, strlen(buf));
+ memcpy( buf, cp, strlen(cp));
+ cp = NULL; /* To terminate the processing loop */
+ DEBUGMSGTL(("disman:event:conf", "%s: Thresh (%s, %ld, %s)\n",
+ tname, oid_name_buf, value, buf));
+ break;
+ }
+ }
+ }
+ if (!cp)
+ break;
+ }
+
+ if (NULL == sess) {
+ sess = netsnmp_query_get_default_session();
+ if (NULL == sess) {
+ config_perror
+ ("You must specify a default user name using the agentSecName token\n");
+ mteObjects_removeEntries( "snmpd.conf", tname );
+ return;
+ }
+ }
+
+ /*
+ * ... and then create the new trigger entry...
+ */
+ entry = _find_typed_mteTrigger_entry( "snmpd.conf", tname+2, test );
+ if (!entry) {
+ /* mteObjects_removeEntries( "snmpd.conf", tname ); */
+ return;
+ }
+
+ /*
+ * ... populate the type-independent fields...
+ * (setting the delta discontinuity OID first)
+ */
+ if ( (flags & MTE_TRIGGER_FLAG_DELTA) &&
+ !(flags & MTE_TRIGGER_FLAG_SYSUPT)) {
+ memset( entry->mteDeltaDiscontID, 0, sizeof(entry->mteDeltaDiscontID));
+ memcpy( entry->mteDeltaDiscontID, name_buf, name_buf_len*sizeof(oid));
+ entry->mteDeltaDiscontID_len = name_buf_len;
+ }
+ name_buf_len = MAX_OID_LEN;
+ if (!snmp_parse_oid(oid_name_buf, name_buf, &name_buf_len)) {
+ snmp_log(LOG_ERR, "trigger OID: %s\n", oid_name_buf);
+ config_perror("unknown monitor OID");
+ mteObjects_removeEntries( "snmpd.conf", tname );
+ return;
+ }
+ entry->session = sess;
+ entry->flags |= flags;
+ entry->mteTriggerTest |= test;
+ entry->mteTriggerFrequency = repeat;
+ entry->mteTriggerValueID_len = name_buf_len;
+ memcpy(entry->mteTriggerValueID, name_buf, name_buf_len*sizeof(oid));
+
+ /*
+ * ... and the relevant test-specific fields.
+ */
+ switch (test) {
+ case MTE_TRIGGER_EXISTENCE:
+ entry->mteTExTest = op;
+ if (op != MTE_EXIST_CHANGED && startup)
+ entry->mteTExStartup = op;
+ if ( idx > 0 ) {
+ /*
+ * Refer to the objects for this trigger (if any)...
+ */
+ memset(entry->mteTExObjOwner, 0, MTE_STR1_LEN+1);
+ memcpy(entry->mteTExObjOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTExObjects, tname, MTE_STR1_LEN+1);
+ }
+ if ( ename[0] ) {
+ /*
+ * ... and the specified event...
+ */
+ memset(entry->mteTExEvOwner, 0, MTE_STR1_LEN+1);
+ if ( ename[0] == '_' )
+ memcpy(entry->mteTExEvOwner, "_snmpd", 6);
+ else
+ memcpy(entry->mteTExEvOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTExEvent, ename, MTE_STR1_LEN+1);
+ } else {
+ /*
+ * ... or the hardcoded default event.
+ */
+ memset(entry->mteTExEvOwner, 0, MTE_STR1_LEN+1);
+ memset(entry->mteTExEvent, 0, MTE_STR1_LEN+1);
+ memcpy(entry->mteTExEvOwner, "_snmpd", 6);
+ memcpy(entry->mteTExEvent, "_mteTriggerFired", 16);
+ }
+ break;
+ case MTE_TRIGGER_BOOLEAN:
+ entry->mteTBoolComparison = op;
+ entry->mteTBoolValue = value;
+ if (!startup)
+ entry->flags &= ~MTE_TRIGGER_FLAG_BSTART;
+ if ( idx > 0 ) {
+ /*
+ * Refer to the objects for this trigger (if any)...
+ */
+ memset(entry->mteTBoolObjOwner, 0, MTE_STR1_LEN+1);
+ memcpy(entry->mteTBoolObjOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTBoolObjects, tname, MTE_STR1_LEN+1);
+ }
+ if ( ename[0] ) {
+ /*
+ * ... and the specified event...
+ */
+ memset(entry->mteTBoolEvOwner, 0, MTE_STR1_LEN+1);
+ if ( ename[0] == '_' )
+ memcpy(entry->mteTBoolEvOwner, "_snmpd", 6);
+ else
+ memcpy(entry->mteTBoolEvOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTBoolEvent, ename, MTE_STR1_LEN+1);
+ } else {
+ /*
+ * ... or the hardcoded default event.
+ */
+ memset(entry->mteTBoolEvOwner, 0, MTE_STR1_LEN+1);
+ memset(entry->mteTBoolEvent, 0, MTE_STR1_LEN+1);
+ memcpy(entry->mteTBoolEvOwner, "_snmpd", 6);
+ memcpy(entry->mteTBoolEvent, "_mteTriggerFired", 16);
+ }
+ break;
+ case MTE_TRIGGER_THRESHOLD:
+ entry->mteTThFallValue = value;
+ value = strtol(buf, NULL, 0);
+ entry->mteTThRiseValue = value;
+ if (!startup)
+ entry->mteTThStartup = 0;
+ if ( idx > 0 ) {
+ /*
+ * Refer to the objects for this trigger (if any)...
+ */
+ memset(entry->mteTThObjOwner, 0, MTE_STR1_LEN+1);
+ memcpy(entry->mteTThObjOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTThObjects, tname, MTE_STR1_LEN+1);
+ }
+ if ( ename[0] ) {
+ /*
+ * ... and the specified event...
+ * (using the same event for all triggers)
+ */
+ memset(entry->mteTThRiseOwner, 0, MTE_STR1_LEN+1);
+ if ( ename[0] == '_' )
+ memcpy(entry->mteTThRiseOwner, "_snmpd", 6);
+ else
+ memcpy(entry->mteTThRiseOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTThRiseEvent, ename, MTE_STR1_LEN+1);
+ memset(entry->mteTThFallOwner, 0, MTE_STR1_LEN+1);
+ if ( ename[0] == '_' )
+ memcpy(entry->mteTThFallOwner, "_snmpd", 6);
+ else
+ memcpy(entry->mteTThFallOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTThFallEvent, ename, MTE_STR1_LEN+1);
+ } else {
+ /*
+ * ... or the hardcoded default events.
+ */
+ memset(entry->mteTThRiseOwner, 0, MTE_STR1_LEN+1);
+ memset(entry->mteTThFallOwner, 0, MTE_STR1_LEN+1);
+ memset(entry->mteTThRiseEvent, 0, MTE_STR1_LEN+1);
+ memset(entry->mteTThFallEvent, 0, MTE_STR1_LEN+1);
+ memcpy(entry->mteTThRiseOwner, "_snmpd", 6);
+ memcpy(entry->mteTThFallOwner, "_snmpd", 6);
+ memcpy(entry->mteTThRiseEvent, "_mteTriggerRising", 17);
+ memcpy(entry->mteTThFallEvent, "_mteTriggerFalling", 18);
+ }
+ cp = skip_token(buf); /* skip riseThreshold value */
+
+ /*
+ * Parse and set (optional) Delta thresholds & events
+ */
+ if ( cp && *cp != '\0' ) {
+ if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
+ config_perror("Delta-threshold on delta-samples not supported");
+ mteObjects_removeEntries( "snmpd.conf", tname );
+ return;
+ }
+ value = strtol(cp, NULL, 0);
+ entry->mteTThDFallValue = value;
+ cp = skip_token_const(cp);
+ value = strtol(cp, NULL, 0);
+ entry->mteTThDRiseValue = value;
+ /*
+ * Set the events in the same way as before
+ */
+ if ( ename[0] ) {
+ memset(entry->mteTThDRiseOwner, 0, MTE_STR1_LEN+1);
+ if ( ename[0] == '_' )
+ memcpy(entry->mteTThDRiseOwner, "_snmpd", 6);
+ else
+ memcpy(entry->mteTThDRiseOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTThDRiseEvent, ename, MTE_STR1_LEN+1);
+ memset(entry->mteTThDFallOwner, 0, MTE_STR1_LEN+1);
+ if ( ename[0] == '_' )
+ memcpy(entry->mteTThDFallOwner, "_snmpd", 6);
+ else
+ memcpy(entry->mteTThDFallOwner, "snmpd.conf", 10);
+ memcpy(entry->mteTThDFallEvent, ename, MTE_STR1_LEN+1);
+ } else {
+ memset(entry->mteTThDRiseOwner, 0, MTE_STR1_LEN+1);
+ memset(entry->mteTThDFallOwner, 0, MTE_STR1_LEN+1);
+ memset(entry->mteTThDRiseEvent, 0, MTE_STR1_LEN+1);
+ memset(entry->mteTThDFallEvent, 0, MTE_STR1_LEN+1);
+ memcpy(entry->mteTThDRiseOwner, "_snmpd", 6);
+ memcpy(entry->mteTThDFallOwner, "_snmpd", 6);
+ memcpy(entry->mteTThDRiseEvent, "_mteTriggerRising", 17);
+ memcpy(entry->mteTThDFallEvent, "_mteTriggerFalling", 18);
+ }
+ }
+
+ break;
+ }
+ snmp_register_callback(SNMP_CALLBACK_LIBRARY,
+ SNMP_CALLBACK_POST_READ_CONFIG,
+ _mteTrigger_callback_enable, entry );
+ return;
+}
+
+void
+parse_linkUpDown_traps(const char *token, const char *line)
+{
+ /*
+ * XXX - This isn't strictly correct according to the
+ * definitions in IF-MIB, but will do for now.
+ */
+ if (strncmp( line, "yes", 3) == 0) {
+ DEBUGMSGTL(("disman:event:conf", "Registering linkUpDown traps\n"));
+
+ /* ifOperStatus */
+ parse_mteMonitor("monitor",
+ "-r 60 -S -e _linkUp \"linkUp\" .1.3.6.1.2.1.2.2.1.8 != 2");
+ parse_mteMonitor("monitor",
+ "-r 60 -S -e _linkDown \"linkDown\" .1.3.6.1.2.1.2.2.1.8 == 2");
+ }
+}
+
+
+void
+parse_default_mteMonitors(const char *token, const char *line)
+{
+ if (strncmp( line, "yes", 3) == 0) {
+ DEBUGMSGTL(("disman:event:conf", "Registering default monitors\n"));
+
+ parse_mteMonitor("monitor",
+ "-o prNames -o prErrMessage \"process table\" prErrorFlag != 0");
+ parse_mteMonitor("monitor",
+ "-o memErrorName -o memSwapErrorMsg \"memory\" memSwapError != 0");
+ parse_mteMonitor("monitor",
+ "-o extNames -o extOutput \"extTable\" extResult != 0");
+ parse_mteMonitor("monitor",
+ "-o dskPath -o dskErrorMsg \"dskTable\" dskErrorFlag != 0");
+ parse_mteMonitor("monitor",
+ "-o laNames -o laErrMessage \"laTable\" laErrorFlag != 0");
+ parse_mteMonitor("monitor",
+ "-o fileName -o fileErrorMsg \"fileTable\" fileErrorFlag != 0");
+ parse_mteMonitor("monitor",
+ "-o snmperrErrMessage \"snmperrs\" snmperrErrorFlag != 0");
+ }
+ return;
+}
+
+/* ================================================
+ *
+ * Handlers for loading persistent trigger entries
+ *
+ * ================================================ */
+
+
+
+/*
+ * Entries for the main mteTriggerTable
+ */
+
+char *
+_parse_mteTCols( char *line, struct mteTrigger *entry, int bcomp )
+{
+ void *vp;
+ size_t tmp;
+ size_t len;
+
+ len = MTE_STR2_LEN; vp = entry->mteTriggerComment;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ if ( bcomp ) {
+ /*
+ * The newer style of config directive skips the
+ * mteTriggerTest and mteTriggerSampleType values,
+ * as these are set implicitly from the relevant
+ * config directives.
+ * Backwards compatability with the previous (combined)
+ * style reads these in explicitly.
+ */
+ len = 1;
+ vp = &entry->mteTriggerTest;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ if (tmp == 2)
+ entry->flags |= MTE_TRIGGER_FLAG_DELTA;
+ }
+ vp = entry->mteTriggerValueID;
+ entry->mteTriggerValueID_len = MAX_OID_LEN;
+ line = read_config_read_data(ASN_OBJECT_ID, line, &vp,
+ &entry->mteTriggerValueID_len);
+ if (bcomp) {
+ /*
+ * The newer style combines the various boolean values
+ * into a single field (which comes later).
+ * Backwards compatability means reading these individually.
+ */
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ if (tmp == TV_TRUE)
+ entry->flags |= MTE_TRIGGER_FLAG_VWILD;
+ }
+ len = MTE_STR2_LEN; vp = entry->mteTriggerTarget;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR2_LEN; vp = entry->mteTriggerContext;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ if (bcomp) {
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ if (tmp == TV_TRUE)
+ entry->flags |= MTE_TRIGGER_FLAG_CWILD;
+ }
+
+ line = read_config_read_data(ASN_UNSIGNED, line,
+ &entry->mteTriggerFrequency, NULL);
+
+ len = MTE_STR1_LEN; vp = entry->mteTriggerOOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTriggerObjects;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+
+ /*
+ * Assorted boolean flag values, combined into a single field
+ */
+ if (bcomp) {
+ /*
+ * Backwards compatability stores the mteTriggerEnabled
+ * and mteTriggerEntryStatus values separately...
+ */
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ if (tmp == TV_TRUE)
+ entry->flags |= MTE_TRIGGER_FLAG_ENABLED;
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ if (tmp == RS_ACTIVE)
+ entry->flags |= MTE_TRIGGER_FLAG_ACTIVE;
+ } else {
+ /*
+ * ... while the newer style combines all the assorted
+ * boolean values into this single field.
+ */
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ entry->flags |= ( tmp &
+ (MTE_TRIGGER_FLAG_VWILD |MTE_TRIGGER_FLAG_CWILD|
+ MTE_TRIGGER_FLAG_ENABLED|MTE_TRIGGER_FLAG_ACTIVE));
+ }
+
+ return line;
+}
+
+void
+parse_mteTTable(const char *token, char *line)
+{
+ char owner[MTE_STR1_LEN+1];
+ char tname[MTE_STR1_LEN+1];
+ void *vp;
+ size_t len;
+ struct mteTrigger *entry;
+
+ DEBUGMSGTL(("disman:event:conf", "Parsing mteTriggerTable config...\n"));
+
+ /*
+ * Read in the index information for this entry
+ * and create a (non-fixed) data structure for it.
+ */
+ memset( owner, 0, sizeof(owner));
+ memset( tname, 0, sizeof(tname));
+ len = MTE_STR1_LEN; vp = owner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = tname;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ entry = _find_mteTrigger_entry( owner, tname );
+
+ DEBUGMSG(("disman:event:conf", "(%s, %s) ", owner, tname));
+
+ /*
+ * Read in the accessible (trigger-independent) column values.
+ */
+ line = _parse_mteTCols( line, entry, 0 );
+ /*
+ * XXX - Will need to read in the 'iquery' access information
+ */
+ entry->flags |= MTE_TRIGGER_FLAG_VALID;
+
+ DEBUGMSG(("disman:event:conf", "\n"));
+}
+
+
+/*
+ * Entries from the mteTriggerDeltaTable
+ */
+
+char *
+_parse_mteTDCols( char *line, struct mteTrigger *entry, int bcomp )
+{
+ void *vp;
+ size_t tmp;
+
+ entry->mteDeltaDiscontID_len = MAX_OID_LEN;
+ vp = entry->mteDeltaDiscontID;
+ line = read_config_read_data(ASN_OBJECT_ID, line, &vp,
+ &entry->mteDeltaDiscontID_len);
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ if (bcomp) {
+ if ( tmp == TV_TRUE )
+ entry->flags |= MTE_TRIGGER_FLAG_DWILD;
+ } else {
+ if ( tmp & MTE_TRIGGER_FLAG_DWILD )
+ entry->flags |= MTE_TRIGGER_FLAG_DWILD;
+ }
+ line = read_config_read_data(ASN_UNSIGNED, line,
+ &entry->mteDeltaDiscontIDType, NULL);
+
+ return line;
+}
+
+void
+parse_mteTDTable(const char *token, char *line)
+{
+ char owner[MTE_STR1_LEN+1];
+ char tname[MTE_STR1_LEN+1];
+ void *vp;
+ size_t len;
+ struct mteTrigger *entry;
+
+ DEBUGMSGTL(("disman:event:conf", "Parsing mteTriggerDeltaTable config... "));
+
+ /*
+ * Read in the index information for this entry
+ * and create a (non-fixed) data structure for it.
+ */
+ memset( owner, 0, sizeof(owner));
+ memset( tname, 0, sizeof(tname));
+ len = MTE_STR1_LEN; vp = owner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = tname;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ entry = _find_mteTrigger_entry( owner, tname );
+
+ DEBUGMSG(("disman:event:conf", "(%s, %s) ", owner, tname));
+
+ /*
+ * Read in the accessible column values.
+ */
+ line = _parse_mteTDCols( line, entry, 0 );
+
+ entry->flags |= (MTE_TRIGGER_FLAG_DELTA|
+ MTE_TRIGGER_FLAG_VALID);
+
+ DEBUGMSG(("disman:event:conf", "\n"));
+}
+
+
+/*
+ * Entries from the mteTriggerExistenceTable
+ */
+
+char *
+_parse_mteTExCols( char *line, struct mteTrigger *entry, int bcomp )
+{
+ void *vp;
+ size_t tmp;
+ size_t len;
+
+ if (bcomp) {
+ len = 1;
+ vp = &entry->mteTExTest;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = 1;
+ vp = &entry->mteTExStartup;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ } else {
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ entry->mteTExStartup = ( tmp & 0xff ); tmp >>= 8;
+ entry->mteTExTest = ( tmp & 0xff );
+ }
+
+ len = MTE_STR1_LEN; vp = entry->mteTExObjOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTExObjects;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+
+ len = MTE_STR1_LEN; vp = entry->mteTExEvOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTExEvent;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+
+ return line;
+}
+
+void
+parse_mteTExTable(const char *token, char *line)
+{
+ char owner[MTE_STR1_LEN+1];
+ char tname[MTE_STR1_LEN+1];
+ void *vp;
+ size_t len;
+ struct mteTrigger *entry;
+
+ DEBUGMSGTL(("disman:event:conf", "Parsing mteTriggerExistenceTable config... "));
+
+ /*
+ * Read in the index information for this entry
+ * and create a (non-fixed) data structure for it.
+ */
+ memset( owner, 0, sizeof(owner));
+ memset( tname, 0, sizeof(tname));
+ len = MTE_STR1_LEN; vp = owner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = tname;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ entry = _find_mteTrigger_entry( owner, tname );
+
+ DEBUGMSG(("disman:event:conf", "(%s, %s) ", owner, tname));
+
+ /*
+ * Read in the accessible column values.
+ * (Note that the first two are combined into a single field)
+ */
+ line = _parse_mteTExCols( line, entry, 0 );
+
+ entry->mteTriggerTest |= MTE_TRIGGER_EXISTENCE;
+ entry->flags |= MTE_TRIGGER_FLAG_VALID;
+
+ DEBUGMSG(("disman:event:conf", "\n"));
+}
+
+
+/*
+ * Entries from the mteTriggerBooleanTable
+ */
+
+char *
+_parse_mteTBlCols( char *line, struct mteTrigger *entry, int bcomp )
+{
+ void *vp;
+ size_t tmp;
+ size_t len;
+
+ if (bcomp) {
+ line = read_config_read_data(ASN_UNSIGNED, line,
+ &entry->mteTBoolComparison, NULL);
+ line = read_config_read_data(ASN_INTEGER, line,
+ &entry->mteTBoolValue, NULL);
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ if (tmp == TV_TRUE)
+ entry->flags |= MTE_TRIGGER_FLAG_BSTART;
+ } else {
+ line = read_config_read_data(ASN_UNSIGNED, line, &tmp, NULL);
+ entry->mteTBoolComparison = ( tmp & 0x0f );
+ entry->flags |= ( tmp & MTE_TRIGGER_FLAG_BSTART );
+ line = read_config_read_data(ASN_INTEGER, line,
+ &entry->mteTBoolValue, NULL);
+ }
+
+
+ len = MTE_STR1_LEN; vp = entry->mteTBoolObjOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTBoolObjects;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+
+ len = MTE_STR1_LEN; vp = entry->mteTBoolEvOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTBoolEvent;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+
+ return line;
+}
+
+void
+parse_mteTBlTable(const char *token, char *line)
+{
+ char owner[MTE_STR1_LEN+1];
+ char tname[MTE_STR1_LEN+1];
+ void *vp;
+ size_t len;
+ struct mteTrigger *entry;
+
+ DEBUGMSGTL(("disman:event:conf", "Parsing mteTriggerBooleanTable config... "));
+
+ /*
+ * Read in the index information for this entry
+ * and create a (non-fixed) data structure for it.
+ */
+ memset( owner, 0, sizeof(owner));
+ memset( tname, 0, sizeof(tname));
+ len = MTE_STR1_LEN; vp = owner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = tname;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ entry = _find_mteTrigger_entry( owner, tname );
+
+ DEBUGMSG(("disman:event:conf", "(%s, %s) ", owner, tname));
+
+ /*
+ * Read in the accessible column values.
+ * (Note that the first & third are combined into a single field)
+ */
+ line = _parse_mteTBlCols( line, entry, 0 );
+
+ entry->mteTriggerTest |= MTE_TRIGGER_BOOLEAN;
+ entry->flags |= MTE_TRIGGER_FLAG_VALID;
+
+ DEBUGMSG(("disman:event:conf", "\n"));
+}
+
+
+/*
+ * Entries from the mteTriggerThresholdTable
+ */
+
+char *
+_parse_mteTThCols( char *line, struct mteTrigger *entry, int bcomp )
+{
+ void *vp;
+ size_t len;
+
+ line = read_config_read_data(ASN_UNSIGNED, line,
+ &entry->mteTThStartup, NULL);
+ line = read_config_read_data(ASN_INTEGER, line,
+ &entry->mteTThRiseValue, NULL);
+ line = read_config_read_data(ASN_INTEGER, line,
+ &entry->mteTThFallValue, NULL);
+ line = read_config_read_data(ASN_INTEGER, line,
+ &entry->mteTThDRiseValue, NULL);
+ line = read_config_read_data(ASN_INTEGER, line,
+ &entry->mteTThDFallValue, NULL);
+
+ len = MTE_STR1_LEN; vp = entry->mteTThObjOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTThObjects;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+
+ len = MTE_STR1_LEN; vp = entry->mteTThRiseOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTThRiseEvent;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTThFallOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTThFallEvent;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+
+ len = MTE_STR1_LEN; vp = entry->mteTThDRiseOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTThDRiseEvent;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTThDFallOwner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = entry->mteTThDFallEvent;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+
+ return line;
+}
+
+void
+parse_mteTThTable(const char *token, char *line)
+{
+ char owner[MTE_STR1_LEN+1];
+ char tname[MTE_STR1_LEN+1];
+ void *vp;
+ size_t len;
+ struct mteTrigger *entry;
+
+ DEBUGMSGTL(("disman:event:conf", "Parsing mteTriggerThresholdTable config... "));
+
+ /*
+ * Read in the index information for this entry
+ * and create a (non-fixed) data structure for it.
+ */
+ memset( owner, 0, sizeof(owner));
+ memset( tname, 0, sizeof(tname));
+ len = MTE_STR1_LEN; vp = owner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = tname;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ entry = _find_mteTrigger_entry( owner, tname );
+
+ DEBUGMSG(("disman:event:conf", "(%s, %s) ", owner, tname));
+
+ /*
+ * Read in the accessible column values.
+ */
+ line = _parse_mteTThCols( line, entry, 0 );
+
+ entry->mteTriggerTest |= MTE_TRIGGER_THRESHOLD;
+ entry->flags |= MTE_TRIGGER_FLAG_VALID;
+
+ DEBUGMSG(("disman:event:conf", "\n"));
+}
+
+
+/*
+ * Backwards Compatability with the previous implementation
+ */
+
+void
+parse_mteTriggerTable(const char *token, char *line)
+{
+ char owner[MTE_STR1_LEN+1];
+ char tname[MTE_STR1_LEN+1];
+ void *vp;
+ size_t len;
+ struct mteTrigger *entry;
+
+ DEBUGMSGTL(("disman:event:conf", "Parsing previous mteTriggerTable config... "));
+
+ /*
+ * Read in the index information for this entry
+ * and create a (non-fixed) data structure for it.
+ */
+ memset( owner, 0, sizeof(owner));
+ memset( tname, 0, sizeof(tname));
+ len = MTE_STR1_LEN; vp = owner;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ len = MTE_STR1_LEN; vp = tname;
+ line = read_config_read_data(ASN_OCTET_STR, line, &vp, &len);
+ entry = _find_mteTrigger_entry( owner, tname );
+
+ DEBUGMSG(("disman:event:conf", "(%s, %s) ", owner, tname));
+
+ /*
+ * Read in the accessible column values for each table in turn...
+ * (similar, though not identical to the newer style).
+ */
+ line = _parse_mteTCols( line, entry, 1 );
+ line = _parse_mteTDCols( line, entry, 1 );
+ line = _parse_mteTExCols( line, entry, 1 );
+ line = _parse_mteTBlCols( line, entry, 1 );
+ line = _parse_mteTThCols( line, entry, 1 );
+
+ /*
+ * ... and then read in the "local internal variables"
+ * XXX - TODO
+ */
+ entry->flags |= MTE_TRIGGER_FLAG_VALID;
+
+ /* XXX - mte_enable_trigger(); ??? */
+ DEBUGMSG(("disman:event:conf", "\n"));
+}
+
+/* ===============================================
+ *
+ * Handler for storing persistent trigger entries
+ *
+ * =============================================== */
+
+int
+store_mteTTable(int majorID, int minorID, void *serverarg, void *clientarg)
+{
+ char line[SNMP_MAXBUF];
+ char *cptr, *cp;
+ void *vp;
+ size_t tint;
+ netsnmp_tdata_row *row;
+ struct mteTrigger *entry;
+
+
+ DEBUGMSGTL(("disman:event:conf", "Storing mteTriggerTable config:\n"));
+
+ for (row = netsnmp_tdata_row_first( trigger_table_data );
+ row;
+ row = netsnmp_tdata_row_next( trigger_table_data, row )) {
+
+ /*
+ * Skip entries that were set up via static config directives
+ */
+ entry = (struct mteTrigger *)netsnmp_tdata_row_entry( row );
+ if ( entry->flags & MTE_TRIGGER_FLAG_FIXED )
+ continue;
+
+ DEBUGMSGTL(("disman:event:conf", " Storing (%s %s)\n",
+ entry->mteOwner, entry->mteTName));
+
+ /*
+ * Save the basic mteTriggerTable entry...
+ */
+ memset(line, 0, sizeof(line));
+ strcat(line, "_mteTTable ");
+ cptr = line + strlen(line);
+
+ cp = entry->mteOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTName; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTriggerComment; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ /*
+ * ... (but skip the mteTriggerTest and
+ * assorted boolean flag fields)...
+ */
+ vp = entry->mteTriggerValueID;
+ tint = entry->mteTriggerValueID_len;
+ cptr = read_config_store_data( ASN_OBJECT_ID, cptr, &vp, &tint );
+ cp = entry->mteTriggerTarget; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTriggerContext; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ tint = entry->mteTriggerFrequency;
+ cptr = read_config_store_data( ASN_UNSIGNED, cptr, &tint, NULL );
+ cp = entry->mteTriggerOOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTriggerObjects; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ tint = entry->flags &
+ (MTE_TRIGGER_FLAG_VWILD |MTE_TRIGGER_FLAG_CWILD|
+ MTE_TRIGGER_FLAG_ENABLED|MTE_TRIGGER_FLAG_ACTIVE);
+ cptr = read_config_store_data( ASN_UNSIGNED, cptr, &tint, NULL );
+ /* XXX - Need to store the 'iquery' access information */
+ snmpd_store_config(line);
+
+ /*
+ * ... then save the other (relevant) table entries separately,
+ * starting with mteDeltaDiscontinuityTable...
+ */
+ if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) {
+ memset(line, 0, sizeof(line));
+ strcat(line, "_mteTDTable ");
+ cptr = line + strlen(line);
+
+ cp = entry->mteOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTName; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ vp = entry->mteDeltaDiscontID;
+ tint = entry->mteDeltaDiscontID_len;
+ cptr = read_config_store_data( ASN_OBJECT_ID, cptr, &vp, &tint );
+
+ tint = entry->flags & MTE_TRIGGER_FLAG_DWILD;
+ cptr = read_config_store_data( ASN_UNSIGNED, cptr, &tint, NULL );
+ tint = entry->mteDeltaDiscontIDType;
+ cptr = read_config_store_data( ASN_UNSIGNED, cptr, &tint, NULL );
+
+ snmpd_store_config(line);
+ }
+
+ /*
+ * ... and the three type-specific trigger tables.
+ */
+ if ( entry->mteTriggerTest & MTE_TRIGGER_EXISTENCE ) {
+ memset(line, 0, sizeof(line));
+ strcat(line, "_mteTExTable ");
+ cptr = line + strlen(line);
+
+ cp = entry->mteOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTName; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ tint = (entry->mteTExTest & 0xff) << 8;
+ tint|= (entry->mteTExStartup & 0xff);
+ cptr = read_config_store_data( ASN_UNSIGNED, cptr, &tint, NULL );
+
+ cp = entry->mteTExObjOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTExObjects; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ cp = entry->mteTExEvOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTExEvent; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ snmpd_store_config(line);
+ }
+ if ( entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN ) {
+ memset(line, 0, sizeof(line));
+ strcat(line, "_mteTBlTable ");
+ cptr = line + strlen(line);
+
+ cp = entry->mteOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTName; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ tint = entry->mteTBoolComparison;
+ tint |= (entry->flags & MTE_TRIGGER_FLAG_BSTART);
+ cptr = read_config_store_data( ASN_UNSIGNED, cptr, &tint, NULL );
+ tint = entry->mteTBoolValue;
+ cptr = read_config_store_data( ASN_INTEGER, cptr, &tint, NULL );
+
+ cp = entry->mteTBoolObjOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTBoolObjects; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ cp = entry->mteTBoolEvOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTBoolEvent; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ snmpd_store_config(line);
+ }
+ if ( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) {
+ memset(line, 0, sizeof(line));
+ strcat(line, "_mteTThTable ");
+ cptr = line + strlen(line);
+
+ cp = entry->mteOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTName; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ cptr = read_config_store_data(ASN_UNSIGNED, cptr,
+ &entry->mteTThStartup, NULL );
+ cptr = read_config_store_data(ASN_INTEGER, cptr,
+ &entry->mteTThRiseValue, NULL );
+ cptr = read_config_store_data(ASN_INTEGER, cptr,
+ &entry->mteTThFallValue, NULL );
+ cptr = read_config_store_data(ASN_INTEGER, cptr,
+ &entry->mteTThDRiseValue, NULL );
+ cptr = read_config_store_data(ASN_INTEGER, cptr,
+ &entry->mteTThDFallValue, NULL );
+
+ cp = entry->mteTThObjOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTThObjects; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ cp = entry->mteTThRiseOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTThRiseEvent; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTThFallOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTThFallEvent; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ cp = entry->mteTThDRiseOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTThDRiseEvent; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTThDFallOwner; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+ cp = entry->mteTThDFallEvent; tint = strlen( cp );
+ cptr = read_config_store_data( ASN_OCTET_STR, cptr, &cp, &tint );
+
+ snmpd_store_config(line);
+ }
+ }
+
+ DEBUGMSGTL(("disman:event:conf", " done.\n"));
+ return SNMPERR_SUCCESS;
+}
+
+int
+clear_mteTTable(int majorID, int minorID, void *serverarg, void *clientarg)
+{
+ netsnmp_tdata_row *row;
+
+ while (( row = netsnmp_tdata_row_first( trigger_table_data ))) {
+ struct mteTrigger *entry = (struct mteTrigger *)
+ netsnmp_tdata_remove_and_delete_row(trigger_table_data, row);
+ if (entry) {
+ /* Remove from the callbacks list and disable triggers */
+ snmp_unregister_callback( SNMP_CALLBACK_LIBRARY,
+ SNMP_CALLBACK_POST_READ_CONFIG,
+ _mteTrigger_callback_enable, entry, 0 );
+ mteTrigger_disable( entry );
+ SNMP_FREE(entry);
+ }
+ }
+ return SNMPERR_SUCCESS;
+}