aboutsummaryrefslogtreecommitdiff
path: root/src/snmploop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/snmploop.c')
-rw-r--r--src/snmploop.c169
1 files changed, 120 insertions, 49 deletions
diff --git a/src/snmploop.c b/src/snmploop.c
index 5d1e98e..3ce638f 100644
--- a/src/snmploop.c
+++ b/src/snmploop.c
@@ -66,6 +66,40 @@ slb_format_oid_value(oid *oid, size_t len, struct variable_list *vp,
return (char*) cache->cache_buffer;
}
+static int
+assrt_clear_prev(void *sym, void *data)
+{
+ struct slb_assertion *ap = sym;
+ if (ap->flags & SLB_ASSERT_PREV) {
+ free(ap->value);
+ ap->value = NULL;
+ }
+ return 0;
+}
+
+static int
+table_clear(void *sym, void *data)
+{
+ struct slb_table *tab = sym;
+ grecs_symtab_clear(tab->tab_idx);
+ return 0;
+}
+
+/* Re-initialize server state */
+static int
+slb_server_init(struct slb_server *srv, int clrflag)
+{
+ slb_node_state_init(srv->state);
+ srv->expr->ex_eval_count = 0;
+ grecs_symtab_enumerate(srv->assertions,
+ assrt_clear_prev,
+ NULL);
+ if (clrflag) {
+ grecs_symtab_enumerate(srv->tables, table_clear, NULL);
+ srv->flags &= ~clrflag;
+ }
+}
+
#define E_VARINST_OK 0
#define E_VARINST_UNSUPPORTED 1
#define E_VARINST_OVERFLOW 2
@@ -125,7 +159,8 @@ varinst_assign(struct slb_varinstance *inst, struct variable_list *var,
}
static int
-assertion_test(struct slb_assertion *ap, struct variable_list *vp)
+assertion_test(struct slb_server *srv, struct slb_assertion *ap,
+ struct variable_list *vp)
{
size_t out_len = 0;
int rc;
@@ -134,40 +169,55 @@ assertion_test(struct slb_assertion *ap, struct variable_list *vp)
buf = slb_format_oid_value(ap->name, ap->length, vp, &ap->cache);
if (!buf)
return 1;
- switch (ap->opcode) {
- case SLB_ASSERT_EQ:
- rc = ((ap->flags & SLB_ASSERT_ICASE) ? strcasecmp : strcmp)
- (ap->value, buf)== 0;
- break;
- case SLB_ASSERT_PREFIX:
- rc = strlen(buf) >= ap->vallen &&
- ((ap->flags & SLB_ASSERT_ICASE) ?
- strncasecmp : strncmp) (buf, ap->value, ap->vallen)
- == 0;
- break;
- case SLB_ASSERT_SUFFIX:
- rc = strlen(buf) >= ap->vallen &&
- ((ap->flags & SLB_ASSERT_ICASE) ?
- strncasecmp : strncmp)
- (buf + strlen(buf) - ap->vallen,
- ap->value, ap->vallen) == 0;
- break;
- case SLB_ASSERT_GLOB:
- rc = wildmatch(ap->value, buf,
- ap->flags & SLB_ASSERT_ICASE) == 0;
- break;
- case SLB_ASSERT_EQUAL:
- /* FIXME */
- rc = strtoul(buf, NULL, 10) == strtoul(ap->value, NULL, 10);
- break;
- case SLB_ASSERT_LT:
- rc = strtoul(buf, NULL, 10) < strtoul(ap->value, NULL, 10);
- break;
- case SLB_ASSERT_LE:
- rc = strtoul(buf, NULL, 10) <= strtoul(ap->value, NULL, 10);
+
+ if (!ap->value) {
+ rc = 1;
+ } else {
+ switch (ap->opcode) {
+ case SLB_ASSERT_EQ:
+ rc = ((ap->flags & SLB_ASSERT_ICASE) ?
+ strcasecmp : strcmp)
+ (ap->value, buf) == 0;
+ break;
+ case SLB_ASSERT_PREFIX:
+ rc = strlen(buf) >= ap->vallen &&
+ ((ap->flags & SLB_ASSERT_ICASE) ?
+ strncasecmp : strncmp)
+ (buf, ap->value, ap->vallen) == 0;
+ break;
+ case SLB_ASSERT_SUFFIX:
+ rc = strlen(buf) >= ap->vallen &&
+ ((ap->flags & SLB_ASSERT_ICASE) ?
+ strncasecmp : strncmp)
+ (buf + strlen(buf) - ap->vallen,
+ ap->value, ap->vallen) == 0;
+ break;
+ case SLB_ASSERT_GLOB:
+ rc = wildmatch(ap->value, buf,
+ ap->flags & SLB_ASSERT_ICASE) == 0;
+ break;
+ case SLB_ASSERT_EQUAL:
+ /* FIXME */
+ rc = strtoul(buf, NULL, 10) ==
+ strtoul(ap->value, NULL, 10);
+ break;
+ case SLB_ASSERT_LT:
+ rc = strtoul(buf, NULL, 10) <
+ strtoul(ap->value, NULL, 10);
+ break;
+ case SLB_ASSERT_LE:
+ rc = strtoul(buf, NULL, 10) <=
+ strtoul(ap->value, NULL, 10);
+ }
+ if (ap->flags & SLB_ASSERT_NEG)
+ rc = !rc;
+ }
+
+ if (ap->flags & SLB_ASSERT_PREV) {
+ free(ap->value);
+ ap->value = grecs_strdup(buf);
+ ap->vallen = strlen(ap->value);
}
- if (ap->flags & SLB_ASSERT_NEG)
- rc = !rc;
return rc;
}
@@ -184,14 +234,40 @@ process_result(struct slb_server *srv, struct snmp_pdu *pdu)
ap = assertion_lookup(srv->assertions, vp->name,
vp->name_length, NULL);
- if (ap && !assertion_test(ap, vp)) {
- logmsg(LOG_NOTICE,
- "%s:%d: %s: assertion \"%s\" failed, got %s",
- ap->locus.beg.file, ap->locus.beg.line,
- srvid(srv),
- ap->text,
- ap->cache.cache_buffer);
- return;
+ if (ap && !assertion_test(srv, ap, vp)) {
+ switch (ap->action) {
+ case SLB_ASSERT_ABORT:
+ logmsg(LOG_NOTICE,
+ "%s:%d: %s: assertion \"%s\" failed, "
+ "got %s",
+ ap->locus.beg.file, ap->locus.beg.line,
+ srvid(srv),
+ ap->text,
+ ap->cache.cache_buffer);
+ return;
+
+ case SLB_ASSERT_WARN:
+ logmsg(LOG_NOTICE,
+ "%s:%d: %s: warning: "
+ "assertion \"%s\" failed, "
+ "got %s",
+ ap->locus.beg.file, ap->locus.beg.line,
+ srvid(srv),
+ ap->text,
+ ap->cache.cache_buffer);
+ break;
+
+ case SLB_ASSERT_REINIT:
+ logmsg(LOG_NOTICE,
+ "%s:%d: %s: assertion \"%s\" failed "
+ "(got %s); re-initializing server",
+ ap->locus.beg.file, ap->locus.beg.line,
+ srvid(srv),
+ ap->text,
+ ap->cache.cache_buffer);
+ slb_server_init(srv, SLB_SRV_TAB_RESOLVED);
+ return;
+ }
}
inst = oidtab_lookup(srv->oidtab, vp->name, vp->name_length);
@@ -312,7 +388,6 @@ oid_to_table(struct slb_server *srv, oid *oid, size_t oidlen)
return clos.result;
}
-
static void
process_next(struct slb_server *srv, struct snmp_pdu *pdu)
{
@@ -358,11 +433,7 @@ _process_pdu(int operation, struct slb_server *srv,
proc(srv, pdu);
} else {
logmsg(LOG_ERR, "server %s: timeout", srvid(srv));
- /* Re-initialize server state */
- slb_node_state_init(srv->state);
- srv->expr->ex_eval_count = 0;
- if (clrflag)
- srv->flags &= ~clrflag;
+ slb_server_init(srv, clrflag);
}
}
@@ -592,7 +663,7 @@ resolve_tabref(struct slb_varinstance *vinst, struct slb_server *srv)
grecs_txtacc_grow_char(acc, 0);
mib = grecs_txtacc_finish(acc, 0);
vinst->vi_oidlen = MAX_OID_LEN;
- /* FIXME: oidtab_delete(srv->oidtab, vinst) */
+ oidtab_delete(srv->oidtab, vinst);
if (!read_objid(mib, vinst->vi_oid, &vinst->vi_oidlen)) {
logmsg(LOG_NOTICE,
"%s:%d: cannot parse %s (MIB %s); "

Return to:

Send suggestions and report system problems to the System administrator.