Code

frontend: Execute commands early on large amounts of incoming traffic.
[sysdb.git] / src / core / store_lookup.c
index e5735d3728e8157ebc90d3157c0278ea6b42acdb..2affaa986f869e3c7514761857653203c291fefa 100644 (file)
@@ -103,6 +103,106 @@ match_name(name_matcher_t *m, const char *name)
        return 1;
 } /* match_name */
 
+static char *
+name_tostring(name_matcher_t *m, char *buf, size_t buflen)
+{
+       snprintf(buf, buflen, "{ %s%s%s, %p }",
+                       m->name ? "'" : "", m->name ? m->name : "NULL", m->name ? "'" : "",
+                       m->name_re);
+       return buf;
+} /* name_tostring */
+
+static char *
+logical_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+       char left[buflen + 1], right[buflen + 1];
+
+       if (! m) {
+               /* this should not happen */
+               snprintf(buf, buflen, "()");
+               return buf;
+       }
+
+       assert((m->type == MATCHER_OR) || (m->type == MATCHER_AND));
+       snprintf(buf, buflen, "(%s, %s, %s)",
+                       m->type == MATCHER_OR ? "OR" : "AND",
+                       sdb_store_matcher_tostring(OP_M(m)->left, left, sizeof(left)),
+                       sdb_store_matcher_tostring(OP_M(m)->right, right, sizeof(right)));
+       return buf;
+} /* logical_tostring */
+
+static char *
+unary_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+       char op[buflen + 1];
+
+       if (! m) {
+               /* this should not happen */
+               snprintf(buf, buflen, "()");
+               return buf;
+       }
+
+       assert(m->type == MATCHER_NOT);
+       snprintf(buf, buflen, "(NOT, %s)",
+                       sdb_store_matcher_tostring(UOP_M(m)->op, op, sizeof(op)));
+       return buf;
+} /* unary_tostring */
+
+static char *
+attr_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+       char name[buflen + 1], value[buflen + 1];
+
+       if (! m) {
+               snprintf(buf, buflen, "ATTR{}");
+               return buf;
+       }
+
+       assert(m->type == MATCHER_ATTR);
+       snprintf(buf, buflen, "ATTR{ NAME%s, VALUE%s }",
+                       name_tostring(&OBJ_M(m)->name, name, sizeof(name)),
+                       name_tostring(&ATTR_M(m)->value, value, sizeof(value)));
+       return buf;
+} /* attr_tostring */
+
+static char *
+service_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+       char name[buflen + 1], attr[buflen + 1];
+
+       if (! m) {
+               snprintf(buf, buflen, "SERVICE{}");
+               return buf;
+       }
+
+       assert(m->type == MATCHER_SERVICE);
+       snprintf(buf, buflen, "SERVICE{ NAME%s, %s }",
+                       name_tostring(&OBJ_M(m)->name, name, sizeof(name)),
+                       attr_tostring(SDB_STORE_MATCHER(SERVICE_M(m)->attr),
+                               attr, sizeof(attr)));
+       return buf;
+} /* service_tostring */
+
+static char *
+host_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+       char name[buflen + 1], service[buflen + 1], attr[buflen + 1];
+
+       if (! m) {
+               snprintf(buf, buflen, "HOST{}");
+               return buf;
+       }
+
+       assert(m->type == MATCHER_HOST);
+       snprintf(buf, buflen, "HOST{ NAME%s, %s, %s }",
+                       name_tostring(&OBJ_M(m)->name, name, sizeof(name)),
+                       service_tostring(SDB_STORE_MATCHER(HOST_M(m)->service),
+                               service, sizeof(service)),
+                       attr_tostring(SDB_STORE_MATCHER(HOST_M(m)->attr),
+                               attr, sizeof(attr)));
+       return buf;
+} /* host_tostring */
+
 /* match attribute specific values;
  * always call this function through match_obj() */
 static int
@@ -218,6 +318,17 @@ static matcher_cb matchers[] = {
        match_obj,
 };
 
+typedef char *(*matcher_tostring_cb)(sdb_store_matcher_t *, char *, size_t);
+
+static matcher_tostring_cb matchers_tostring[] = {
+       logical_tostring,
+       logical_tostring,
+       unary_tostring,
+       attr_tostring,
+       service_tostring,
+       host_tostring,
+};
+
 static int
 match_logical(sdb_store_matcher_t *m, sdb_store_base_t *obj)
 {
@@ -570,7 +681,14 @@ sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr,
                                /* service = */ NULL,
                                sdb_store_attr_matcher(matcher, matcher_re, NULL, NULL));
 
-       if (m && inv) {
+       if (! m)
+               return NULL;
+
+       /* pass ownership to the host matcher */
+       sdb_object_deref(SDB_OBJ(HOST_M(m)->service));
+       sdb_object_deref(SDB_OBJ(HOST_M(m)->attr));
+
+       if (inv) {
                sdb_store_matcher_t *tmp;
                tmp = sdb_store_inv_matcher(m);
                /* pass ownership to the inverse matcher */
@@ -613,6 +731,18 @@ sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_base_t *obj)
        return matchers[m->type](m, obj);
 } /* sdb_store_matcher_matches */
 
+char *
+sdb_store_matcher_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+       if (! m)
+               return NULL;
+
+       if ((m->type < 0)
+                       || (((size_t)m->type >= SDB_STATIC_ARRAY_LEN(matchers_tostring))))
+               return NULL;
+       return matchers_tostring[m->type](m, buf, buflen);
+} /* sdb_store_matcher_tostring */
+
 int
 sdb_store_lookup(sdb_store_matcher_t *m, sdb_store_lookup_cb cb,
                void *user_data)