/* * DisMan Event MIB: * Implementation of the trigger table configure handling */ #include #include #include #include #include #include "utilities/iquery.h" #include "disman/event/mteObjects.h" #include "disman/event/mteTrigger.h" #include "disman/event/mteTriggerConf.h" #include 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. */ strlcpy(buf, cp, sizeof(buf)); 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; }